diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt
index 4b50ec8d1..2b46e2cdc 100644
--- a/code/studio/src/plugins/gui_editor/CMakeLists.txt
+++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt
@@ -34,6 +34,8 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR
texture_chooser.h
action_property_manager.h
texture_property_manager.h
+ expression_editor.h
+ expr_link_dlg.h
)
SET(OVQT_PLUGIN_GUI_EDITOR_UIS
@@ -51,6 +53,8 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS
add_widget_widget.ui
action_list.ui
texture_chooser.ui
+ expression_editor.ui
+ expr_link_dlg.ui
)
SET(QT_USE_QTGUI TRUE)
diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp
new file mode 100644
index 000000000..e8d01af85
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp
@@ -0,0 +1,124 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#include "expr_link_dlg.h"
+#include
+
+ExprLinkDlg::ExprLinkDlg( QWidget *parent ) :
+QDialog( parent )
+{
+ m_ui.setupUi( this );
+
+ connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) );
+ connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) );
+}
+
+ExprLinkDlg::~ExprLinkDlg()
+{
+}
+
+void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname )
+{
+ QListIterator< SlotInfo > itra( a );
+ QListIterator< SlotInfo > itrb( b );
+
+ while( itra.hasNext() )
+ {
+ const SlotInfo &info = itra.next();
+
+ QListWidgetItem *item = new QListWidgetItem();
+ item->setText( info.name );
+ item->setData( Qt::UserRole, info.slot );
+
+ m_ui.list1->addItem( item );
+ }
+
+ while( itrb.hasNext() )
+ {
+ const SlotInfo &info = itrb.next();
+
+ QListWidgetItem *item = new QListWidgetItem();
+ item->setText( info.name );
+ item->setData( Qt::UserRole, info.slot );
+
+ m_ui.list2->addItem( item );
+ }
+
+ m_ui.groupBox1->setTitle( aname );
+ m_ui.groupBox2->setTitle( bname );
+}
+
+int ExprLinkDlg::getSlotA() const
+{
+ QListWidgetItem *item = m_ui.list1->currentItem();
+ if( item == NULL )
+ return -1;
+
+ int slot = item->data( Qt::UserRole ).toInt();
+ return slot;
+}
+
+int ExprLinkDlg::getSlotB() const
+{
+ QListWidgetItem *item = m_ui.list2->currentItem();
+ if( item == NULL )
+ return -1;
+
+ int slot = item->data( Qt::UserRole ).toInt();
+ return slot;
+}
+
+void ExprLinkDlg::onOKClicked()
+{
+ int slotA = getSlotA();
+ int slotB = getSlotB();
+
+ if( ( slotA == -1 ) || ( slotB == -1 ) )
+ {
+ QMessageBox::information( this,
+ tr( "No slots selected" ),
+ tr( "You need to select a slot on both sides." ) );
+ return;
+ }
+
+ if( ( slotA == 0 ) && ( slotB == 0 ) )
+ {
+ QMessageBox::information( this,
+ tr( "Wrong slots selected" ),
+ tr( "You can only select the 'Out' slot on one of the sides." ) );
+ return;
+ }
+
+ if( ( slotA != 0 ) && ( slotB != 0 ) )
+ {
+ QMessageBox::information( this,
+ tr( "Wrong slots selected" ),
+ tr( "One of the slots selected must be the 'Out' slot!" ) );
+ return;
+ }
+
+ accept();
+}
+
+void ExprLinkDlg::onCancelClicked()
+{
+ reject();
+}
+
+
diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.h b/code/studio/src/plugins/gui_editor/expr_link_dlg.h
new file mode 100644
index 000000000..3f3ba97c0
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.h
@@ -0,0 +1,49 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#ifndef EXPR_LINK_DLG
+#define EXPR_LINK_DLG
+
+#include
+#include
+#include "ui_expr_link_dlg.h"
+#include "expr_slot_info.h"
+
+class ExprLinkDlg : public QDialog
+{
+ Q_OBJECT
+public:
+ ExprLinkDlg( QWidget *parent = NULL );
+ ~ExprLinkDlg();
+
+ void load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname );
+
+ int getSlotA() const;
+ int getSlotB() const;
+
+private Q_SLOTS:
+ void onOKClicked();
+ void onCancelClicked();
+
+private:
+ Ui::ExprLinkDialog m_ui;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.ui b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui
new file mode 100644
index 000000000..d6fdf9d7d
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui
@@ -0,0 +1,76 @@
+
+
+ ExprLinkDialog
+
+
+
+ 0
+ 0
+ 641
+ 334
+
+
+
+ Linking nodes
+
+
+ -
+
+
-
+
+
+ GroupBox
+
+
+
-
+
+
+
+
+
+ -
+
+
+ GroupBox
+
+
+
-
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 398
+ 20
+
+
+
+
+ -
+
+
+ Ok
+
+
+
+ -
+
+
+ Cancel
+
+
+
+
+
+
+
+
diff --git a/code/studio/src/plugins/gui_editor/expr_slot_info.h b/code/studio/src/plugins/gui_editor/expr_slot_info.h
new file mode 100644
index 000000000..470edf68d
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expr_slot_info.h
@@ -0,0 +1,32 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#ifndef EXPR_SLOT_INFO
+#define EXPR_SLOT_INFO
+
+#include
+
+struct SlotInfo
+{
+ QString name;
+ int slot;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp
new file mode 100644
index 000000000..392bdca41
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp
@@ -0,0 +1,377 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#include "expression_editor.h"
+#include
+#include
+#include
+#include
+
+#include "expression_node.h"
+#include "expression_link.h"
+#include "expr_link_dlg.h"
+#include "expression_store.h"
+#include "expression_info.h"
+
+#include
+#include
+
+class ExpressionEditorPvt
+{
+public:
+
+ ExpressionEditorPvt()
+ {
+ m_root = NULL;
+ }
+
+ ExpressionStore store;
+ ExpressionNode *m_root;
+};
+
+ExpressionEditor::ExpressionEditor( QWidget *parent ) :
+QMainWindow( parent )
+{
+ m_ui.setupUi( this );
+
+ m_pvt = new ExpressionEditorPvt();
+
+ m_selectionCount = 0;
+
+ m_scene = new QGraphicsScene( this );
+ m_ui.view->setScene( m_scene );
+
+ connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) );
+ connect( m_ui.tree, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) );
+
+ m_nodeCount = 0;
+}
+
+ExpressionEditor::~ExpressionEditor()
+{
+ delete m_pvt;
+ m_pvt = NULL;
+ m_scene = NULL;
+}
+
+void ExpressionEditor::load()
+{
+ m_pvt->store.load();
+
+ QList< const ExpressionInfo* > l;
+ m_pvt->store.getExpressions( l );
+
+ QListIterator< const ExpressionInfo* > itr( l );
+ while( itr.hasNext() )
+ {
+ addExpression( itr.next() );
+ }
+
+ l.clear();
+}
+
+void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e )
+{
+ QMenu menu;
+ QAction *a = NULL;
+
+ if( m_selectionCount > 0 )
+ {
+ a = menu.addAction( "Remove" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) );
+
+ if( m_selectionCount == 1 )
+ {
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ 0 ] );
+ if( node != NULL )
+ {
+ if( node->variable() )
+ {
+ a = menu.addAction( "Change slot count" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) );
+ }
+ else
+ if( node->isValue() )
+ {
+ a = menu.addAction( "Change value" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onChangeValue() ) );
+ }
+
+ a = menu.addAction( "Set as root" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onSetRoot() ) );
+ }
+ }
+ else
+ if( m_selectionCount == 2 )
+ {
+ a = menu.addAction( "Link" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onLinkItems() ) );
+ }
+
+ a = menu.addAction( "Unlink" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onUnLinkItems() ) );
+ }
+ else
+ {
+ a = menu.addAction( "Build expression" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onBuildExpression() ) );
+
+ a = menu.addAction( "Save" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onSave() ) );
+
+ a = menu.addAction( "Clear" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onClear() ) );
+ }
+
+ menu.exec( e->globalPos() );
+}
+
+void ExpressionEditor::closeEvent( QCloseEvent *e )
+{
+ QMainWindow::closeEvent( e );
+
+ Q_EMIT closing();
+}
+
+void ExpressionEditor::onDeleteSelection()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ QListIterator< QGraphicsItem* > itr( l );
+ while( itr.hasNext() )
+ {
+ QGraphicsItem *item = itr.next();
+
+ ExpressionNode *node = dynamic_cast< ExpressionNode* >( item );
+ if( node != NULL )
+ {
+ ExpressionLink *link = NULL;
+
+ int c = node->slotCount();
+ for( int i = 0; i < c; i++ )
+ {
+ link = node->link( i );
+ if( link != NULL )
+ {
+ link->unlink();
+ m_scene->removeItem( link );
+ delete link;
+ }
+ }
+ }
+
+ m_scene->removeItem( item );
+ delete item;
+ }
+}
+
+void ExpressionEditor::onSelectionChanged()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ m_selectionCount = l.count();
+}
+
+void ExpressionEditor::onLinkItems()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] );
+ ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] );
+
+ QList< SlotInfo > froml;
+ QList< SlotInfo > tol;
+
+ from->getSlots( froml );
+ to->getSlots( tol );
+
+ // If there are no free slots, or both "Out" slots are taken we can't link
+ if( froml.isEmpty() || tol.isEmpty() || ( !from->slotEmpty( 0 ) && !to->slotEmpty( 0 ) ) )
+ {
+ QMessageBox::information( this,
+ tr( "Failed to link nodes" ),
+ tr( "Unfortunately those nodes are full." ) );
+ return;
+ }
+
+ ExprLinkDlg d;
+ d.load( froml, tol, from->name(), to->name() );
+ int result = d.exec();
+ if( result == QDialog::Rejected )
+ return;
+
+ int slotA = d.getSlotA();
+ int slotB = d.getSlotB();
+
+ ExpressionLink *link = new ExpressionLink();
+ link->link( from, to, slotA, slotB );
+
+ m_scene->addItem( link );
+}
+
+void ExpressionEditor::onUnLinkItems()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+
+ for( int i = 0; i < l.count(); i++ )
+ {
+ ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ i ] );
+ if( node == NULL )
+ continue;
+
+ node->clearLinks();
+ }
+}
+
+void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item )
+{
+ QString name = item->text( 0 );
+
+ const ExpressionInfo *info = m_pvt->store.getInfo( name );
+
+ QString n = name;
+ n += " #";
+ n += QString::number( m_nodeCount );
+ m_nodeCount++;
+
+ ExpressionNode *node = new ExpressionNode( n, info->slotNames.count() );
+ node->setSlotNames( info->slotNames );
+ node->setVariable( info->variable );
+ node->setIsValue( info->value );
+ if( node->isValue() )
+ {
+ node->setValue( "Value" );
+ }
+ m_scene->addItem( node );
+}
+
+void ExpressionEditor::onChangeSlotCount()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] );
+ int oldc = node->slotCount();
+
+ int c = QInputDialog::getInt( this,
+ tr( "Change slot count" ),
+ tr( "Enter new slot count" ),
+ oldc,
+ 1,
+ 26 );
+
+ if( oldc == c )
+ return;
+
+ node->changeSlotCount( c );
+}
+
+void ExpressionEditor::onChangeValue()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] );
+
+ QString oldValue = node->getValue();
+
+ QString newValue = QInputDialog::getText( this,
+ tr( "Change value" ),
+ tr( "Enter new value" ),
+ QLineEdit::Normal,
+ oldValue );
+
+ if( newValue.isEmpty() )
+ return;
+ if( newValue == oldValue )
+ return;
+
+ node->setValue( newValue );
+}
+
+void ExpressionEditor::onSetRoot()
+{
+ QList< QGraphicsItem* > l = m_scene->selectedItems();
+ ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] );
+
+ if( m_pvt->m_root != NULL )
+ m_pvt->m_root->setRoot( false );
+
+ m_pvt->m_root = node;
+ node->setRoot( true );
+}
+
+void ExpressionEditor::onBuildExpression()
+{
+ if( m_pvt->m_root == NULL )
+ {
+ QMessageBox::information( this,
+ tr( "Building expression" ),
+ tr( "Failed to build expression: You must set a root node." ) );
+ return;
+ }
+
+ QString result = m_pvt->m_root->build();
+ QMessageBox::information( this,
+ tr( "Building expression" ),
+ tr( "The result is\n" ) + result );
+}
+
+void ExpressionEditor::onSave()
+{
+ if( m_pvt->m_root != NULL )
+ {
+ m_result = m_pvt->m_root->build();
+ }
+
+ close();
+}
+
+void ExpressionEditor::onClear()
+{
+ m_scene->clear();
+ m_pvt->m_root = NULL;
+ m_nodeCount = 0;
+ m_selectionCount = 0;
+ m_result = "";
+}
+
+
+void ExpressionEditor::addExpression( const ExpressionInfo *info )
+{
+ QTreeWidgetItem *item = findTopLevelItem( info->category );
+ if( item == NULL )
+ {
+ item = new QTreeWidgetItem();
+ item->setText( 0, info->category );
+ m_ui.tree->addTopLevelItem( item );
+ }
+
+ QTreeWidgetItem *citem = new QTreeWidgetItem();
+ citem->setText( 0, info->name );
+ item->addChild( citem );
+}
+
+QTreeWidgetItem* ExpressionEditor::findTopLevelItem( const QString &text )
+{
+ int c = m_ui.tree->topLevelItemCount();
+ for( int i = 0; i < c; i++ )
+ {
+ QTreeWidgetItem *item = m_ui.tree->topLevelItem( i );
+ if( item->text( 0 ) == text )
+ return item;
+ }
+
+ return NULL;
+}
+
diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h
new file mode 100644
index 000000000..92cc959bd
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_editor.h
@@ -0,0 +1,75 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#ifndef EXPRESSION_EDITOR
+#define EXPRESSION_EDITOR
+
+#include "ui_expression_editor.h"
+
+class QGraphicsScene;
+class QGraphicsItem;
+class ExpressionEditorPvt;
+class ExpressionInfo;
+
+class ExpressionEditor : public QMainWindow
+{
+ Q_OBJECT
+public:
+ ExpressionEditor( QWidget *parent = NULL );
+ ~ExpressionEditor();
+
+ void load();
+ QString result() const{ return m_result; }
+
+Q_SIGNALS:
+ void closing();
+
+protected:
+ void contextMenuEvent( QContextMenuEvent *e );
+ void closeEvent( QCloseEvent *e );
+
+private Q_SLOTS:
+ void onDeleteSelection();
+ void onSelectionChanged();
+ void onLinkItems();
+ void onUnLinkItems();
+ void onItemDblClicked( QTreeWidgetItem *item );
+ void onChangeSlotCount();
+ void onChangeValue();
+ void onSetRoot();
+ void onBuildExpression();
+ void onSave();
+ void onClear();
+
+private:
+ void addExpression( const ExpressionInfo *info );
+ QTreeWidgetItem* findTopLevelItem( const QString &text );
+
+ Ui::ExpressionEditor m_ui;
+ QGraphicsScene *m_scene;
+
+ int m_selectionCount;
+ int m_nodeCount;
+
+ ExpressionEditorPvt *m_pvt;
+ QString m_result;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui
new file mode 100644
index 000000000..fa21420a2
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_editor.ui
@@ -0,0 +1,58 @@
+
+
+ ExpressionEditor
+
+
+ Qt::ApplicationModal
+
+
+
+ 0
+ 0
+ 800
+ 600
+
+
+
+ Expression Editor
+
+
+
+ -
+
+
+
+
+
+
+
+
+ 1
+
+
+
+ -
+
+
+
+ Expressions
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/studio/src/plugins/gui_editor/expression_info.h b/code/studio/src/plugins/gui_editor/expression_info.h
new file mode 100644
index 000000000..86218b6af
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_info.h
@@ -0,0 +1,41 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef EXPRESSION_INFO
+#define EXPRESSION_INFO
+
+#include
+#include
+
+struct ExpressionInfo
+{
+ QString name;
+ bool value;
+ QString category;
+ bool variable;
+ QStringList slotNames;
+
+ ExpressionInfo()
+ {
+ value = false;
+ variable = false;
+ }
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp
new file mode 100644
index 000000000..54c7734b0
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_link.cpp
@@ -0,0 +1,78 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "expression_link.h"
+#include "expression_node.h"
+#include
+#include
+
+ExpressionLink::ExpressionLink( QGraphicsItem *parent ) :
+QGraphicsLineItem( parent )
+{
+ m_from = NULL;
+ m_to = NULL;
+}
+
+ExpressionLink::~ExpressionLink()
+{
+ unlink();
+}
+
+void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot )
+{
+ m_from = from;
+ m_to = to;
+ m_from->setLink( this, fromSlot );
+ m_to->setLink( this, toSlot );
+
+ m_fromSlot = fromSlot;
+ m_toSlot = toSlot;
+
+ nodeMoved();
+}
+
+void ExpressionLink::unlink()
+{
+ if( m_from == NULL )
+ return;
+
+ m_from->setLink( NULL, m_fromSlot );
+ m_to->setLink( NULL, m_toSlot );
+
+ m_from = NULL;
+ m_to = NULL;
+
+ delete this;
+}
+
+void ExpressionLink::nodeMoved()
+{
+ setLine( QLineF( m_from->slotPos( m_fromSlot ), m_to->slotPos( m_toSlot ) ) );
+}
+
+void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
+{
+ QPen p;
+ p.setColor( Qt::black );
+ p.setWidth( 5 );
+ setPen( p );
+
+ QGraphicsLineItem::paint( painter, option, widget );
+}
+
+
diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h
new file mode 100644
index 000000000..a0e699451
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_link.h
@@ -0,0 +1,51 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef EXPRESSION_LINK
+#define EXPRESSION_LINK
+
+#include
+
+class ExpressionNode;
+
+class ExpressionLink : public QGraphicsLineItem
+{
+public:
+ ExpressionLink( QGraphicsItem *parent = NULL );
+ ~ExpressionLink();
+
+ void link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot );
+ void unlink();
+
+ void nodeMoved();
+
+ void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget );
+
+ ExpressionNode* from() const{ return m_from; }
+ ExpressionNode* to() const{ return m_to; }
+
+private:
+ ExpressionNode *m_from;
+ ExpressionNode *m_to;
+
+ int m_fromSlot;
+ int m_toSlot;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_loader.cpp b/code/studio/src/plugins/gui_editor/expression_loader.cpp
new file mode 100644
index 000000000..07db432e0
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_loader.cpp
@@ -0,0 +1,220 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "expression_loader.h"
+#include "expression_info.h"
+
+#include
+#include
+
+class ExpressionLoaderPvt
+{
+public:
+
+ bool parseName()
+ {
+ QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement );
+ if( reader.hasError() )
+ return false;
+
+ m_info->name = text;
+
+ return true;
+ }
+
+ bool parseValue()
+ {
+ QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement );
+ if( reader.hasError() )
+ return false;
+
+ if( text.toLower() == "true" )
+ m_info->value = true;
+ else
+ m_info->value = false;
+
+ return true;
+ }
+
+ bool parseCategory()
+ {
+ QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement );
+ if( reader.hasError() )
+ return false;
+
+ m_info->category = text;
+
+ return true;
+ }
+
+ bool parseVariable()
+ {
+ QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement );
+ if( reader.hasError() )
+ return false;
+
+ if( text.toLower() == "true" )
+ m_info->variable = true;
+ else
+ m_info->variable = false;
+
+ return true;
+ }
+
+ bool parseSlot()
+ {
+ QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement );
+ if( reader.hasError() )
+ return false;
+
+ m_info->slotNames.push_back( text );
+
+ return true;
+ }
+
+ bool parseSlots()
+ {
+ bool error = false;
+
+ while( !reader.atEnd() )
+ {
+ reader.readNext();
+
+ if( reader.isStartElement() )
+ {
+ QString name = reader.name().toString();
+ if( name == "slot" )
+ error = !parseSlot();
+ }
+ else
+ if( reader.isEndElement() )
+ {
+ if( reader.name() == "slots" )
+ break;
+ }
+ }
+
+ if( reader.atEnd() )
+ return false;
+
+ return true;
+ }
+
+ bool load( QFile *f )
+ {
+ reader.clear();
+ reader.setDevice( f );
+
+ bool error = false;
+
+ // start of document
+ reader.readNext();
+ if( reader.atEnd() )
+ return false;
+
+ // root node
+ reader.readNext();
+ if( reader.atEnd() )
+ return false;
+
+ if( reader.isStartElement() )
+ {
+ // Not an expression file?
+ if( reader.name() != "expression" )
+ return false;
+ }
+
+ while( !reader.atEnd() )
+ {
+ reader.readNext();
+
+ if( reader.isStartElement() )
+ {
+ QString name = reader.name().toString();
+
+ if( name == "name" )
+ error = !parseName();
+ else
+ if( name == "value" )
+ error = !parseValue();
+ else
+ if( name == "category" )
+ error = !parseCategory();
+ else
+ if( name == "variable" )
+ error = !parseVariable();
+ else
+ if( name == "slots" )
+ error = !parseSlots();
+ }
+
+ if( error )
+ break;
+ }
+
+ if( error || reader.hasError() )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ void setInfo( ExpressionInfo *info ){ m_info = info; }
+
+private:
+ QXmlStreamReader reader;
+ ExpressionInfo *m_info;
+};
+
+ExpressionLoader::ExpressionLoader()
+{
+ m_pvt = new ExpressionLoaderPvt;
+}
+
+ExpressionLoader::~ExpressionLoader()
+{
+ delete m_pvt;
+ m_pvt = NULL;
+}
+
+ExpressionInfo* ExpressionLoader::load( const QString &filename )
+{
+ ExpressionInfo *info = NULL;
+ bool ok = false;
+
+ QFile f( filename );
+ if( !f.open( QIODevice::ReadOnly | QIODevice::Text ) )
+ return NULL;
+
+ info = new ExpressionInfo();
+ m_pvt->setInfo( info );
+ ok = m_pvt->load( &f );
+
+ f.close();
+
+ if( !ok )
+ {
+ delete info;
+ info = NULL;
+ }
+
+ return info;
+}
+
+
diff --git a/code/studio/src/plugins/gui_editor/expression_loader.h b/code/studio/src/plugins/gui_editor/expression_loader.h
new file mode 100644
index 000000000..f315fcdcd
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_loader.h
@@ -0,0 +1,39 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef EXPRESSION_LOADER
+#define EXPRESSION_LOADER
+
+struct ExpressionInfo;
+class QString;
+class ExpressionLoaderPvt;
+
+class ExpressionLoader
+{
+public:
+ ExpressionLoader();
+ ~ExpressionLoader();
+
+ ExpressionInfo* load( const QString &filename );
+
+private:
+ ExpressionLoaderPvt *m_pvt;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp
new file mode 100644
index 000000000..8a0ef774b
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_node.cpp
@@ -0,0 +1,410 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#include "expression_node.h"
+#include "expression_link.h"
+#include
+#include
+
+struct NodeSlotInfo
+{
+ // top-left
+ QPoint tl;
+
+ // text top-left
+ QPoint ttl;
+
+ // The text displayed
+ QString text;
+
+ // text width
+ qreal tw;
+
+ // text height
+ qreal th;
+
+ // width-height of the box
+ qreal wh;
+};
+
+class NodeSlot
+{
+public:
+ NodeSlot( const NodeSlotInfo &info )
+ {
+ m_info = info;
+ }
+
+ ~NodeSlot()
+ {
+ }
+
+ QPointF pos() const{
+ QPointF p;
+ p.setX( m_info.tl.x() + m_info.wh / 2.0 );
+ p.setY( m_info.tl.y() + m_info.wh / 2.0 );
+
+ return p;
+ }
+
+ void paint( QPainter *painter )
+ {
+ QBrush boxBrush;
+ QPen p;
+
+ boxBrush.setColor( Qt::black );
+ boxBrush.setStyle( Qt::SolidPattern );
+ p.setColor( Qt::black );
+ painter->setPen( p );
+
+ QRectF box;
+ QRectF tbox;
+
+ box.setTopLeft( m_info.tl );
+ box.setHeight( m_info.wh );
+ box.setWidth( m_info.wh );
+
+ painter->fillRect( box, boxBrush );
+
+ tbox.setTopLeft( m_info.ttl );
+ tbox.setHeight( m_info.th );
+ tbox.setWidth( m_info.tw );
+
+ painter->drawText( tbox, Qt::AlignRight, m_info.text );
+ }
+
+ QString text() const{ return m_info.text; }
+ void setText( const QString &text ){ m_info.text = text; }
+
+private:
+ NodeSlotInfo m_info;
+};
+
+
+
+ExpressionNode::ExpressionNode( const QString &name, int slotCount, QGraphicsItem *parent ) :
+QGraphicsItem( parent )
+{
+ setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsScenePositionChanges );
+
+ m_w = 100;
+ m_h = 100;
+ m_hh = 20.0;
+
+ m_variable = false;
+ m_isValue = false;
+ m_isRoot = false;
+
+ m_name = name;
+
+ if( slotCount > 3 )
+ m_h = m_h + 20.0 * ( slotCount - 3 );
+
+ createSlots( slotCount );
+}
+
+ExpressionNode::~ExpressionNode()
+{
+ clearLinks();
+ clearSlots();
+}
+
+QRectF ExpressionNode::boundingRect() const
+{
+ return QRectF( 0, 0, m_w, m_h );
+}
+
+void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
+{
+ QBrush br;
+ QBrush boxBrush;
+ QPen p;
+ QColor c;
+
+ QRectF rect = boundingRect();
+ QRectF header = rect;
+ header.setHeight( m_hh );
+
+ // Draw filled rectangle, header
+ if( !m_isRoot )
+ {
+ c.setRed( 44 );
+ c.setGreen( 169 );
+ c.setBlue( 232 );
+ }
+ else
+ {
+ c.setRed( 255 );
+ c.setGreen( 0 );
+ c.setBlue( 0 );
+ }
+ br.setColor( c );
+ br.setStyle( Qt::SolidPattern );
+ p.setColor( c );
+ painter->setPen( p );
+ painter->fillRect( header, br );
+
+ // Draw header text
+ p.setColor( Qt::black );
+ painter->setPen( p );
+ painter->drawText( header, Qt::AlignCenter, m_name );
+
+ // Draw value if applicable
+ if( m_isValue )
+ {
+ QRectF vbox;
+ vbox.setTopLeft( QPoint( 0.0, 20.0 ) );
+ vbox.setWidth( header.width() );
+ vbox.setHeight( header.height() );
+ QPen vpen;
+ vpen.setColor( Qt::red );
+ painter->setPen( vpen );
+ painter->drawText( vbox, Qt::AlignCenter, m_value );
+ painter->setPen( p );
+ }
+
+ if( option->state & QStyle::State_Selected )
+ {
+ p.setStyle( Qt::DotLine );
+ p.setColor( Qt::red );
+ }
+
+ // Draw outline of the entire thing + header
+ painter->setPen( p );
+ painter->drawRect( rect );
+ painter->drawRect( header );
+
+ paintSlots( painter );
+}
+
+
+QPointF ExpressionNode::slotPos( int slot ) const
+{
+ const NodeSlot *s = m_slots[ slot ];
+ QPointF sp = s->pos();
+ QPointF mp = pos();
+
+ mp += sp;
+ return mp;
+}
+
+void ExpressionNode::changeSlotCount( int count )
+{
+ clearSlots();
+ clearLinks();
+ m_links.clear();
+
+ if( count <= 3 )
+ m_h = 100.0;
+ else
+ m_h = 100.0 + 20.0 * ( count - 3 );
+
+ createSlots( count );
+
+ update();
+}
+
+void ExpressionNode::clearSlots()
+{
+ qDeleteAll( m_slots );
+ m_slots.clear();
+}
+
+bool ExpressionNode::slotEmpty( int slot ) const
+{
+ if( m_links[ 0 ] == NULL )
+ return true;
+ else
+ return false;
+}
+
+void ExpressionNode::getSlots( QList< SlotInfo > &l )
+{
+ SlotInfo info;
+
+ for( int i = 0; i < m_slots.count(); i++ )
+ {
+ if( m_links[ i ] != NULL )
+ continue;
+
+ info.name = m_slots[ i ]->text();
+ info.slot = i;
+ l.push_back( info );
+ }
+}
+
+void ExpressionNode::setLink( ExpressionLink *link, int slot )
+{
+ m_links[ slot ] = link;
+}
+
+ExpressionLink* ExpressionNode::link( int slot ) const
+{
+ return m_links[ slot ];
+}
+
+void ExpressionNode::setSlotNames( const QList< QString > &l )
+{
+ int c = l.count();
+ for( int i = 0; i < c; i++ )
+ {
+ // "Out" slot is at position 0, so set the names with an offset of 1
+ m_slots[ i + 1 ]->setText( l[ i ] );
+ }
+}
+
+void ExpressionNode::setValue( const QString &value )
+{
+ m_value = value;
+
+ int c = m_value.count();
+ if( c < 15 )
+ m_w = 100.0;
+ else
+ m_w = m_w + ( 100.0 / 15.0 ) * ( c - 15.0 );
+
+ update();
+}
+
+void ExpressionNode::setRoot( bool b )
+{
+ m_isRoot = b;
+ update();
+}
+
+QString ExpressionNode::build() const
+{
+ QString result;
+
+ if( isValue() )
+ return m_value;
+
+ QStringList l = m_name.split( ' ' );
+ result = l[ 0 ];
+ result += "( ";
+
+ int c = m_links.count();
+ for( int i = 1; i < c; i++ )
+ {
+ ExpressionLink *link = m_links[ i ];
+ if( link == NULL )
+ continue;
+
+ ExpressionNode *node = NULL;
+
+ if( link->from() == this )
+ node = link->to();
+ else
+ node = link->from();
+
+ result += node->build();
+
+ if( i != ( c - 1 ) )
+ result += ", ";
+ }
+
+ result += " )";
+ return result;
+}
+
+QVariant ExpressionNode::itemChange( GraphicsItemChange change, const QVariant &value )
+{
+ if( change == ItemScenePositionHasChanged )
+ {
+ onNodeMove();
+ }
+
+ return QGraphicsItem::itemChange( change, value );
+}
+
+void ExpressionNode::onNodeMove()
+{
+ for( int i = 0; i < m_links.count(); i++ )
+ {
+ ExpressionLink *link = m_links[ i ];
+ if( link == NULL )
+ continue;
+
+ link->nodeMoved();
+ }
+}
+
+void ExpressionNode::createSlots( int count)
+{
+ // Out nodes
+ m_links.push_back( NULL );
+
+ for( int i = 0; i < count; i++ )
+ m_links.push_back( NULL );
+
+ // First create the "Out" slot
+ NodeSlotInfo info;
+ info.tw = 25.0;
+ info.th = 12.0;
+ info.wh = 10.0;
+
+ qreal x = 0.0;
+ qreal y = m_h * 0.5;
+ qreal tx = info.wh;
+ qreal ty = m_h * 0.5 - 2;
+
+ info.tl = QPoint( x, y );
+ info.ttl = QPoint( tx, ty );
+ info.text = "Out";
+
+ m_slots.push_back( new NodeSlot( info ) );
+
+ // Then the rest of them
+ for( int i = 0; i < count; i++ )
+ {
+ x = m_w - info.wh;
+ y = 30 + i * 20.0;
+ tx = x - 5 - info.tw;
+ ty = y - 2;
+
+ info.tl = QPoint( x, y );
+ info.ttl = QPoint( tx, ty );
+ info.text = QString( 'A' + i );
+
+ m_slots.push_back( new NodeSlot( info ) );
+ }
+}
+
+void ExpressionNode::paintSlots( QPainter *painter )
+{
+ for( int i = 0; i < m_slots.count(); i++ )
+ {
+ NodeSlot *slot = m_slots[ i ];
+ slot->paint( painter );
+ }
+}
+
+
+void ExpressionNode::clearLinks()
+{
+ for( int i = 0; i < m_links.count(); i++ )
+ {
+ ExpressionLink *link = m_links[ i ];
+ if( link == NULL )
+ continue;
+
+ link->unlink();
+ }
+}
+
diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h
new file mode 100644
index 000000000..1e0290344
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_node.h
@@ -0,0 +1,95 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+
+#ifndef EXPRESSION_NODE
+#define EXPRESSION_NODE
+
+#include
+#include
+#include "expr_slot_info.h"
+
+class ExpressionLink;
+class NodeSlot;
+
+class ExpressionNode : public QGraphicsItem
+{
+public:
+ ExpressionNode( const QString &name, int slotCount = 3, QGraphicsItem *parent = NULL );
+ ~ExpressionNode();
+
+ QRectF boundingRect() const;
+ void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget );
+
+ void setLink( ExpressionLink *link, int slot );
+ ExpressionLink* link( int slot ) const;
+
+ QPointF slotPos( int slot ) const;
+
+ int slotCount() const{ return m_slots.count(); }
+ void changeSlotCount( int count );
+ void clearSlots();
+
+ bool slotEmpty( int slot ) const;
+
+ void getSlots( QList< SlotInfo > &l );
+
+ void clearLinks();
+
+ QString name() const{ return m_name; }
+
+ void setSlotNames( const QList< QString > &l );
+
+ void setVariable( bool b ){ m_variable = b; }
+ bool variable() const{ return m_variable; }
+
+ void setValue( const QString &value );
+ QString getValue() const{ return m_value; }
+
+ bool isValue() const{ return m_isValue; }
+ void setIsValue( bool b ){ m_isValue = b; }
+ void setRoot( bool b );
+
+ QString build() const;
+
+protected:
+ QVariant itemChange( GraphicsItemChange change, const QVariant &value );
+
+private:
+ void onNodeMove();
+ void createSlots( int count = 3 );
+ void paintSlots( QPainter *painter );
+
+ qreal m_w; // node width
+ qreal m_h; // node height
+ qreal m_hh; // header height
+
+ QList< NodeSlot* > m_slots;
+ QList< ExpressionLink* > m_links;
+
+ QString m_name;
+
+ bool m_variable;
+
+ QString m_value;
+ bool m_isValue;
+ bool m_isRoot;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expression_store.cpp b/code/studio/src/plugins/gui_editor/expression_store.cpp
new file mode 100644
index 000000000..9f2218b4e
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_store.cpp
@@ -0,0 +1,105 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#include "expression_store.h"
+#include "expression_info.h"
+#include "expression_loader.h"
+#include
+#include
+
+class ExpressionStorePvt
+{
+public:
+
+ ~ExpressionStorePvt()
+ {
+ qDeleteAll( expressions );
+ expressions.clear();
+ }
+
+
+ QMap< QString, ExpressionInfo* > expressions;
+};
+
+ExpressionStore::ExpressionStore()
+{
+ m_pvt = new ExpressionStorePvt();
+}
+
+ExpressionStore::~ExpressionStore()
+{
+ delete m_pvt;
+ m_pvt = NULL;
+}
+
+
+bool ExpressionStore::load()
+{
+ QDir d( "expressions" );
+ if( !d.exists() )
+ return false;
+
+ QFileInfoList l = d.entryInfoList();
+ QListIterator< QFileInfo > itr( l );
+ if( !itr.hasNext() )
+ return false;
+
+ ExpressionLoader loader;
+
+ while( itr.hasNext() )
+ {
+ const QFileInfo &info = itr.next();
+ if( !info.isFile() )
+ continue;
+
+ if( info.suffix() != "xml" )
+ continue;
+
+ ExpressionInfo *expr = loader.load( info.absoluteFilePath() );
+ if( expr == NULL )
+ continue;
+
+ m_pvt->expressions[ expr->name ] = expr;
+ }
+
+ return false;
+}
+
+void ExpressionStore::getExpressions( QList< const ExpressionInfo* > &l ) const
+{
+ l.clear();
+
+ QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.constBegin();
+ while( itr != m_pvt->expressions.constEnd() )
+ {
+ l.push_back( itr.value() );
+ ++itr;
+ }
+}
+
+const ExpressionInfo* ExpressionStore::getInfo( const QString &name )
+{
+ QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.find( name );
+ if( itr == m_pvt->expressions.end() )
+ return NULL;
+ else
+ return itr.value();
+}
+
+
+
diff --git a/code/studio/src/plugins/gui_editor/expression_store.h b/code/studio/src/plugins/gui_editor/expression_store.h
new file mode 100644
index 000000000..9c29fa0f6
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expression_store.h
@@ -0,0 +1,46 @@
+// Ryzom Core Studio - GUI Editor Plugin
+//
+// Copyright (C) 2014 Laszlo Kis-Adam
+// Copyright (C) 2010 Ryzom Core
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef EXPRESSION_STORE
+#define EXPRESSION_STORE
+
+#include
+#include
+#include "expression_info.h"
+
+//struct ExpressionInfo;
+class ExpressionStorePvt;
+
+class ExpressionStore
+{
+public:
+ ExpressionStore();
+ ~ExpressionStore();
+
+ bool load();
+
+ void getExpressions( QList< const ExpressionInfo* > &l ) const;
+
+ const ExpressionInfo* getInfo( const QString &name );
+
+private:
+ ExpressionStorePvt *m_pvt;
+};
+
+#endif
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/add.xml b/code/studio/src/plugins/gui_editor/expressions/add.xml
new file mode 100644
index 000000000..62cec88af
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/add.xml
@@ -0,0 +1,9 @@
+
+Mathematical
+add
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/and.xml b/code/studio/src/plugins/gui_editor/expressions/and.xml
new file mode 100644
index 000000000..cc8c05c6e
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/and.xml
@@ -0,0 +1,9 @@
+
+Logical
+and
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/div.xml b/code/studio/src/plugins/gui_editor/expressions/div.xml
new file mode 100644
index 000000000..aba3faffc
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/div.xml
@@ -0,0 +1,9 @@
+
+Mathematical
+div
+false
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/eq.xml b/code/studio/src/plugins/gui_editor/expressions/eq.xml
new file mode 100644
index 000000000..77b7041cc
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/eq.xml
@@ -0,0 +1,9 @@
+
+Logical
+eq
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml
new file mode 100644
index 000000000..248a68332
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml
@@ -0,0 +1,10 @@
+
+Logical
+ifthenelse
+false
+
+if
+then
+else
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/mul.xml b/code/studio/src/plugins/gui_editor/expressions/mul.xml
new file mode 100644
index 000000000..54d03b025
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/mul.xml
@@ -0,0 +1,9 @@
+
+Mathematical
+mul
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/ne.xml b/code/studio/src/plugins/gui_editor/expressions/ne.xml
new file mode 100644
index 000000000..31d62af02
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/ne.xml
@@ -0,0 +1,9 @@
+
+Logical
+ne
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/not.xml b/code/studio/src/plugins/gui_editor/expressions/not.xml
new file mode 100644
index 000000000..872b9b7a4
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/not.xml
@@ -0,0 +1,8 @@
+
+Logical
+not
+false
+
+A
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/or.xml b/code/studio/src/plugins/gui_editor/expressions/or.xml
new file mode 100644
index 000000000..2d977267c
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/or.xml
@@ -0,0 +1,9 @@
+
+Logical
+or
+true
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/sub.xml b/code/studio/src/plugins/gui_editor/expressions/sub.xml
new file mode 100644
index 000000000..5f35c2895
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/sub.xml
@@ -0,0 +1,9 @@
+
+Mathematical
+sub
+false
+
+A
+B
+
+
diff --git a/code/studio/src/plugins/gui_editor/expressions/value.xml b/code/studio/src/plugins/gui_editor/expressions/value.xml
new file mode 100644
index 000000000..9bd57fc95
--- /dev/null
+++ b/code/studio/src/plugins/gui_editor/expressions/value.xml
@@ -0,0 +1,6 @@
+
+Value
+value
+true
+false
+
diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp
index 3f4e318db..9f6568936 100644
--- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp
+++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp
@@ -44,7 +44,6 @@
#include "editor_selection_watcher.h"
#include "editor_message_processor.h"
#include "add_widget_widget.h"
-#include "texture_chooser.h"
namespace GUIEditor
{
@@ -71,8 +70,6 @@ namespace GUIEditor
widgetInfoTree = new CWidgetInfoTree;
- tc = new TextureChooser();
-
createMenus();
readSettings();
@@ -118,9 +115,6 @@ namespace GUIEditor
removeMenus();
- delete tc;
- tc = NULL;
-
delete messageProcessor;
messageProcessor = NULL;
@@ -359,12 +353,6 @@ namespace GUIEditor
GUICtrl->show();
}
- void GUIEditorWindow::onTCClicked()
- {
- tc->load();
- tc->exec();
- }
-
void GUIEditorWindow::createMenus()
{
Core::MenuManager *mm = Core::ICore::instance()->menuManager();
@@ -411,10 +399,6 @@ namespace GUIEditor
connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) );
m->addAction( a );
- a = new QAction( "Texture Chooser", this );
- connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTCClicked() ) );
- m->addAction( a );
-
menu = m;
}
}
diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h
index d18a24813..cc2dfbc65 100644
--- a/code/studio/src/plugins/gui_editor/gui_editor_window.h
+++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h
@@ -25,11 +25,8 @@
#include "property_browser_ctrl.h"
class QtTreePropertyBrowser;
-
class QMenu;
-class TextureChooser;
-
namespace GUIEditor
{
@@ -67,8 +64,6 @@ private Q_SLOTS:
void onGUILoaded();
void onAddWidgetClicked();
void onTreeChanged();
- void onTCClicked();
-
protected:
void hideEvent( QHideEvent *evnt );
@@ -101,8 +96,6 @@ private:
QString currentProjectFile;
QMenu *menu;
-
- TextureChooser *tc;
};
}
diff --git a/code/studio/src/plugins/gui_editor/link_editor.cpp b/code/studio/src/plugins/gui_editor/link_editor.cpp
index c57a6cd09..3cb49f37a 100644
--- a/code/studio/src/plugins/gui_editor/link_editor.cpp
+++ b/code/studio/src/plugins/gui_editor/link_editor.cpp
@@ -18,20 +18,49 @@
#include "link_editor.h"
#include "nel/gui/interface_group.h"
#include "nel/gui/widget_manager.h"
+#include "expression_editor.h"
+#include
namespace GUIEditor
{
+ class LinkEditorPvt
+ {
+ public:
+
+ LinkEditorPvt()
+ {
+ ee = new ExpressionEditor();
+ ee->load();
+ }
+
+ ~LinkEditorPvt()
+ {
+ delete ee;
+ ee = NULL;
+ }
+
+ ExpressionEditor *ee;
+ };
+
+
LinkEditor::LinkEditor( QWidget *parent ) :
QWidget( parent )
{
setupUi( this );
setup();
+
+ m_pvt = new LinkEditorPvt();
+
connect( okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKButtonClicked() ) );
connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( hide() ) );
+ connect( expressionEdit, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( onTextEditContextMenu( const QPoint& ) ) );
+ connect( m_pvt->ee, SIGNAL( closing() ), this, SLOT( onEEClosing() ) );
}
LinkEditor::~LinkEditor()
{
+ delete m_pvt;
+ m_pvt = NULL;
}
void LinkEditor::setup()
@@ -89,4 +118,23 @@ namespace GUIEditor
hide();
}
+
+ void LinkEditor::onTextEditContextMenu( const QPoint &pos )
+ {
+ QMenu *menu = expressionEdit->createStandardContextMenu();
+ QAction *a = menu->addAction( "Expression Editor" );
+ connect( a, SIGNAL( triggered() ), this, SLOT( onEE() ) );
+
+ menu->exec( mapToGlobal( pos ) );
+ }
+
+ void LinkEditor::onEE()
+ {
+ m_pvt->ee->show();
+ }
+
+ void LinkEditor::onEEClosing()
+ {
+ expressionEdit->setPlainText( m_pvt->ee->result() );
+ }
}
diff --git a/code/studio/src/plugins/gui_editor/link_editor.h b/code/studio/src/plugins/gui_editor/link_editor.h
index b70019d20..f5617982e 100644
--- a/code/studio/src/plugins/gui_editor/link_editor.h
+++ b/code/studio/src/plugins/gui_editor/link_editor.h
@@ -23,6 +23,8 @@
namespace GUIEditor
{
+ class LinkEditorPvt;
+
class LinkEditor : public QWidget, public Ui::LinkEditor
{
Q_OBJECT
@@ -35,12 +37,16 @@ namespace GUIEditor
Q_SIGNALS:
void okClicked();
-
+
private Q_SLOTS:
void onOKButtonClicked();
+ void onTextEditContextMenu( const QPoint &pos );
+ void onEE();
+ void onEEClosing();
private:
uint32 currentLinkId;
+ LinkEditorPvt *m_pvt;
};
}
diff --git a/code/studio/src/plugins/gui_editor/link_editor.ui b/code/studio/src/plugins/gui_editor/link_editor.ui
index 13a6e7d7e..657b0eabc 100644
--- a/code/studio/src/plugins/gui_editor/link_editor.ui
+++ b/code/studio/src/plugins/gui_editor/link_editor.ui
@@ -26,6 +26,9 @@
-
+
+ Qt::CustomContextMenu
+