From 9f65dc5d2b6566f1bbfef8e59773bc5c89f42b17 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 9 Mar 2013 22:02:31 +0100 Subject: [PATCH] FIXED: Widgets will no longer get stuck in the widget hierarchy tree, when deleting their parent. --- code/nel/include/nel/gui/interface_element.h | 19 +++++ code/nel/src/gui/interface_element.cpp | 32 +++++++ .../plugins/gui_editor/widget_hierarchy.cpp | 84 ++++++++++++------- .../src/plugins/gui_editor/widget_hierarchy.h | 2 + 4 files changed, 109 insertions(+), 28 deletions(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 739f1b95e..83bda2c84 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -70,6 +70,14 @@ namespace NLGUI { public: + /// Watches CInterfaceElement deletions + class IDeletionWatcher + { + public: + IDeletionWatcher(){} + virtual ~IDeletionWatcher(){} + virtual void onDeleted( const std::string &name ){} + }; enum EStrech { @@ -489,6 +497,12 @@ namespace NLGUI /// Called when the widget is removed from it's parent group virtual void onRemoved(){} + /// Registers a deletion watcher + static void registerDeletionWatcher( IDeletionWatcher *watcher ); + + /// Unregisters a deletion watcher + static void unregisterDeletionWatcher( IDeletionWatcher *watcher ); + protected: bool editorSelected; @@ -549,6 +563,11 @@ namespace NLGUI void parseSizeRef(const char *sizeRefStr, sint32 &sizeref, sint32 &sizeDivW, sint32 &sizeDivH); private: + /// Notifies the deletion watchers that this interface element is being deleted + void notifyDeletionWatchers(); + + static std::vector< IDeletionWatcher* > deletionWatchers; + //void snapSize(); bool serializable; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index dc51735ff..9385887a4 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -32,6 +32,7 @@ using namespace NLMISC; namespace NLGUI { bool CInterfaceElement::editorMode = false; + std::vector< CInterfaceElement::IDeletionWatcher* > CInterfaceElement::deletionWatchers; // ------------------------------------------------------------------------------------------------ CInterfaceElement::~CInterfaceElement() @@ -44,6 +45,7 @@ namespace NLGUI } delete _Links; } + notifyDeletionWatchers(); } // ------------------------------------------------------------------------------------------------ @@ -1551,6 +1553,36 @@ namespace NLGUI } } + void CInterfaceElement::registerDeletionWatcher( IDeletionWatcher *watcher ) + { + std::vector< IDeletionWatcher* >::iterator itr + = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher ); + // Already registered + if( itr != deletionWatchers.end() ) + return; + deletionWatchers.push_back( watcher ); + } + + void CInterfaceElement::unregisterDeletionWatcher( IDeletionWatcher *watcher ) + { + std::vector< IDeletionWatcher* >::iterator itr + = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher ); + // Not registered + if( itr == deletionWatchers.end() ) + return; + deletionWatchers.erase( itr ); + } + + void CInterfaceElement::notifyDeletionWatchers() + { + std::vector< IDeletionWatcher* >::iterator itr = deletionWatchers.begin(); + while( itr != deletionWatchers.end() ) + { + (*itr)->onDeleted( _Id ); + ++itr; + } + } + CStringMapper* CStringShared::_UIStringMapper = NULL; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp index 96ae10aa3..2bab73c1e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp @@ -56,6 +56,26 @@ namespace name = s.toUtf8().constData(); return name; } + + class CWidgetDeletionWatcher : public CInterfaceElement::IDeletionWatcher + { + public: + CWidgetDeletionWatcher(){ h = NULL; } + + ~CWidgetDeletionWatcher(){} + + void onDeleted( const std::string &id ){ + if( h != NULL ) + h->onWidgetDeleted( id ); + } + + void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; } + + private: + GUIEditor::WidgetHierarchy *h; + }; + + CWidgetDeletionWatcher deletionWatcher; } namespace GUIEditor @@ -66,6 +86,7 @@ namespace GUIEditor setupUi( this ); connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); + deletionWatcher.setWidgetHierarchy( this ); } WidgetHierarchy::~WidgetHierarchy() @@ -74,6 +95,7 @@ namespace GUIEditor void WidgetHierarchy::clearHierarchy() { + CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher ); widgetHT->clear(); widgetHierarchyMap.clear(); } @@ -81,6 +103,7 @@ namespace GUIEditor void WidgetHierarchy::buildHierarchy( std::string &masterGroup ) { clearHierarchy(); + CInterfaceElement::registerDeletionWatcher( &deletionWatcher ); CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup ); if( mg != NULL ) @@ -131,6 +154,39 @@ namespace GUIEditor } } + void WidgetHierarchy::onWidgetDeleted( const std::string &id ) + { + std::map< std::string, QTreeWidgetItem* >::iterator itr + = widgetHierarchyMap.find( id ); + if( itr == widgetHierarchyMap.end() ) + return; + + if( widgetHT->currentItem() == itr->second ) + { + QTreeWidgetItem *item = itr->second; + QTreeWidgetItem *p = item; + + // Deselect item + item->setSelected( false ); + widgetHT->setCurrentItem( NULL ); + + // Collapse the tree + while( p != NULL ) + { + p->setExpanded( false ); + p = p->parent(); + } + + currentSelection = ""; + } + + itr->second->setSelected( false ); + + delete itr->second; + itr->second = NULL; + widgetHierarchyMap.erase( itr ); + } + void WidgetHierarchy::onGUILoaded() { if( masterGroup.empty() ) @@ -145,35 +201,7 @@ namespace GUIEditor return; if( newSelection.empty() ) - { - if( widgetHT->currentItem() != NULL ) - { - QTreeWidgetItem *item = widgetHT->currentItem(); - QTreeWidgetItem *p = item; - - // Deselect item - item->setSelected( false ); - widgetHT->setCurrentItem( NULL ); - - // Collapse the tree - while( p != NULL ) - { - p->setExpanded( false ); - p = p->parent(); - } - - // Finally remove the item! - delete item; - item = NULL; - - std::map< std::string, QTreeWidgetItem* >::iterator itr = - widgetHierarchyMap.find( currentSelection ); - if( itr != widgetHierarchyMap.end() ) - widgetHierarchyMap.erase( itr ); - currentSelection = ""; - } return; - } std::map< std::string, QTreeWidgetItem* >::iterator itr = widgetHierarchyMap.find( newSelection ); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h index 58e66212e..6de6b1366 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h @@ -42,6 +42,8 @@ namespace GUIEditor void clearHierarchy(); void buildHierarchy( std::string &masterGroup ); + void onWidgetDeleted( const std::string &id ); + private: void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group );