mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-23 15:46:18 +00:00
CHANGED: #1471 Widget property templates are now stored in a tree. Also added some new controls to the widget property dialog.
--HG-- branch : gsoc2012-gui-editor
This commit is contained in:
parent
d83c375981
commit
2cebadaa79
12 changed files with 496 additions and 106 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "../../3rdparty/qtpropertybrowser/QtTreePropertyBrowser"
|
||||
|
||||
#include "widget_properties.h"
|
||||
#include "widget_info_tree.h"
|
||||
#include "widget_properties_parser.h"
|
||||
#include "widget_hierarchy.h"
|
||||
#include "widget_serializer.h"
|
||||
|
@ -61,14 +62,17 @@ namespace GUIEditor
|
|||
viewPort = new NelGUIWidget;
|
||||
setCentralWidget( viewPort );
|
||||
|
||||
widgetInfoTree = new CWidgetInfoTree;
|
||||
|
||||
createMenus();
|
||||
readSettings();
|
||||
|
||||
CWidgetPropParser parser;
|
||||
|
||||
parser.setWidgetPropMap( &widgetInfo );
|
||||
parser.setWidgetInfoTree( widgetInfoTree );
|
||||
parser.parseGUIWidgets();
|
||||
widgetProps->setupWidgetInfo( &widgetInfo );
|
||||
widgetProps->setupWidgetInfo( widgetInfoTree );
|
||||
|
||||
QDockWidget *dock = new QDockWidget( "Widget Hierarchy", this );
|
||||
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
|
||||
|
@ -80,7 +84,7 @@ namespace GUIEditor
|
|||
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
|
||||
|
||||
QtTreePropertyBrowser *propBrowser = new QtTreePropertyBrowser;
|
||||
browserCtrl.setupWidgetInfo( widgetInfo );
|
||||
browserCtrl.setupWidgetInfo( widgetInfoTree );
|
||||
browserCtrl.setBrowser( propBrowser );
|
||||
dock->setWidget( propBrowser );
|
||||
addDockWidget( Qt::RightDockWidgetArea, dock );
|
||||
|
@ -116,6 +120,9 @@ namespace GUIEditor
|
|||
// no deletion needed for these, since dockwidget owns them
|
||||
hierarchyView = NULL;
|
||||
propBrowser = NULL;
|
||||
|
||||
delete widgetInfoTree;
|
||||
widgetInfoTree = NULL;
|
||||
}
|
||||
|
||||
QUndoStack *GUIEditorWindow::undoStack() const
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace GUIEditor
|
|||
class ProcList;
|
||||
class ProjectWindow;
|
||||
class NelGUIWidget;
|
||||
class CWidgetInfoTree;
|
||||
|
||||
class GUIEditorWindow: public QMainWindow
|
||||
{
|
||||
|
@ -76,6 +77,8 @@ private:
|
|||
ProjectWindow *projectWindow;
|
||||
NelGUIWidget *viewPort;
|
||||
|
||||
CWidgetInfoTree *widgetInfoTree;
|
||||
|
||||
CPropBrowserCtrl browserCtrl;
|
||||
QString currentProject;
|
||||
QString currentProjectFile;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nel/gui/interface_group.h"
|
||||
#include "nel/gui/widget_manager.h"
|
||||
#include <typeinfo>
|
||||
#include "widget_info_tree.h"
|
||||
|
||||
namespace GUIEditor
|
||||
{
|
||||
|
@ -42,14 +43,18 @@ namespace GUIEditor
|
|||
browser = b;
|
||||
}
|
||||
|
||||
void CPropBrowserCtrl::setupWidgetInfo( const std::map< std::string, SWidgetInfo > &info )
|
||||
void CPropBrowserCtrl::setupWidgetInfo( CWidgetInfoTree *tree )
|
||||
{
|
||||
widgetInfo.clear();
|
||||
|
||||
std::map< std::string, SWidgetInfo >::const_iterator itr;
|
||||
for( itr = info.begin(); itr != info.end(); ++itr )
|
||||
std::vector< std::string > names;
|
||||
tree->getNames( names );
|
||||
|
||||
std::vector< std::string >::const_iterator itr;
|
||||
for( itr = names.begin(); itr != names.end(); ++itr )
|
||||
{
|
||||
const SWidgetInfo &w = itr->second;
|
||||
CWidgetInfoTreeNode *node = tree->findNodeByName( *itr );
|
||||
const SWidgetInfo &w = node->getInfo();
|
||||
widgetInfo[ w.GUIName ] = w;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace NLGUI
|
|||
|
||||
namespace GUIEditor
|
||||
{
|
||||
class CWidgetInfoTree;
|
||||
|
||||
/// This class controls the Widget property browser widget.
|
||||
/// It receives signals from the widget that draws/manages the Nel GUI widgets, and handles them.
|
||||
|
@ -45,7 +46,7 @@ namespace GUIEditor
|
|||
CPropBrowserCtrl();
|
||||
~CPropBrowserCtrl();
|
||||
void setBrowser( QtTreePropertyBrowser *b );
|
||||
void setupWidgetInfo( const std::map< std::string, SWidgetInfo > &info );
|
||||
void setupWidgetInfo( CWidgetInfoTree *tree );
|
||||
void clear();
|
||||
|
||||
public Q_SLOTS:
|
||||
|
@ -60,9 +61,8 @@ namespace GUIEditor
|
|||
|
||||
QtTreePropertyBrowser *browser;
|
||||
QtVariantPropertyManager *propertyMgr;
|
||||
std::map< std::string, SWidgetInfo > widgetInfo;
|
||||
|
||||
std::string currentElement;
|
||||
std::map< std::string, SWidgetInfo > widgetInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,25 @@ namespace GUIEditor
|
|||
resolved = false;
|
||||
isAbstract = true;
|
||||
}
|
||||
|
||||
~SWidgetInfo()
|
||||
{
|
||||
resolved = false;
|
||||
isAbstract = false;
|
||||
}
|
||||
|
||||
/// Find a property by it's name
|
||||
std::vector< SPropEntry >::iterator findProp( const std::string &name )
|
||||
{
|
||||
std::vector< SPropEntry >::iterator itr = props.begin();
|
||||
while( itr != props.end() )
|
||||
{
|
||||
if( itr->propName == name )
|
||||
break;
|
||||
++itr;
|
||||
}
|
||||
return itr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
// Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef WIDGET_INFO_TREE_H
|
||||
#define WIDGET_INFO_TREE_H
|
||||
|
||||
#include "widget_info_tree_node.h"
|
||||
#include "nel/misc/debug.h"
|
||||
|
||||
namespace GUIEditor
|
||||
{
|
||||
class CWidgetInfoTree
|
||||
{
|
||||
public:
|
||||
CWidgetInfoTree()
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
~CWidgetInfoTree()
|
||||
{
|
||||
delete root;
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
/// Find a node by it's name
|
||||
CWidgetInfoTreeNode* findNodeByName( const std::string &name )
|
||||
{
|
||||
if( root == NULL )
|
||||
return NULL;
|
||||
|
||||
return root->findNodeByName( name );
|
||||
}
|
||||
|
||||
void addRootNode( SWidgetInfo &info )
|
||||
{
|
||||
nlassert( root == NULL );
|
||||
root = CWidgetInfoTreeNode::create( info );
|
||||
}
|
||||
|
||||
/// Add a new node as a child to it's ancestor
|
||||
bool addNode( SWidgetInfo &info )
|
||||
{
|
||||
CWidgetInfoTreeNode *node = findNodeByName( info.ancestor );
|
||||
if( node == NULL )
|
||||
return false;
|
||||
else
|
||||
node->addChild( info );
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Finds a node and removes it
|
||||
bool removeNode( SWidgetInfo *info )
|
||||
{
|
||||
CWidgetInfoTreeNode *node = findNodeByName( info->name );
|
||||
if( node == NULL )
|
||||
return false;
|
||||
|
||||
if( node == root )
|
||||
root = NULL;
|
||||
if( node->getParent() != NULL )
|
||||
node->getParent()->removeChildByNameND( node->getInfo().name );
|
||||
delete node;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Get the node names and put them into the vector
|
||||
void getNames( std::vector< std::string > &v ) const
|
||||
{
|
||||
if( root == NULL )
|
||||
return;
|
||||
root->getNames( v );
|
||||
}
|
||||
|
||||
private:
|
||||
CWidgetInfoTreeNode *root;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,182 @@
|
|||
// Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef WIDGET_INFO_TREE_NODE
|
||||
#define WIDGET_INFO_TREE_NODE
|
||||
|
||||
#include "widget_info.h"
|
||||
|
||||
namespace GUIEditor
|
||||
{
|
||||
|
||||
/// Widget Tree Info Node
|
||||
class CWidgetInfoTreeNode
|
||||
{
|
||||
public:
|
||||
CWidgetInfoTreeNode( SWidgetInfo &info )
|
||||
{
|
||||
this->info = info;
|
||||
parent = NULL;
|
||||
children.clear();
|
||||
}
|
||||
|
||||
~CWidgetInfoTreeNode()
|
||||
{
|
||||
removeChildren();
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
/// Set the parent of this node
|
||||
void setParent( CWidgetInfoTreeNode *newParent )
|
||||
{
|
||||
parent = newParent;
|
||||
}
|
||||
|
||||
|
||||
/// Returns the parent of this node
|
||||
CWidgetInfoTreeNode* getParent() const
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
/// Create a new node
|
||||
static CWidgetInfoTreeNode* create( SWidgetInfo &info )
|
||||
{
|
||||
return new CWidgetInfoTreeNode( info );
|
||||
}
|
||||
|
||||
/// Get the WidgetInfo of this node
|
||||
SWidgetInfo& getInfo()
|
||||
{
|
||||
return info;
|
||||
}
|
||||
|
||||
/// Add a new child node
|
||||
void addChild( SWidgetInfo &info )
|
||||
{
|
||||
CWidgetInfoTreeNode *node = CWidgetInfoTreeNode::create( info );
|
||||
node->setParent( this );
|
||||
children.push_back( node );
|
||||
|
||||
// copy the properties to the child, since they inherit them
|
||||
for( std::vector< SPropEntry >::const_iterator itr = this->info.props.begin(); itr != this->info.props.end(); ++itr )
|
||||
{
|
||||
node->addProperty( *itr );
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove child by name
|
||||
bool removeChildByName( const std::string &name )
|
||||
{
|
||||
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
|
||||
{
|
||||
if( ( *itr )->getInfo().name == name )
|
||||
{
|
||||
children.erase( itr );
|
||||
delete ( *itr );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Remove child by name, but don't delete the child
|
||||
bool removeChildByNameND( const std::string &name )
|
||||
{
|
||||
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
|
||||
{
|
||||
if( ( *itr )->getInfo().name == name )
|
||||
{
|
||||
children.erase( itr );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Remove child by ancestor's name
|
||||
bool removeChildByAncestor( const std::string &ancestor )
|
||||
{
|
||||
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
|
||||
{
|
||||
if( ( *itr )->getInfo().ancestor == ancestor )
|
||||
{
|
||||
children.erase( itr );
|
||||
delete ( *itr );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Remove all children
|
||||
void removeChildren()
|
||||
{
|
||||
std::vector< CWidgetInfoTreeNode* >::iterator itr = children.begin();
|
||||
while( itr != children.end() )
|
||||
{
|
||||
CWidgetInfoTreeNode *node = *itr;
|
||||
++itr;
|
||||
delete node;
|
||||
}
|
||||
children.clear();
|
||||
}
|
||||
|
||||
/// Add new property to the node
|
||||
void addProperty( const SPropEntry &prop )
|
||||
{
|
||||
info.props.push_back( prop );
|
||||
}
|
||||
|
||||
/// Find the node by it's name and then return a pointer to it
|
||||
CWidgetInfoTreeNode* findNodeByName( const std::string &name )
|
||||
{
|
||||
if( info.name == name )
|
||||
return this;
|
||||
|
||||
CWidgetInfoTreeNode *node = NULL;
|
||||
|
||||
for( std::vector< CWidgetInfoTreeNode* >::iterator itr = children.begin(); itr != children.end(); ++itr )
|
||||
{
|
||||
node = ( *itr )->findNodeByName( name );
|
||||
if( node != NULL )
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Get the node names and put them into the vector
|
||||
void getNames( std::vector< std::string > &v ) const
|
||||
{
|
||||
v.push_back( info.name );
|
||||
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
|
||||
( *itr )->getNames( v );
|
||||
}
|
||||
|
||||
private:
|
||||
SWidgetInfo info;
|
||||
CWidgetInfoTreeNode *parent;
|
||||
std::vector< CWidgetInfoTreeNode* > children;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -15,32 +15,34 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "widget_properties.h"
|
||||
#include "widget_info_tree.h"
|
||||
#include <qmessagebox.h>
|
||||
|
||||
namespace GUIEditor{
|
||||
CWidgetProperties::CWidgetProperties( QWidget *parent ) :
|
||||
QWidget( parent )
|
||||
{
|
||||
setupUi( this );
|
||||
connect( closeButton, SIGNAL( clicked(bool) ), this, SLOT( hide() ) );
|
||||
connect( rmWButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveWButtonClicked() ) );
|
||||
connect( rmPButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemovePButtonClicked() ) );
|
||||
}
|
||||
|
||||
CWidgetProperties::~CWidgetProperties()
|
||||
{
|
||||
}
|
||||
|
||||
void CWidgetProperties::setupWidgetInfo( std::map< std::string, SWidgetInfo > *info )
|
||||
void CWidgetProperties::setupWidgetInfo( CWidgetInfoTree *tree )
|
||||
{
|
||||
widgetInfo = info;
|
||||
for( std::map< std::string, SWidgetInfo >::iterator itr = info->begin(); itr != info->end(); ++itr ){
|
||||
widgetList->addItem( itr->first.c_str() );
|
||||
}
|
||||
|
||||
this->tree = tree;
|
||||
buildWidgetList();
|
||||
onListSelectionChanged( 0 );
|
||||
connect( widgetList, SIGNAL( currentRowChanged( int ) ), this, SLOT( onListSelectionChanged( int ) ) );
|
||||
}
|
||||
|
||||
void CWidgetProperties::onListSelectionChanged( int i )
|
||||
{
|
||||
if( i < 0 )
|
||||
return;
|
||||
if( i >= widgetList->count() )
|
||||
return;
|
||||
|
||||
|
@ -48,18 +50,82 @@ namespace GUIEditor{
|
|||
setPropsOf( item->text().toStdString().c_str() );
|
||||
}
|
||||
|
||||
|
||||
void CWidgetProperties::onRemoveWButtonClicked()
|
||||
{
|
||||
if( widgetList->count() == 0 )
|
||||
return;
|
||||
|
||||
QString widgetName = widgetList->currentItem()->text();
|
||||
|
||||
int reply = QMessageBox::question( this,
|
||||
tr( "Removing a widget" ),
|
||||
tr( "Are you sure you want to remove %1?" ).arg( widgetName ),
|
||||
QMessageBox::Yes | QMessageBox::Cancel
|
||||
);
|
||||
|
||||
if( reply != QMessageBox::Yes )
|
||||
return;
|
||||
|
||||
/*
|
||||
Remove the damned thing here
|
||||
*/
|
||||
|
||||
buildWidgetList();
|
||||
}
|
||||
|
||||
void CWidgetProperties::onRemovePButtonClicked()
|
||||
{
|
||||
QTreeWidgetItem *item = widgetPropTree->currentItem();
|
||||
CWidgetInfoTreeNode *node = tree->findNodeByName( widgetList->currentItem()->text().toStdString() );
|
||||
|
||||
if( ( item == NULL ) || ( node == NULL ) )
|
||||
return;
|
||||
|
||||
std::string name = item->text( 0 ).toStdString();
|
||||
|
||||
std::vector< SPropEntry >::const_iterator itr = node->getInfo().findProp( name );
|
||||
if( itr == node->getInfo().props.end() )
|
||||
return;
|
||||
|
||||
int reply = QMessageBox::question( this,
|
||||
tr( "Removing a property" ),
|
||||
tr( "Are you sure you want to remove" ).arg( QString( name.c_str() ) ),
|
||||
QMessageBox::Yes | QMessageBox::Cancel
|
||||
);
|
||||
|
||||
if( reply != QMessageBox::Yes )
|
||||
return;
|
||||
|
||||
/*
|
||||
Remove the damned thing here
|
||||
*/
|
||||
|
||||
onListSelectionChanged( widgetList->currentRow() );
|
||||
}
|
||||
|
||||
|
||||
void CWidgetProperties::buildWidgetList()
|
||||
{
|
||||
widgetList->clear();
|
||||
std::vector< std::string > widgetNames;
|
||||
tree->getNames( widgetNames );
|
||||
std::sort( widgetNames.begin(), widgetNames.end() );
|
||||
for( std::vector< std::string >::const_iterator itr = widgetNames.begin(); itr != widgetNames.end(); ++itr )
|
||||
widgetList->addItem( itr->c_str() );
|
||||
widgetList->setCurrentRow( 0 );
|
||||
}
|
||||
|
||||
void CWidgetProperties::setPropsOf( const char *name )
|
||||
{
|
||||
std::map< std::string, SWidgetInfo >::iterator itr =
|
||||
widgetInfo->find( name );
|
||||
|
||||
if( itr == widgetInfo->end() )
|
||||
CWidgetInfoTreeNode *node = tree->findNodeByName( name );
|
||||
if( node == NULL )
|
||||
return;
|
||||
|
||||
widgetPropTree->clear();
|
||||
|
||||
std::vector< SPropEntry > &v = itr->second.props;
|
||||
for( std::vector< SPropEntry >::iterator itr2 = v.begin(); itr2 != v.end(); ++itr2 )
|
||||
const std::vector< SPropEntry > &v = node->getInfo().props;
|
||||
for( std::vector< SPropEntry >::const_iterator itr2 = v.begin(); itr2 != v.end(); ++itr2 )
|
||||
{
|
||||
SPropEntry e = *itr2;
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem;
|
||||
|
@ -69,6 +135,5 @@ namespace GUIEditor{
|
|||
widgetPropTree->addTopLevelItem( item );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
namespace GUIEditor
|
||||
{
|
||||
class CWidgetInfoTree;
|
||||
|
||||
class CWidgetProperties : public QWidget, public Ui::WidgetProperties
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -33,14 +35,25 @@ namespace GUIEditor
|
|||
public:
|
||||
CWidgetProperties( QWidget *parent = NULL );
|
||||
~CWidgetProperties();
|
||||
void setupWidgetInfo( std::map< std::string, SWidgetInfo > *info );
|
||||
void setupWidgetInfo( CWidgetInfoTree *tree );
|
||||
|
||||
private Q_SLOTS:
|
||||
void onListSelectionChanged( int i );
|
||||
|
||||
/// Removes widget from the list
|
||||
void onRemoveWButtonClicked();
|
||||
|
||||
/// Removes widget property from the list
|
||||
void onRemovePButtonClicked();
|
||||
|
||||
private:
|
||||
/// Builds the widget list
|
||||
void buildWidgetList();
|
||||
|
||||
/// Builds the property list for the currently selected widget
|
||||
void setPropsOf( const char *name );
|
||||
std::map< std::string, SWidgetInfo > *widgetInfo;
|
||||
|
||||
CWidgetInfoTree *tree;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>308</height>
|
||||
<width>703</width>
|
||||
<height>302</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Widget Properties</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="widgetList"/>
|
||||
|
@ -40,38 +40,37 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>56</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<widget class="QPushButton" name="addWButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>428</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<widget class="QPushButton" name="rmWButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addPButton">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rmPButton">
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -19,11 +19,21 @@
|
|||
#include <QDir>
|
||||
#include <QStringList>
|
||||
#include "nel/misc/debug.h"
|
||||
#include "widget_info_tree.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
|
||||
namespace GUIEditor
|
||||
{
|
||||
CWidgetPropParser::CWidgetPropParser()
|
||||
{
|
||||
}
|
||||
|
||||
CWidgetPropParser::~CWidgetPropParser()
|
||||
{
|
||||
widgetInfoTree = NULL;
|
||||
}
|
||||
|
||||
void CWidgetPropParser::parseGUIWidgets()
|
||||
{
|
||||
QDir d( "widgets" );
|
||||
|
@ -47,7 +57,7 @@ namespace GUIEditor
|
|||
while( itr.hasNext() )
|
||||
parseGUIWidget( "widgets/" + itr.next() );
|
||||
|
||||
resolveInheritance();
|
||||
buildWidgetInfoTree();
|
||||
|
||||
widgetInfo = NULL;
|
||||
}
|
||||
|
@ -209,61 +219,48 @@ namespace GUIEditor
|
|||
}
|
||||
}
|
||||
|
||||
bool propCompare( const SPropEntry &left, const SPropEntry &right )
|
||||
{
|
||||
return left.propName < right.propName;
|
||||
}
|
||||
|
||||
void CWidgetPropParser::resolveInheritance()
|
||||
void CWidgetPropParser::buildWidgetInfoTree()
|
||||
{
|
||||
// First find the root node
|
||||
// It is the one which has no ancestor
|
||||
SWidgetInfo *info = NULL;
|
||||
for( std::map< std::string, SWidgetInfo >::iterator itr = widgetInfo->begin(); itr != widgetInfo->end(); ++itr )
|
||||
{
|
||||
resolveInheritanceFor( itr->first );
|
||||
std::sort( itr->second.props.begin(), itr->second.props.end(), propCompare );
|
||||
if( itr->second.ancestor.empty() )
|
||||
{
|
||||
info = &( itr->second );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CWidgetPropParser::resolveInheritanceFor( const std::string name )
|
||||
{
|
||||
if( name.empty() )
|
||||
// No root node, cannot continue!
|
||||
if( info == NULL )
|
||||
return;
|
||||
|
||||
std::map< std::string, SWidgetInfo >::iterator itr =
|
||||
widgetInfo->find( name );
|
||||
if( itr == widgetInfo->end() )
|
||||
return;
|
||||
|
||||
SWidgetInfo *info = &(itr->second);
|
||||
if( info->resolved )
|
||||
return;
|
||||
|
||||
if( info->ancestor.empty() )
|
||||
return;
|
||||
|
||||
std::vector< SPropEntry > &props = info->props;
|
||||
|
||||
SWidgetInfo *info2 = info;
|
||||
widgetInfoTree->addRootNode( *info );
|
||||
info->resolved = true;
|
||||
|
||||
// Now add the rest of the widgets
|
||||
bool added = false;
|
||||
do
|
||||
{
|
||||
if( info2->ancestor.empty() )
|
||||
break;
|
||||
|
||||
std::map< std::string, SWidgetInfo >::iterator itr2 =
|
||||
widgetInfo->find( info2->ancestor );
|
||||
if( itr2 == widgetInfo->end() )
|
||||
break;
|
||||
added = false;
|
||||
|
||||
info2 = &( itr2->second );
|
||||
|
||||
for( std::vector< SPropEntry >::iterator propItr = info2->props.begin(); propItr != info2->props.end(); ++propItr )
|
||||
props.push_back( *propItr );
|
||||
for( std::map< std::string, SWidgetInfo >::iterator itr = widgetInfo->begin(); itr != widgetInfo->end(); ++itr )
|
||||
{
|
||||
// Skip if already added
|
||||
if( itr->second.resolved )
|
||||
continue;
|
||||
|
||||
// Try to add it, if successful, mark it
|
||||
if( widgetInfoTree->addNode( itr->second ) )
|
||||
{
|
||||
itr->second.resolved = true;
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( !info2->resolved );
|
||||
|
||||
info->resolved = true;
|
||||
while( added );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,14 +26,18 @@
|
|||
|
||||
namespace GUIEditor
|
||||
{
|
||||
class CWidgetInfoTree;
|
||||
|
||||
/// Parser for the widget properties XML files
|
||||
class CWidgetPropParser
|
||||
{
|
||||
public:
|
||||
CWidgetPropParser(){}
|
||||
~CWidgetPropParser(){}
|
||||
|
||||
CWidgetPropParser();
|
||||
~CWidgetPropParser();
|
||||
void setWidgetPropMap( std::map< std::string, SWidgetInfo > *info ){ widgetInfo = info; }
|
||||
void setWidgetInfoTree( CWidgetInfoTree *tree ){ widgetInfoTree = tree; }
|
||||
|
||||
/// Parse the GUI widget template definitions
|
||||
void parseGUIWidgets();
|
||||
|
||||
private:
|
||||
|
@ -41,10 +45,12 @@ namespace GUIEditor
|
|||
void parseGUIWidgetXML( QFile &file );
|
||||
QString parseGUIWidgetHeader( QXmlStreamReader &reader );
|
||||
void parseGUIWidgetProperties( QXmlStreamReader &reader, const QString &widgetName );
|
||||
void resolveInheritance();
|
||||
void resolveInheritanceFor( const std::string name );
|
||||
|
||||
/// Build the widget info tree from the parsed data
|
||||
void buildWidgetInfoTree();
|
||||
|
||||
std::map< std::string, SWidgetInfo > *widgetInfo;
|
||||
std::map< std::string, SWidgetInfo > *widgetInfo;
|
||||
CWidgetInfoTree *widgetInfoTree;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue