From 62744db86d24b6aad5f61ff19394875c877d83f8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:20:25 +0200 Subject: [PATCH 01/29] Dragged elements will no longer disappear. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 ++- code/nel/src/gui/widget_manager.cpp | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 5d2468e7a..ccf561d45 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -532,7 +532,8 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; - NLMISC::CRefPtr< CInterfaceElement > draggedElement; + NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging + std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e3f1064fa..c985557c5 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1036,6 +1036,8 @@ namespace NLGUI setCapturePointerLeft(NULL); setCapturePointerRight(NULL); _CapturedView = NULL; + + _OrphanElements.clear(); resetColorProps(); resetAlphaRolloverSpeedProps(); @@ -2039,6 +2041,15 @@ namespace NLGUI } } + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); + while( oeitr != _OrphanElements.end() ) + { + CInterfaceElement *e = *oeitr; + CViewBase *v = dynamic_cast< CViewBase* >( e ); + v->draw(); + ++oeitr; + } + if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2657,7 +2668,11 @@ namespace NLGUI void CWidgetManager::stopDragging() { - draggedElement = NULL; + if( draggedElement != NULL ) + { + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; + } } // ------------------------------------------------------------------------------------------------ @@ -3454,6 +3469,8 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { + _OrphanElements.clear(); + for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From f9dbef7df70fb0cc5e21723fe3caa77d8109bd6a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 16:31:26 +0200 Subject: [PATCH 02/29] Set dragged widgets' coordinates based on the move rather than the mouse pointer's coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c985557c5..5b131ee36 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,8 +2633,11 @@ namespace NLGUI else if( draggedElement != NULL ) { - draggedElement->setXReal( newX ); - draggedElement->setYReal( newY ); + sint32 dx = newX - oldX; + sint32 dy = newY - oldY; + + draggedElement->setXReal( draggedElement->getXReal() + dx ); + draggedElement->setYReal( draggedElement->getYReal() + dy ); draggedElement->invalidateCoords(); } } From bd7cb1eea3d4e3d974279b8f4b5e412a1c65bda1 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 18:45:52 +0200 Subject: [PATCH 03/29] Add widget to a new parent when the widget being dragged is dropped, otherwise add it to the orphanlist so that it's drawn anyways. NOTE: The dropped widget can be clipped. If it is clipped, it never shows up even tho it's there. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 1 + code/nel/src/gui/interface_group.cpp | 30 ++++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 19 +++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index ff0efac3b..daf6d2d53 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -57,6 +57,7 @@ namespace NLGUI CInterfaceElement* findFromShortId(const std::string &id); /// Dynamic creation + virtual void addElement (CInterfaceElement *child, sint eltOrder = -1 ); virtual void addView (CViewBase *child , sint eltOrder = -1); virtual void addCtrl (CCtrlBase *child, sint eltOrder = -1); virtual void addGroup (CInterfaceGroup *child, sint eltOrder = -1); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 4d37eda1c..05f210568 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -911,6 +911,31 @@ namespace NLGUI } } + // ------------------------------------------------------------------------------------------------ + void CInterfaceGroup::addElement (CInterfaceElement *child, sint eltOrder /*= -1*/) + { + if (!child) + { + nlwarning(" : tried to add a NULL view"); + return; + } + + if( child->isGroup() ) + { + addGroup( static_cast< CInterfaceGroup* >( child ), eltOrder ); + } + else + if( child->isCtrl() ) + { + addCtrl( static_cast< CCtrlBase* >( child ), eltOrder ); + } + else + if( child->isView() ) + { + addView( static_cast< CViewBase* >( child ), eltOrder ); + } + } + // ------------------------------------------------------------------------------------------------ void CInterfaceGroup::addView (CViewBase *child, sint eltOrder /*= -1*/) { @@ -1312,6 +1337,11 @@ namespace NLGUI for (ite = _EltOrder.begin() ; ite != _EltOrder.end(); ite++) { CViewBase *pVB = *ite; + if( pVB->getName() == "=MARKED=" ) + { + nlinfo( "=MARKED=" ); + } + if (pVB->getActive()) pVB->draw(); } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b131ee36..e44fa4d15 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2673,7 +2673,24 @@ namespace NLGUI { if( draggedElement != NULL ) { - _OrphanElements.push_back( draggedElement ); + CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + + if( g != NULL ) + { + CInterfaceElement *e = draggedElement; + e->setName( "=MARKED=" ); + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + g->addElement( e ); + + e->setParentPos( g ); + e->setParentSize( g ); + + checkCoords(); + } + else + _OrphanElements.push_back( draggedElement ); + draggedElement = NULL; } } From e7ab56beea0861700c24a414db2eb7454af41690 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 20:40:37 +0200 Subject: [PATCH 04/29] Orphaned widgets won't get stuck. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 62 ++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index e44fa4d15..771bcf50e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2410,20 +2410,45 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + + if( CInterfaceElement::getEditorMode() ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); + while( itr != _OrphanElements.rend() ) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + CInterfaceElement *e = *itr; + + int x = getPointer()->getXReal(); + int y = getPointer()->getYReal(); + + if( e->isIn( x, y ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); + _CapturedView = static_cast< CViewBase* >( e ); captured = true; + break; + } + + ++itr; + } + } + + if( !captured ) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + { + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + { + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } @@ -2674,23 +2699,22 @@ namespace NLGUI if( draggedElement != NULL ) { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); + CInterfaceElement *e = draggedElement; + + e->setParent( g ); + e->setIdRecurse( e->getShortId() ); + e->setParentPos( g ); + e->setParentSize( g ); if( g != NULL ) { - CInterfaceElement *e = draggedElement; - e->setName( "=MARKED=" ); - e->setParent( g ); - e->setIdRecurse( e->getShortId() ); g->addElement( e ); - - e->setParentPos( g ); - e->setParentSize( g ); - - checkCoords(); } else _OrphanElements.push_back( draggedElement ); + checkCoords(); + draggedElement = NULL; } } From a658be39b71bf9d16946b3e3e89944bd2b027fd9 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 22:59:40 +0200 Subject: [PATCH 05/29] No need for free floating elements when we can simply reparent to the top window... --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 1 - code/nel/src/gui/widget_manager.cpp | 73 +++++------------------ 2 files changed, 16 insertions(+), 58 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index ccf561d45..8bd9052e5 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -533,7 +533,6 @@ namespace NLGUI NLMISC::CRefPtr< CViewBase > _CapturedView; NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging - std::vector< NLMISC::CRefPtr< CInterfaceElement > > _OrphanElements; // elements that were dragged out of their parents bool startDragging(); void stopDragging(); diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 771bcf50e..40df50cb2 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -1037,8 +1037,6 @@ namespace NLGUI setCapturePointerRight(NULL); _CapturedView = NULL; - _OrphanElements.clear(); - resetColorProps(); resetAlphaRolloverSpeedProps(); resetGlobalAlphasProps(); @@ -2041,15 +2039,6 @@ namespace NLGUI } } - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::iterator oeitr = _OrphanElements.begin(); - while( oeitr != _OrphanElements.end() ) - { - CInterfaceElement *e = *oeitr; - CViewBase *v = dynamic_cast< CViewBase* >( e ); - v->draw(); - ++oeitr; - } - if( draggedElement != NULL ) { CInterfaceElement *e = draggedElement; @@ -2411,44 +2400,20 @@ namespace NLGUI if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) { - std::vector< NLMISC::CRefPtr< CInterfaceElement > >::reverse_iterator itr = _OrphanElements.rbegin(); - while( itr != _OrphanElements.rend() ) + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - CInterfaceElement *e = *itr; - - int x = getPointer()->getXReal(); - int y = getPointer()->getYReal(); - - if( e->isIn( x, y ) ) + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) { - _CapturedView = static_cast< CViewBase* >( e ); + nMaxDepth = d; + setCapturePointerLeft( ctrl ); captured = true; - break; - } - - ++itr; - } - } - - if( !captured ) - { - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) - { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) - { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) - { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; - } } } } @@ -2690,7 +2655,7 @@ namespace NLGUI e->setParent( NULL ); draggedElement = e; - + return true; } @@ -2700,20 +2665,16 @@ namespace NLGUI { CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() ); CInterfaceElement *e = draggedElement; + CInterfaceGroup *tw = getTopWindow(); + + if( g == NULL ) + g = tw; e->setParent( g ); e->setIdRecurse( e->getShortId() ); e->setParentPos( g ); e->setParentSize( g ); - - if( g != NULL ) - { - g->addElement( e ); - } - else - _OrphanElements.push_back( draggedElement ); - - checkCoords(); + g->addElement( e ); draggedElement = NULL; } @@ -3513,8 +3474,6 @@ namespace NLGUI CWidgetManager::~CWidgetManager() { - _OrphanElements.clear(); - for (uint32 i = 0; i < _MasterGroups.size(); ++i) { delete _MasterGroups[i].Group; From 006f87278b78ae7ef08d3de6a6d0856194f29559 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:32:24 +0200 Subject: [PATCH 06/29] Refactored IWidgetAdditionWatcher, now it's called IWidgetWatcher and it also reports widget moves. --HG-- branch : dfighter-tools --- .../include/nel/gui/widget_addition_watcher.h | 32 ----------- code/nel/include/nel/gui/widget_manager.h | 22 ++++++-- code/nel/src/gui/widget_manager.cpp | 53 ++++++++++++------- .../plugins/gui_editor/widget_hierarchy.cpp | 29 ++++++---- .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 5 files changed, 70 insertions(+), 67 deletions(-) delete mode 100644 code/nel/include/nel/gui/widget_addition_watcher.h diff --git a/code/nel/include/nel/gui/widget_addition_watcher.h b/code/nel/include/nel/gui/widget_addition_watcher.h deleted file mode 100644 index a2717e398..000000000 --- a/code/nel/include/nel/gui/widget_addition_watcher.h +++ /dev/null @@ -1,32 +0,0 @@ -// Ryzom - MMORPG Framework -// 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 . - -#ifndef WIDGET_ADD_WATCHER -#define WIDGET_ADD_WATCHER - -#include - -namespace NLGUI -{ - class IWidgetAdditionWatcher - { - public: - virtual void widgetAdded( const std::string &name ) = 0; - }; -} - -#endif - diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8bd9052e5..89023c445 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -75,6 +75,16 @@ namespace NLGUI virtual void process() = 0; }; + // Interface for event handlers that can be called when widgets are added or moved + class IWidgetWatcher + { + public: + IWidgetWatcher(){} + virtual ~IWidgetWatcher(){} + virtual void onWidgetAdded( const std::string &name ) = 0; + virtual void onWidgetMoved( const std::string &oldid, const std::string &newid ) = 0; + }; + /// Frame render times struct SInterfaceTimes { @@ -498,10 +508,12 @@ namespace NLGUI void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); - - void notifyAdditionWatchers( const std::string &widgetName ); - void registerAdditionWatcher( IWidgetAdditionWatcher *watcher ); - void unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ); + + + void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); + void registerWidgetWatcher( IWidgetWatcher *watcher ); + void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); @@ -594,7 +606,7 @@ namespace NLGUI std::vector< INewScreenSizeHandler* > newScreenSizeHandlers; std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers; std::vector< IEditorSelectionWatcher* > selectionWatchers; - std::vector< IWidgetAdditionWatcher* > additionWatchers; + std::vector< IWidgetWatcher* > widgetWatchers; std::string currentEditorSelection; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 40df50cb2..11ad888f4 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -34,7 +34,6 @@ #include "nel/gui/interface_expr.h" #include "nel/gui/reflect_register.h" #include "nel/gui/editor_selection_watcher.h" -#include "nel/gui/widget_addition_watcher.h" #include "nel/misc/events.h" namespace NLGUI @@ -2669,6 +2668,8 @@ namespace NLGUI if( g == NULL ) g = tw; + + std::string oldid = e->getId(); e->setParent( g ); e->setIdRecurse( e->getShortId() ); @@ -2677,6 +2678,8 @@ namespace NLGUI g->addElement( e ); draggedElement = NULL; + + onWidgetMoved( oldid, e->getId() ); } } @@ -3364,36 +3367,46 @@ namespace NLGUI selectionWatchers.erase( itr ); } - void CWidgetManager::notifyAdditionWatchers( const std::string &widgetName ) + void CWidgetManager::onWidgetAdded( const std::string &id ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr = additionWatchers.begin(); - while( itr != additionWatchers.end() ) + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) { - (*itr)->widgetAdded( widgetName ); + (*itr)->onWidgetAdded( id ); ++itr; } } - void CWidgetManager::registerAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::onWidgetMoved( const std::string &oldid, const std::string &newid ) { - std::vector< IWidgetAdditionWatcher* >::const_iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); - // already exists - if( itr != additionWatchers.end() ) - return; - - additionWatchers.push_back( watcher ); + std::vector< IWidgetWatcher* >::const_iterator itr = widgetWatchers.begin(); + while( itr != widgetWatchers.end() ) + { + (*itr)->onWidgetMoved( oldid, newid ); + ++itr; + } } - void CWidgetManager::unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher ) + void CWidgetManager::registerWidgetWatcher( IWidgetWatcher *watcher ) { - std::vector< IWidgetAdditionWatcher* >::iterator itr - = std::find( additionWatchers.begin(), additionWatchers.end(), watcher ); - // doesn't exist - if( itr == additionWatchers.end() ) + std::vector< IWidgetWatcher* >::const_iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); + // already exists + if( itr != widgetWatchers.end() ) return; - additionWatchers.erase( itr ); + widgetWatchers.push_back( watcher ); + } + + void CWidgetManager::unregisterWidgetWatcher( IWidgetWatcher *watcher ) + { + std::vector< IWidgetWatcher* >::iterator itr + = std::find( widgetWatchers.begin(), widgetWatchers.end(), watcher ); + // doesn't exist + if( itr == widgetWatchers.end() ) + return; + + widgetWatchers.erase( itr ); } CInterfaceElement* CWidgetManager::addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ) @@ -3426,7 +3439,7 @@ namespace NLGUI else g->addView( v ); - notifyAdditionWatchers( v->getId() ); + onWidgetAdded( v->getId() ); return v; } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 24208f4a3..8318ea926 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -18,7 +18,6 @@ #include "widget_hierarchy.h" #include "nel/gui/interface_group.h" #include "nel/gui/widget_manager.h" -#include "nel/gui/widget_addition_watcher.h" namespace { @@ -76,18 +75,24 @@ namespace GUIEditor::WidgetHierarchy *h; }; - class CWidgetAdditionWatcher : public IWidgetAdditionWatcher + class CWidgetWatcher : public CWidgetManager::IWidgetWatcher { public: - CWidgetAdditionWatcher(){ h = NULL; } - ~CWidgetAdditionWatcher(){} + CWidgetWatcher(){ h = NULL; } + ~CWidgetWatcher(){} - void widgetAdded( const std::string &name ) + void onWidgetAdded( const std::string &name ) { if( h != NULL ) h->onWidgetAdded( name ); } - + + void onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + if( h != NULL ) + h->onWidgetMoved( oldid, newid ); + } + void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; } private: @@ -95,7 +100,7 @@ namespace }; CWidgetDeletionWatcher deletionWatcher; - CWidgetAdditionWatcher additionWatcher; + CWidgetWatcher widgetwatcher; } namespace GUIEditor @@ -107,7 +112,7 @@ namespace GUIEditor connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); deletionWatcher.setWidgetHierarchy( this ); - additionWatcher.setWidgetHierarchy( this ); + widgetwatcher.setWidgetHierarchy( this ); } WidgetHierarchy::~WidgetHierarchy() @@ -117,7 +122,7 @@ namespace GUIEditor void WidgetHierarchy::clearHierarchy() { CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->unregisterAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->unregisterWidgetWatcher( &widgetwatcher ); widgetHT->clear(); widgetHierarchyMap.clear(); } @@ -126,7 +131,7 @@ namespace GUIEditor { clearHierarchy(); CInterfaceElement::registerDeletionWatcher( &deletionWatcher ); - CWidgetManager::getInstance()->registerAdditionWatcher( &additionWatcher ); + CWidgetManager::getInstance()->registerWidgetWatcher( &widgetwatcher ); CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup ); if( mg != NULL ) @@ -231,6 +236,10 @@ namespace GUIEditor widgetHierarchyMap[ id ] = item; } + void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) + { + } + void WidgetHierarchy::getCurrentGroup( QString &g ) { std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 4641c8ce8..e416ec145 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -44,6 +44,7 @@ namespace GUIEditor void onWidgetDeleted( const std::string &id ); void onWidgetAdded( const std::string &id ); + void onWidgetMoved( const std::string &oldid, const std::string &newid ); void getCurrentGroup( QString &g ); From 9cae0c179397b26b44312d2b1f4fc152eba24937 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 24 Sep 2014 23:56:11 +0200 Subject: [PATCH 07/29] When repareting a widget, remove the old item from the hierarchy and add a new one at the right place. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 48 +++++++++++++++++++ .../src/plugins/gui_editor/widget_hierarchy.h | 2 + 2 files changed, 50 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 8318ea926..333386aca 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -182,6 +182,27 @@ namespace GUIEditor } } + QTreeWidgetItem* WidgetHierarchy::findItem( const std::string &id ) + { + std::map< std::string, QTreeWidgetItem* >::iterator itr + = widgetHierarchyMap.find( id ); + if( itr == widgetHierarchyMap.end() ) + return NULL; + else + return itr->second; + } + + QTreeWidgetItem* WidgetHierarchy::findParent( const std::string &id ) + { + // Get the parent's name + std::string::size_type p = id.find_last_of( ':' ); + if( p == std::string::npos ) + return NULL; + std::string parentId = id.substr( 0, p ); + + return findItem( parentId ); + } + void WidgetHierarchy::onWidgetDeleted( const std::string &id ) { std::map< std::string, QTreeWidgetItem* >::iterator itr @@ -238,6 +259,33 @@ namespace GUIEditor void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid ) { + QTreeWidgetItem *newParent = NULL; + QTreeWidgetItem *item = NULL; + QString id; + + newParent = findParent( newid ); + item = findItem( oldid ); + + if( ( newParent == NULL ) || ( item == NULL ) ) + return; + + // Remove old item + QTreeWidgetItem *p = item->parent(); + if( p != NULL ) + p->setExpanded( false ); + id = item->data( 0, Qt::DisplayRole ).toString(); + delete item; + item = NULL; + + // Remove reference to old item + widgetHierarchyMap.erase( oldid ); + + // Add new item + item = new QTreeWidgetItem(); + item->setData( 0, Qt::DisplayRole, id ); + item->setSelected( true ); + newParent->addChild( item ); + newParent->setExpanded( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index e416ec145..3d748e15f 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -50,6 +50,8 @@ namespace GUIEditor private: void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); + QTreeWidgetItem* findItem( const std::string &id ); + QTreeWidgetItem* findParent( const std::string &id ); public Q_SLOTS: void onGUILoaded(); From 4ec13e57e4097b9962e67d63203e1047037e3281 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 25 Sep 2014 00:37:25 +0200 Subject: [PATCH 08/29] Collapse the tree, and only expand the items that are needed to get to the selected items. --HG-- branch : dfighter-tools --- .../plugins/gui_editor/widget_hierarchy.cpp | 34 +++++++++++++------ .../src/plugins/gui_editor/widget_hierarchy.h | 1 + 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 333386aca..d52f55e27 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -285,7 +285,24 @@ namespace GUIEditor item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - newParent->setExpanded( true ); + + + selectItem( item ); + } + + void WidgetHierarchy::selectItem( QTreeWidgetItem *item ) + { + widgetHT->collapseAll(); + + QTreeWidgetItem *currItem = item; + while( currItem != NULL ) + { + currItem->setExpanded( true ); + currItem = currItem->parent(); + } + + widgetHT->setCurrentItem( item ); + item->setSelected( true ); } void WidgetHierarchy::getCurrentGroup( QString &g ) @@ -345,18 +362,11 @@ namespace GUIEditor if( widgetHT->currentItem() != NULL ) widgetHT->currentItem()->setSelected( false ); - // expand the tree items, so that we can see the selected item - QTreeWidgetItem *item = itr->second; - QTreeWidgetItem *currItem = item; - while( currItem != NULL ) - { - currItem->setExpanded( true ); - currItem = currItem->parent(); - } + widgetHT->collapseAll(); // select the current item - item->setSelected( true ); - widgetHT->setCurrentItem( item ); + QTreeWidgetItem *item = itr->second; + selectItem( item ); currentSelection = newSelection; } @@ -364,6 +374,8 @@ namespace GUIEditor { if( item->parent() == NULL ) return; + + selectItem( item ); std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 3d748e15f..27218715d 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -52,6 +52,7 @@ namespace GUIEditor void buildHierarchy( QTreeWidgetItem *parent, NLGUI::CInterfaceGroup *group ); QTreeWidgetItem* findItem( const std::string &id ); QTreeWidgetItem* findParent( const std::string &id ); + void selectItem( QTreeWidgetItem *item ); public Q_SLOTS: void onGUILoaded(); From 8c3702f826f8826e0044b01647a4d1db5924ebee Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:00:52 +0200 Subject: [PATCH 09/29] Update coords when changing something. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bd73fb7fa..bfdd0d6fa 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -493,6 +493,10 @@ namespace GUIEditor if( e == NULL ) return; e->setProperty( propName.toUtf8().constData(), propValue.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); // Make sure the changes are applied @@ -631,6 +635,16 @@ namespace GUIEditor e->setProperty( propName.toUtf8().constData(), v ); } + + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e != NULL ) + { + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); + } + } @@ -643,6 +657,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::onTexturePropertyChanged( QtProperty *p, const QString &v ) @@ -654,6 +672,10 @@ namespace GUIEditor return; e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() ); + + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } void CPropBrowserCtrl::enablePropertyWatchers() From 0af278e50a7fe94d8d8e83e19bbbd202691d6219 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 01:04:49 +0200 Subject: [PATCH 10/29] A little bit of refactoring. --HG-- branch : dfighter-tools --- .../gui_editor/property_browser_ctrl.cpp | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index bfdd0d6fa..c005f80e5 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -518,13 +518,12 @@ namespace GUIEditor return; std::string type = itr->second; + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); + if( e == NULL ) + return; if( type == "button_type" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelButtonType::toString( value ); if( v.empty() ) @@ -535,10 +534,6 @@ namespace GUIEditor else if( type == "text_justification" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v; v = NelTxtJustification::toString( value ); if( v.empty() ) @@ -549,10 +544,6 @@ namespace GUIEditor else if( type == "posref" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRef::toString( value ); if( v.empty() ) return; @@ -562,10 +553,6 @@ namespace GUIEditor else if( type == "posreftt" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelPosRefTT::toString( value ); if( v.empty() ) return; @@ -612,10 +599,6 @@ namespace GUIEditor else if( type == "tooltip_parent" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelTTParent::toString( value ); if( v.empty() ) return; @@ -625,10 +608,6 @@ namespace GUIEditor else if( type == "bitmap_align" ) { - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e == NULL ) - return; - std::string v = NelBMAlign::toString( value ); if( v.empty() ) return; @@ -637,13 +616,9 @@ namespace GUIEditor } - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( currentElement ); - if( e != NULL ) - { - CInterfaceGroup *g = e->getParent(); - if( g != NULL ) - g->updateCoords(); - } + CInterfaceGroup *g = e->getParent(); + if( g != NULL ) + g->updateCoords(); } From 4797b150d8015c209ef3f268d0dc69f449d641d4 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 19:54:19 +0200 Subject: [PATCH 11/29] Move the text too with the text button. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/view_text.h | 9 ++++++++- code/nel/src/gui/ctrl_text_button.cpp | 22 ++++++++++------------ code/nel/src/gui/view_text.cpp | 13 +++++++++++-- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h index df3cf27e3..e7cc54d82 100644 --- a/code/nel/include/nel/gui/view_text.h +++ b/code/nel/include/nel/gui/view_text.h @@ -202,7 +202,11 @@ namespace NLGUI REFLECT_EXPORT_END - virtual void serial(NLMISC::IStream &f); + virtual void serial(NLMISC::IStream &f); + + // Sets the parent element + // See the comment at the field + void setParentElm( CInterfaceElement *parent ){ _ParentElm = parent; } protected: std::string _HardtextFormat; @@ -379,6 +383,9 @@ namespace NLGUI /// Dynamic tooltips std::vector _Tooltips; + // Parent element is the element where this text belongs to + // For example: text button + CInterfaceElement *_ParentElm; private: void setup (); diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index d3a0f6765..b14fb27ca 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -66,8 +66,6 @@ namespace NLGUI { if( _ViewText != NULL ) { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); delete _ViewText; _ViewText = NULL; } @@ -569,6 +567,7 @@ namespace NLGUI ((CViewTextID*)_ViewText)->parseTextIdOptions(cur); // Same RenderLayer as us. _ViewText->setRenderLayer(getRenderLayer()); + _ViewText->setParentElm(this); // Parse the hardText (if not text id) if(!_IsViewTextId) { @@ -863,6 +862,12 @@ namespace NLGUI } if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); + + // When dragging the button, the text needs to move too + if( CInterfaceElement::editorMode ) + _ViewText->updateCoords(); + + _ViewText->draw(); } } @@ -873,6 +878,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); + _ViewText->updateCoords(); + // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) { @@ -910,15 +917,13 @@ namespace NLGUI } // setup the viewText and add to parent - _ViewText->setParent (getParent()); + _ViewText->setParentElm (this); _ViewText->setParentPos (this); _ViewText->setParentPosRef (_TextParentPosRef); _ViewText->setPosRef (_TextPosRef); _ViewText->setActive(_Active); _ViewText->setX(_TextX); _ViewText->setY(_TextY); - - getParent()->addView(_ViewText); } // *************************************************************************** @@ -1007,17 +1012,10 @@ namespace NLGUI // *************************************************************************** void CCtrlTextButton::onRemoved() { - if( _ViewText != NULL ) - { - if( _Parent != NULL ) - _Parent->delView( _ViewText, true ); - } } void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { - if( e == _ViewText ) - _ViewText = NULL; } } diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp index 6ff1930af..602126dd8 100644 --- a/code/nel/src/gui/view_text.cpp +++ b/code/nel/src/gui/view_text.cpp @@ -1814,9 +1814,18 @@ namespace NLGUI if (_AutoClamp) { CViewBase::updateCoords (); - if (_Parent) + + // If there's no parent, try the parent of the parent element. + // Since we will be under the same group + CInterfaceGroup *parent = _Parent; + if( parent == NULL ) + { + if( _ParentElm != NULL ) + parent = _ParentElm->getParent(); + } + + if (parent) { - CInterfaceGroup *parent = _Parent; // avoid resizing parents to compute the limiter while (parent && (parent->getResizeFromChildW() || parent->isGroupList() )) { From 0055e2dd91d95c562c9620fddf01908f719895b8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:15:46 +0200 Subject: [PATCH 12/29] A little refactoring. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/ctrl_text_button.h | 1 + code/nel/include/nel/gui/interface_element.h | 8 ++++++++ code/nel/src/gui/ctrl_text_button.cpp | 12 ++++++++---- code/nel/src/gui/widget_manager.cpp | 4 +--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index 183b6a65e..d2b49ffa9 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -126,6 +126,7 @@ namespace NLGUI void onRemoved(); void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); protected: diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index db7a499c8..048ec4b6e 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -510,6 +510,14 @@ namespace NLGUI /// so other widgets in the group can check if it belongs to them virtual void onWidgetDeleted( CInterfaceElement *e ){} + /// Move the element by x in the X direction and y in the Y direction + // Uses real coordinates + virtual void moveBy( sint32 x, sint32 y ) + { + _XReal += x; + _YReal += y; + } + protected: bool editorSelected; diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index b14fb27ca..03db2b797 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -863,10 +863,6 @@ namespace NLGUI if(getFrozen() && getFrozenHalfTone()) _ViewText->setAlpha(_ViewText->getAlpha()>>2); - // When dragging the button, the text needs to move too - if( CInterfaceElement::editorMode ) - _ViewText->updateCoords(); - _ViewText->draw(); } } @@ -1017,5 +1013,13 @@ namespace NLGUI void CCtrlTextButton::onWidgetDeleted( CInterfaceElement *e ) { } + + void CCtrlTextButton::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + if( _ViewText != NULL ) + _ViewText->updateCoords(); + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 54b180ef1..5b51fcb6b 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2633,9 +2633,7 @@ namespace NLGUI sint32 dx = newX - oldX; sint32 dy = newY - oldY; - draggedElement->setXReal( draggedElement->getXReal() + dx ); - draggedElement->setYReal( draggedElement->getYReal() + dy ); - draggedElement->invalidateCoords(); + draggedElement->moveBy( dx, dy ); } } From 22d9accae616b7bf2c655d148c7454e84a39d9bd Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 20:54:44 +0200 Subject: [PATCH 13/29] When moving a widget, save the reference to the hierarchy lookup map... --HG-- branch : dfighter-tools --- code/studio/src/plugins/gui_editor/widget_hierarchy.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index d52f55e27..5605d6439 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -279,13 +279,15 @@ namespace GUIEditor // Remove reference to old item widgetHierarchyMap.erase( oldid ); - + // Add new item item = new QTreeWidgetItem(); item->setData( 0, Qt::DisplayRole, id ); item->setSelected( true ); newParent->addChild( item ); - + + // Add reference to new item + widgetHierarchyMap[ newid ] = item; selectItem( item ); } From 2603ad3a2ba040e2ee2ffbc1fe1606553c10b95b Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 27 Sep 2014 21:48:51 +0200 Subject: [PATCH 14/29] Refactoring. Added CInterfaceFactory. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_factory.h | 35 ++++++++++++++++++++ code/nel/src/gui/ctrl_text_button.cpp | 3 +- code/nel/src/gui/group_editbox.cpp | 3 +- code/nel/src/gui/interface_factory.cpp | 29 ++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 code/nel/include/nel/gui/interface_factory.h create mode 100644 code/nel/src/gui/interface_factory.cpp diff --git a/code/nel/include/nel/gui/interface_factory.h b/code/nel/include/nel/gui/interface_factory.h new file mode 100644 index 000000000..bd7f8352a --- /dev/null +++ b/code/nel/include/nel/gui/interface_factory.h @@ -0,0 +1,35 @@ +// Ryzom - MMORPG Framework +// 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 . + +#ifndef IFACE_FACTORY +#define IFACE_FACTORY + +#include + +namespace NLGUI +{ + class CViewBase; + + /// Simple interface element ( widget ) factory + class CInterfaceFactory + { + public: + static CViewBase* createClass( const std::string &name ); + }; +} + + +#endif diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index 03db2b797..a3a10d93e 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -23,6 +23,7 @@ #include "nel/gui/group_container_base.h" #include "nel/gui/lua_ihm.h" #include "nel/gui/widget_manager.h" +#include "nel/gui/interface_factory.h" #include "nel/misc/i18n.h" using namespace std; @@ -904,7 +905,7 @@ namespace NLGUI if( _ViewText == NULL ) { - CViewBase *v = CWidgetManager::getInstance()->getParser()->createClass( "text" ); + CViewBase *v = CInterfaceFactory::createClass( "text" ); nlassert( v != NULL ); _ViewText = dynamic_cast< CViewText* >( v ); _ViewText->setId( _Id + "_text" ); diff --git a/code/nel/src/gui/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp index c18c69134..ba65a07c4 100644 --- a/code/nel/src/gui/group_editbox.cpp +++ b/code/nel/src/gui/group_editbox.cpp @@ -27,6 +27,7 @@ #include "nel/gui/widget_manager.h" #include "nel/gui/view_renderer.h" #include "nel/gui/db_manager.h" +#include "nel/gui/interface_factory.h" #include using namespace std; @@ -1543,7 +1544,7 @@ namespace NLGUI if( editorMode ) { nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() ); - _ViewText = dynamic_cast< CViewText* >( CWidgetManager::getInstance()->getParser()->createClass( "text" ) ); + _ViewText = dynamic_cast< CViewText* >( CInterfaceFactory::createClass( "text" ) ); if( _ViewText != NULL ) { _ViewText->setParent( this ); diff --git a/code/nel/src/gui/interface_factory.cpp b/code/nel/src/gui/interface_factory.cpp new file mode 100644 index 000000000..ec914baa6 --- /dev/null +++ b/code/nel/src/gui/interface_factory.cpp @@ -0,0 +1,29 @@ +// Ryzom - MMORPG Framework +// 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 . + +#include "nel/gui/interface_factory.h" +#include "nel/gui/view_base.h" +#include "nel/misc/factory.h" + +namespace NLGUI +{ + CViewBase* CInterfaceFactory::createClass( const std::string &name ) + { + return NLMISC_GET_FACTORY( CViewBase, std::string ).createObject( std::string( name ) , CViewBase::TCtorParam() ); + } +} + + From 86007c9156b50455d7140a3c13e49ebc56fa354c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:23:22 +0200 Subject: [PATCH 15/29] Posref changes in the editor should apply... --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_element.cpp | 4 ++-- code/nel/src/gui/widget_manager.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 0225d2797..981d93a9b 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -226,13 +226,13 @@ namespace NLGUI else if( name == "posref" ) { - convertHotSpot( value.c_str() ); + _PosRef = convertHotSpot( value.c_str() ); return; } else if( name == "parentposref" ) { - convertHotSpot( value.c_str() ); + _ParentPosRef = convertHotSpot( value.c_str() ); } else if( name == "sizeref" ) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 5b51fcb6b..92b94b112 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,6 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); + //e->setName( "==MARKED==" ); + draggedElement = NULL; onWidgetMoved( oldid, e->getId() ); From 4571038fa665c8000e00f6ee04f1914139baf18c Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 17:38:24 +0200 Subject: [PATCH 16/29] Update CCtrlTextButton's CViewText's coords after updating it's own coords. --HG-- branch : dfighter-tools --- code/nel/src/gui/ctrl_text_button.cpp | 5 ++++- code/nel/src/gui/widget_manager.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index a3a10d93e..cdf9ea0d2 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -875,7 +875,8 @@ namespace NLGUI // Should have been setuped with addCtrl nlassert(_Setuped); - _ViewText->updateCoords(); + if( _Name == "==MARKED==" ) + bool marked = true; // Compute Size according to bitmap and Text. if (!(_SizeRef & 1)) @@ -890,6 +891,8 @@ namespace NLGUI } CViewBase::updateCoords(); + + _ViewText->updateCoords(); } // *************************************************************************** diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 92b94b112..65c3e101e 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,7 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - //e->setName( "==MARKED==" ); + e->setName( "==MARKED==" ); draggedElement = NULL; From d2587df8c14cb748e7ff1031ce59ef2dd3ba0b46 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 20:29:04 +0200 Subject: [PATCH 17/29] From now on dragged widgets will be re-aligned on drop. They will find the nearest hotspot of the group they are dropped into, and calculate an offset so they will align to the hotspot and yet remain where they were dropped. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 9 ++ code/nel/src/gui/interface_element.cpp | 91 ++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 048ec4b6e..3b095ac85 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -518,6 +518,15 @@ namespace NLGUI _YReal += y; } + /// Retrieves the coordinates of the specified hotspot + void getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const; + + /// Tells which hotspot is the closest to the specified element + void getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ); + + /// Aligns the element to the other element specified + void alignTo( CInterfaceElement *other ); + protected: bool editorSelected; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 981d93a9b..75fee53f2 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1594,6 +1594,97 @@ namespace NLGUI } } + void CInterfaceElement::getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const + { + x = _XReal; + y = _YReal; + + if( ( hs & Hotspot_Mx ) != 0 ) + y += _HReal / 2; + else + if( ( hs & Hotspot_Tx ) != 0 ) + y += _HReal; + + + if( ( hs & Hotspot_xM ) != 0 ) + x += _WReal / 2; + else + if( ( hs & Hotspot_xR ) != 0 ) + x += _WReal; + } + + void CInterfaceElement::getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ) + { + /// Iterate over the following hotspots, calculate the distance and store the closest + + + static THotSpot hslist[] = + { + Hotspot_BL, + Hotspot_BR, + Hotspot_MM, + Hotspot_TL, + Hotspot_TR + }; + + int c = sizeof( hslist ) / sizeof( THotSpot ); + + int x,y,ox,oy,vx,vy; + float d; + float closestd = 9999999.0f; + THotSpot closestHS = Hotspot_TR; + + for( int i = 0; i < c; i++ ) + { + other->getHSCoords( hslist[ i ], ox, oy ); + getHSCoords( hslist[ i ], x, y ); + + // Make a vector between the two hotspots + vx = x - ox; + vy = y - oy; + + // Calculate length + d = sqrt( pow( vx, 2.0f ) + pow( vy, 2.0f ) ); + + // If these hotspots are the closest, store the hotspot + if( d < closestd ) + { + closestd = d; + closestHS = hslist[ i ]; + } + } + + hs = closestHS; + } + + void CInterfaceElement::alignTo( CInterfaceElement *other ) + { + if( other == this ) + return; + + // Check which hotspot is the closest + THotSpot hs; + other->getClosestHotSpot( this, hs ); + + // Get the hotspot coordinates + sint32 x, y, ox, oy; + getHSCoords( hs, x, y ); + other->getHSCoords( hs, ox, oy ); + + // Calculate the difference between the hotspot we found and our current position, + sint32 dx = ox - x; + sint32 dy = oy - y; + + // This difference is our offset, so we remain in the same position + setX( -1 * dx ); + setY( -1 * dy ); + + setPosRef( hs ); + setParentPosRef( hs ); + + invalidateCoords(); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 65c3e101e..ec22798fb 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - e->setName( "==MARKED==" ); + e->alignTo( g ); + //e->setName( "==MARKED==" ); draggedElement = NULL; From 97ddd3573d3ede76420775e282889546389a22ba Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:37:05 +0200 Subject: [PATCH 18/29] Select groups first. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 37 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index ec22798fb..734547512 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2400,21 +2400,34 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - - // Take the top most control. - uint nMaxDepth = 0; - const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); - for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { - CCtrlBase *ctrl= _CtrlsUnderPointer[i]; - if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) { - uint d = ctrl->getDepth( pNewCurrentWnd ); - if (d > nMaxDepth) + _CapturedView = g; + captured = true; + break; + } + } + + if( !captured ) + { + // Take the top most control. + uint nMaxDepth = 0; + const std::vector< CCtrlBase* >& _CtrlsUnderPointer = getCtrlsUnderPointer(); + for (sint32 i = (sint32)_CtrlsUnderPointer.size()-1; i >= 0; i--) + { + CCtrlBase *ctrl= _CtrlsUnderPointer[i]; + if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) ) { - nMaxDepth = d; - setCapturePointerLeft( ctrl ); - captured = true; + uint d = ctrl->getDepth( pNewCurrentWnd ); + if (d > nMaxDepth) + { + nMaxDepth = d; + setCapturePointerLeft( ctrl ); + captured = true; + } } } } From 5d5bf860d4729b1114308efa28d015bcfca2fcfe Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:42:18 +0200 Subject: [PATCH 19/29] Reparent items in widget hierarchy instead of deleting and creating a new item... --HG-- branch : dfighter-tools --- .../src/plugins/gui_editor/widget_hierarchy.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 5605d6439..1439fea9e 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -269,21 +269,16 @@ namespace GUIEditor if( ( newParent == NULL ) || ( item == NULL ) ) return; - // Remove old item + // Remove item from old parent QTreeWidgetItem *p = item->parent(); if( p != NULL ) p->setExpanded( false ); - id = item->data( 0, Qt::DisplayRole ).toString(); - delete item; - item = NULL; + p->removeChild( item ); // Remove reference to old item widgetHierarchyMap.erase( oldid ); - // Add new item - item = new QTreeWidgetItem(); - item->setData( 0, Qt::DisplayRole, id ); - item->setSelected( true ); + // Add item to new parent newParent->addChild( item ); // Add reference to new item From 64571abd478d9956bf2da10760302b03e83674a8 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:52:56 +0200 Subject: [PATCH 20/29] When moving a group draw it's children too. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 2 ++ code/nel/src/gui/interface_group.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index daf6d2d53..62e61373e 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -328,6 +328,8 @@ namespace NLGUI void onWidgetDeleted( CInterfaceElement *e ); + void moveBy( sint32 x, sint32 y ); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 05f210568..ac6b57fb0 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2544,5 +2544,16 @@ namespace NLGUI for( std::vector< CInterfaceGroup* >::iterator itr = _ChildrenGroups.begin(); itr != _ChildrenGroups.end(); ++itr ) (*itr)->onWidgetDeleted( e ); } + + void CInterfaceGroup::moveBy( sint32 x, sint32 y ) + { + CInterfaceElement::moveBy( x, y ); + + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->updateCoords(); + } + } } From ad9e9839fbc7b544e65b26777a7cc581e2402838 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 17:59:39 +0200 Subject: [PATCH 21/29] Don't try to handle the right mouse button actions in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 734547512..950306750 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2302,6 +2302,14 @@ namespace NLGUI eventDesc.setX( _Pointer->getX() ); eventDesc.setY( _Pointer->getY() ); + if( CInterfaceElement::getEditorMode() ) + { + // Let's pretend we've handled the event... or actually we have! + if( ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightdown ) || + ( eventDesc.getEventTypeExtended() == CEventDescriptorMouse::mouserightup ) ) + return true; + } + if( isMouseHandlingEnabled() ) { // First thing to do : Capture handling From 08b6675b3db7f2fe2030259bd74c261db5f1b295 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:00:54 +0200 Subject: [PATCH 22/29] Only select a group first in editor mode. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 950306750..f0fbe1b1a 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,14 +2408,17 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) + if( CInterfaceElement::getEditorMode() ) { - CInterfaceGroup *g = _GroupsUnderPointer[ i ]; - if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { - _CapturedView = g; - captured = true; - break; + CInterfaceGroup *g = _GroupsUnderPointer[ i ]; + if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) ) + { + _CapturedView = g; + captured = true; + break; + } } } From d7d62e690c0700195bde583f6206e2b920179f54 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 18:45:17 +0200 Subject: [PATCH 23/29] Make group selection optional. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/widget_manager.h | 3 +++ code/nel/src/gui/widget_manager.cpp | 3 ++- .../plugins/gui_editor/editor_message_processor.cpp | 5 +++++ .../src/plugins/gui_editor/editor_message_processor.h | 1 + .../src/plugins/gui_editor/gui_editor_window.cpp | 10 ++++++++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 89023c445..8790fc272 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -516,6 +516,8 @@ namespace NLGUI void unregisterWidgetWatcher( IWidgetWatcher *watcher ); CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); + + void setGroupSelection( bool b ){ groupSelection = b; } private: CWidgetManager(); @@ -610,6 +612,7 @@ namespace NLGUI std::string currentEditorSelection; + bool groupSelection; }; } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index f0fbe1b1a..c6068b363 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() ) + if( CInterfaceElement::getEditorMode() && groupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3516,6 +3516,7 @@ namespace NLGUI setScreenWH( 0, 0 ); currentEditorSelection = ""; + groupSelection = false; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 691dbdead..e834aa21f 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -130,5 +130,10 @@ namespace GUIEditor e->setActive( false ); e->setActive( true ); } + + void CEditorMessageProcessor::onSetGroupSelection( bool b ) + { + CWidgetManager::getInstance()->setGroupSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5c19a03c2..5d4098272 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -38,6 +38,7 @@ namespace GUIEditor public Q_SLOTS: void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); + void onSetGroupSelection( bool b ); private: CWidgetInfoTree *tree; 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 9f6568936..3a4f982aa 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,16 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + + // ---------------------------------------------------------------------------------- + m->addSeparator(); + + a = new QAction( "Select groups", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } From 3ffe56b862850eafe088f5abee6df32486943cd3 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 20:36:16 +0200 Subject: [PATCH 24/29] Added support for ungrouping. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 3 ++ code/nel/include/nel/gui/widget_manager.h | 1 + code/nel/src/gui/interface_group.cpp | 40 +++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 34 ++++++++++++++++ .../gui_editor/editor_message_processor.cpp | 12 ++++++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 95 insertions(+) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index 62e61373e..cdfd182e7 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -330,6 +330,9 @@ namespace NLGUI void moveBy( sint32 x, sint32 y ); + // Blows up the group, moves it's children to it's parent + bool explode(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 8790fc272..917a0e9ba 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -518,6 +518,7 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); void setGroupSelection( bool b ){ groupSelection = b; } + bool unGroupSelection(); private: CWidgetManager(); diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index ac6b57fb0..35b493ecb 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2555,5 +2555,45 @@ namespace NLGUI v->updateCoords(); } } + + bool CInterfaceGroup::explode() + { + CInterfaceGroup *p = getParent(); + if( p == NULL ) + return false; + + std::string oldId; + + // Reparent children + for( sint32 i = 0; i < _EltOrder.size(); i++ ) + { + CInterfaceElement *e = _EltOrder[ i ]; + + oldId = e->getId(); + + e->setParent( p ); + + if( e->getParentPos() == this ) + e->setParentPos( p ); + + if( e->getParentSize() == this ) + e->setParentSize( p ); + + if( e->getParentPos() == p ) + e->alignTo( p ); + + p->addElement( e ); + e->setIdRecurse( e->getShortId() ); + + CWidgetManager::getInstance()->onWidgetMoved( oldId, e->getId() ); + } + + _EltOrder.clear(); + _Views.clear(); + _Controls.clear(); + _ChildrenGroups.clear(); + + return true; + } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c6068b363..21c9bd53d 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -3477,6 +3477,40 @@ namespace NLGUI return v; } + bool CWidgetManager::unGroupSelection() + { + if( currentEditorSelection.empty() ) + return false; + + // Does the element exist? + CInterfaceElement *e = getElementFromId( currentEditorSelection ); + if( e == NULL ) + return false; + + // Is the element a group? + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( e ); + if( g == NULL ) + return false; + + // Can't blow up a root group :( + CInterfaceGroup *p = g->getParent(); + if( p == NULL ) + return false; + + // KABOOM! + bool ok = g->explode(); + if( !ok ) + return false; + + p->delElement( g ); + + setCurrentEditorSelection( "" ); + + p->updateCoords(); + + return true; + } + CWidgetManager::CWidgetManager() { diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index e834aa21f..4c48a4fa4 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -135,5 +135,17 @@ namespace GUIEditor { CWidgetManager::getInstance()->setGroupSelection( b ); } + + void CEditorMessageProcessor::onUngroup() + { + bool ok = CWidgetManager::getInstance()->unGroupSelection(); + + if( !ok ) + { + QMessageBox::critical( NULL, + tr( "Ungrouping widgets" ), + tr( "Couldn't ungroup widgets." ) ); + } + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 5d4098272..9e6d3cf89 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onUngroup(); private: CWidgetInfoTree *tree; 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 3a4f982aa..01433bf9e 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Ungroup", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); + m->addAction( a ); + // ---------------------------------------------------------------------------------- m->addSeparator(); From bec078af25601d743ae3f35b5da8931c42fe73ea Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:00:56 +0200 Subject: [PATCH 25/29] Sizes should remain the same when ungrouping. --HG-- branch : dfighter-tools --- code/nel/src/gui/interface_group.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 35b493ecb..516a2f6aa 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2571,16 +2571,15 @@ namespace NLGUI oldId = e->getId(); + e->setW( e->getWReal() ); + e->setH( e->getHReal() ); + e->setSizeRef( "" ); + e->setParent( p ); - if( e->getParentPos() == this ) - e->setParentPos( p ); - - if( e->getParentSize() == this ) - e->setParentSize( p ); - - if( e->getParentPos() == p ) - e->alignTo( p ); + e->setParentPos( p ); + e->setParentSize( p ); + e->alignTo( p ); p->addElement( e ); e->setIdRecurse( e->getShortId() ); From a1e2c5667a03436f9dcb6ecaa7bfc46db7059626 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Wed, 8 Oct 2014 21:28:20 +0200 Subject: [PATCH 26/29] A little crash fix. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_element.h | 2 +- code/nel/src/gui/interface_element.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 3b095ac85..0be4c02e3 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -508,7 +508,7 @@ namespace NLGUI /// Called when the widget is deleted, /// so other widgets in the group can check if it belongs to them - virtual void onWidgetDeleted( CInterfaceElement *e ){} + virtual void onWidgetDeleted( CInterfaceElement *e ); /// Move the element by x in the X direction and y in the Y direction // Uses real coordinates diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 75fee53f2..c9b480516 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1685,6 +1685,14 @@ namespace NLGUI invalidateCoords(); } + void CInterfaceElement::onWidgetDeleted( CInterfaceElement *e ) + { + if( e == getParentPos() ) + setParentPos( NULL ); + if( e == getParentSize() ) + setParentSize( NULL ); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; From 8cec8de3a068f856d6c97bd16b0bf3063e7a70ef Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 17:33:57 +0200 Subject: [PATCH 27/29] Unselect selection when clicking 'nothing'. --HG-- branch : dfighter-tools --- code/nel/src/gui/widget_manager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 21c9bd53d..c26a23231 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2475,6 +2475,11 @@ namespace NLGUI // handle the capture _CapturedView->handleEvent( evnt ); } + else + { + if( CInterfaceElement::getEditorMode() ) + setCurrentEditorSelection( "" ); + } } // Manage RightClick From aac2fd41a16f871c7cfccd84aac8597bf98289f0 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Fri, 10 Oct 2014 20:25:25 +0200 Subject: [PATCH 28/29] Allow multiselection. --HG-- branch : dfighter-tools --- .../nel/gui/editor_selection_watcher.h | 3 +- code/nel/include/nel/gui/widget_manager.h | 16 +++-- code/nel/src/gui/view_base.cpp | 2 +- code/nel/src/gui/widget_manager.cpp | 70 +++++++++++++------ .../gui_editor/editor_message_processor.cpp | 44 +++++++----- .../gui_editor/editor_message_processor.h | 1 + .../gui_editor/editor_selection_watcher.cpp | 4 +- .../gui_editor/editor_selection_watcher.h | 4 +- .../plugins/gui_editor/gui_editor_window.cpp | 14 ++-- .../gui_editor/property_browser_ctrl.cpp | 12 +++- .../gui_editor/property_browser_ctrl.h | 2 +- .../plugins/gui_editor/widget_hierarchy.cpp | 19 +++-- .../src/plugins/gui_editor/widget_hierarchy.h | 2 +- 13 files changed, 132 insertions(+), 61 deletions(-) diff --git a/code/nel/include/nel/gui/editor_selection_watcher.h b/code/nel/include/nel/gui/editor_selection_watcher.h index 415f4f9db..7e262bdf1 100644 --- a/code/nel/include/nel/gui/editor_selection_watcher.h +++ b/code/nel/include/nel/gui/editor_selection_watcher.h @@ -15,6 +15,7 @@ // along with this program. If not, see . #include +#include namespace NLGUI { @@ -24,7 +25,7 @@ namespace NLGUI public: /// Notifies the watcher about the change - virtual void selectionChanged( std::string &newSelection ) = 0; + virtual void selectionChanged() = 0; }; } diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 917a0e9ba..243847ad7 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -503,8 +503,15 @@ namespace NLGUI IParser* getParser() const{ return parser; } - std::string& getCurrentEditorSelection(){ return currentEditorSelection; } - void setCurrentEditorSelection( const std::string &name ); + /// Retrieves the Id of the currently selected widgets + void getEditorSelection( std::vector< std::string > &selection ); + + /// Adds the widget with the specified Id to the selected widgets + void selectWidget( const std::string &name ); + + /// Clears the selection + void clearEditorSelection(); + void notifySelectionWatchers(); void registerSelectionWatcher( IEditorSelectionWatcher *watcher ); void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher ); @@ -519,6 +526,7 @@ namespace NLGUI void setGroupSelection( bool b ){ groupSelection = b; } bool unGroupSelection(); + void setMultiSelection( bool b ){ multiSelection = b; } private: CWidgetManager(); @@ -611,9 +619,9 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* > selectionWatchers; std::vector< IWidgetWatcher* > widgetWatchers; - - std::string currentEditorSelection; + std::vector< std::string > editorSelection; bool groupSelection; + bool multiSelection; }; } diff --git a/code/nel/src/gui/view_base.cpp b/code/nel/src/gui/view_base.cpp index 05d958d3e..2b09061a9 100644 --- a/code/nel/src/gui/view_base.cpp +++ b/code/nel/src/gui/view_base.cpp @@ -57,7 +57,7 @@ namespace NLGUI { if( editorMode ) { - CWidgetManager::getInstance()->setCurrentEditorSelection( getId() ); + CWidgetManager::getInstance()->selectWidget( getId() ); return true; } } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index c26a23231..6ee1588c3 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2077,9 +2077,9 @@ namespace NLGUI if( CInterfaceElement::getEditorMode() ) { - if( !currentEditorSelection.empty() ) + for( int i = 0; i < editorSelection.size(); i++ ) { - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); if( e != NULL ) e->drawHighlight(); } @@ -2478,7 +2478,7 @@ namespace NLGUI else { if( CInterfaceElement::getEditorMode() ) - setCurrentEditorSelection( "" ); + clearEditorSelection(); } } @@ -3349,25 +3349,53 @@ namespace NLGUI } } - - void CWidgetManager::setCurrentEditorSelection( const std::string &name ) + void CWidgetManager::getEditorSelection( std::vector< std::string > &selection ) { + selection.clear(); + for( int i = 0; i < editorSelection.size(); i++ ) + selection.push_back( editorSelection[ i ] ); + } + + void CWidgetManager::selectWidget( const std::string &name ) + { + std::vector< std::string >::iterator itr + = std::find( editorSelection.begin(), editorSelection.end(), name ); + CInterfaceElement *e = getElementFromId( name ); - if( e != NULL ) + + if( itr != editorSelection.end() ) { - if( !currentEditorSelection.empty() ) + // If multiselection is on unselect if already selected + if( multiSelection ) { - CInterfaceElement *prev = getElementFromId( currentEditorSelection ); - if( prev != NULL ) - prev->setEditorSelected( false ); + editorSelection.erase( itr ); + if( e != NULL ) + e->setEditorSelected( false ); } - e->setEditorSelected( true ); } else - if( !name.empty() ) - return; - - currentEditorSelection = name; + { + // Select if not yet selected + if( e != NULL ) + { + // If multiselection is off, we can only have 1 widget selected + if( !multiSelection ) + { + editorSelection.clear(); + } + + e->setEditorSelected( true ); + editorSelection.push_back( name ); + } + + } + + notifySelectionWatchers(); + } + + void CWidgetManager::clearEditorSelection() + { + editorSelection.clear(); notifySelectionWatchers(); } @@ -3376,7 +3404,7 @@ namespace NLGUI std::vector< IEditorSelectionWatcher* >::iterator itr = selectionWatchers.begin(); while( itr != selectionWatchers.end() ) { - (*itr)->selectionChanged( currentEditorSelection ); + (*itr)->selectionChanged(); ++itr; } } @@ -3484,11 +3512,11 @@ namespace NLGUI bool CWidgetManager::unGroupSelection() { - if( currentEditorSelection.empty() ) + if( editorSelection.size() != 1 ) return false; // Does the element exist? - CInterfaceElement *e = getElementFromId( currentEditorSelection ); + CInterfaceElement *e = getElementFromId( editorSelection[ 0 ] ); if( e == NULL ) return false; @@ -3509,7 +3537,7 @@ namespace NLGUI p->delElement( g ); - setCurrentEditorSelection( "" ); + clearEditorSelection(); p->updateCoords(); @@ -3554,8 +3582,8 @@ namespace NLGUI setScreenWH( 0, 0 ); - currentEditorSelection = ""; groupSelection = false; + multiSelection = false; } CWidgetManager::~CWidgetManager() @@ -3569,6 +3597,8 @@ namespace NLGUI curContextHelp = NULL; CStringShared::deleteStringMapper(); + + editorSelection.clear(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index 4c48a4fa4..a818cf174 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -25,35 +25,40 @@ namespace GUIEditor { void CEditorMessageProcessor::onDelete() { - std::string selection = CWidgetManager::getInstance()->getCurrentEditorSelection(); + std::vector< std::string > selection; + + CWidgetManager::getInstance()->getEditorSelection( selection ); if( selection.empty() ) return; QMessageBox::StandardButton r = QMessageBox::question( NULL, tr( "Deleting widget" ), - tr( "Are you sure you want to delete %1?" ).arg( selection.c_str() ), + tr( "Are you sure you want to delete these?" ), QMessageBox::Yes | QMessageBox::No ); if( r != QMessageBox::Yes ) return; - CInterfaceElement *e = - CWidgetManager::getInstance()->getElementFromId( selection ); - if( e == NULL ) - return; - - CInterfaceElement *p = e->getParent(); - if( p == NULL ) - return; - - CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); - if( g == NULL ) - return; - - if( g->delElement( e ) ) + for( int i = 0; i < selection.size(); i++ ) { - CWidgetManager::getInstance()->setCurrentEditorSelection( "" ); + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ i ] ); + if( e == NULL ) + continue; + + CInterfaceElement *p = e->getParent(); + if( p == NULL ) + continue; + + CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( p ); + if( g == NULL ) + continue; + + g->delElement( e ); + } + + + CWidgetManager::getInstance()->clearEditorSelection(); } void CEditorMessageProcessor::onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ) @@ -147,5 +152,10 @@ namespace GUIEditor tr( "Couldn't ungroup widgets." ) ); } } + + void CEditorMessageProcessor::onSetMultiSelection( bool b ) + { + CWidgetManager::getInstance()->setMultiSelection( b ); + } } diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index 9e6d3cf89..c3483e2ef 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -40,6 +40,7 @@ namespace GUIEditor void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); void onUngroup(); + void onSetMultiSelection( bool b ); private: CWidgetInfoTree *tree; diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp index ee3a079ad..7647c8abb 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.cpp @@ -18,9 +18,9 @@ namespace GUIEditor { - void CEditorSelectionWatcher::selectionChanged( std::string &newSelection ) + void CEditorSelectionWatcher::selectionChanged() { - Q_EMIT sgnSelectionChanged( newSelection ); + Q_EMIT sgnSelectionChanged(); } } diff --git a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h index 61218c0cd..2eab68310 100644 --- a/code/studio/src/plugins/gui_editor/editor_selection_watcher.h +++ b/code/studio/src/plugins/gui_editor/editor_selection_watcher.h @@ -27,10 +27,10 @@ namespace GUIEditor public: CEditorSelectionWatcher() : QObject( NULL ){} - void selectionChanged( std::string &newSelection ); + void selectionChanged(); Q_SIGNALS: - void sgnSelectionChanged( std::string &id ); + void sgnSelectionChanged(); }; } 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 01433bf9e..6cc072ce8 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -283,8 +283,8 @@ namespace GUIEditor CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + disconnect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); projectFiles.clearAll(); projectWindow->clear(); @@ -322,8 +322,8 @@ namespace GUIEditor linkList->onGUILoaded(); CEditorSelectionWatcher *w = GUICtrl->getWatcher(); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) ); - connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), hierarchyView, SLOT( onSelectionChanged() ) ); + connect( w, SIGNAL( sgnSelectionChanged() ), &browserCtrl, SLOT( onSelectionChanged() ) ); } void GUIEditorWindow::onAddWidgetClicked() @@ -413,6 +413,12 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetGroupSelection( bool ) ) ); m->addAction( a ); + a = new QAction( "Multiselect", this ); + a->setCheckable( true ); + a->setChecked( false ); + connect( a, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onSetMultiSelection( bool ) ) ); + m->addAction( a ); + menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp index c005f80e5..84302bcf0 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.cpp @@ -436,7 +436,7 @@ namespace GUIEditor browser->clear(); } - void CPropBrowserCtrl::onSelectionChanged( std::string &id ) + void CPropBrowserCtrl::onSelectionChanged() { if( browser == NULL ) return; @@ -444,14 +444,20 @@ namespace GUIEditor disablePropertyWatchers(); browser->clear(); - CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( id ); + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { enablePropertyWatchers(); return; } - currentElement = id; + currentElement = selection[ 0 ]; std::string n = e->getClassName(); diff --git a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h index abf80d7de..3d72d92ba 100644 --- a/code/studio/src/plugins/gui_editor/property_browser_ctrl.h +++ b/code/studio/src/plugins/gui_editor/property_browser_ctrl.h @@ -59,7 +59,7 @@ namespace GUIEditor void clear(); public Q_SLOTS: - void onSelectionChanged( std::string &id ); + void onSelectionChanged(); private Q_SLOTS: void onPropertyChanged( QtProperty *prop, const QVariant &v ); diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp index 1439fea9e..343d8efd8 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.cpp @@ -304,14 +304,15 @@ namespace GUIEditor void WidgetHierarchy::getCurrentGroup( QString &g ) { - std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection(); - if( s.empty() ) + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + if( selection.size() != 1 ) { g = ""; return; } - NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( s ); + NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] ); if( e == NULL ) { g = ""; @@ -342,8 +343,16 @@ namespace GUIEditor currentSelection.clear(); } - void WidgetHierarchy::onSelectionChanged( std::string &newSelection ) + void WidgetHierarchy::onSelectionChanged() { + std::vector< std::string > selection; + CWidgetManager::getInstance()->getEditorSelection( selection ); + + if( selection.size() != 1 ) + return; + + std::string newSelection = selection[ 0 ]; + if( newSelection == currentSelection ) return; @@ -376,6 +385,6 @@ namespace GUIEditor std::string n = item->text( 0 ).toUtf8().constData(); currentSelection = makeFullName( item, n ); - CWidgetManager::getInstance()->setCurrentEditorSelection( currentSelection ); + CWidgetManager::getInstance()->selectWidget( currentSelection ); } } diff --git a/code/studio/src/plugins/gui_editor/widget_hierarchy.h b/code/studio/src/plugins/gui_editor/widget_hierarchy.h index 27218715d..cdfc9a741 100644 --- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h +++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h @@ -56,7 +56,7 @@ namespace GUIEditor public Q_SLOTS: void onGUILoaded(); - void onSelectionChanged( std::string &newSelection ); + void onSelectionChanged(); private Q_SLOTS: void onItemDblClicked( QTreeWidgetItem *item ); From 7b45a05562ac762d5022104d5741fc59ae8f434d Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Sat, 11 Oct 2014 00:42:43 +0200 Subject: [PATCH 29/29] Added support for grouping widgets. --HG-- branch : dfighter-tools --- code/nel/include/nel/gui/interface_group.h | 6 ++ code/nel/include/nel/gui/widget_manager.h | 6 +- code/nel/src/gui/interface_group.cpp | 46 ++++++++++++++ code/nel/src/gui/widget_manager.cpp | 63 ++++++++++++++++++- .../gui_editor/editor_message_processor.cpp | 5 ++ .../gui_editor/editor_message_processor.h | 1 + .../plugins/gui_editor/gui_editor_window.cpp | 4 ++ 7 files changed, 127 insertions(+), 4 deletions(-) diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index cdfd182e7..b9efd3357 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -333,6 +333,12 @@ namespace NLGUI // Blows up the group, moves it's children to it's parent bool explode(); + /// Adjusts the group's size so that all elements are fully inside the borders + void spanElements(); + + /// Aligns the elements - used for forming groups + void alignElements(); + protected: void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH); diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 243847ad7..d722a9165 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -524,7 +524,8 @@ namespace NLGUI CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName ); - void setGroupSelection( bool b ){ groupSelection = b; } + void setGroupSelection( bool b ){ _GroupSelection = b; } + bool groupSelection(); bool unGroupSelection(); void setMultiSelection( bool b ){ multiSelection = b; } @@ -620,8 +621,9 @@ namespace NLGUI std::vector< IWidgetWatcher* > widgetWatchers; std::vector< std::string > editorSelection; - bool groupSelection; + bool _GroupSelection; bool multiSelection; + uint32 _WidgetCount; }; } diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp index 516a2f6aa..29ad75f8c 100644 --- a/code/nel/src/gui/interface_group.cpp +++ b/code/nel/src/gui/interface_group.cpp @@ -2594,5 +2594,51 @@ namespace NLGUI return true; } + + void CInterfaceGroup::spanElements() + { + sint32 minx = std::numeric_limits< sint32 >::max(); + sint32 miny = std::numeric_limits< sint32 >::max(); + sint32 maxx = std::numeric_limits< sint32 >::min(); + sint32 maxy = std::numeric_limits< sint32 >::min(); + + sint32 tlx,tly,brx,bry; + + // Find the min and max coordinates of the elements + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + + v->getHSCoords( Hotspot_TL, tlx, tly ); + v->getHSCoords( Hotspot_BR, brx, bry ); + + if( tlx < minx ) + minx = tlx; + if( brx > maxx ) + maxx = brx; + if( bry < miny ) + miny = bry; + if( tly > maxy ) + maxy = tly; + } + + // Set the position and the width and height based on these coords + setW( maxx - minx ); + setH( maxy - miny ); + _WReal = getW(); + _HReal = getH(); + _XReal = minx; + _YReal = miny; + } + + void CInterfaceGroup::alignElements() + { + for( int i = 0; i < _EltOrder.size(); i++ ) + { + CViewBase *v = _EltOrder[ i ]; + v->alignTo( this ); + } + } + } diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 6ee1588c3..e2689f5a0 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2408,7 +2408,7 @@ namespace NLGUI // This may happen when alt-tab has been used => the sheet is dragged but the left button is up if (!CCtrlDraggable::getDraggedSheet()) { - if( CInterfaceElement::getEditorMode() && groupSelection ) + if( CInterfaceElement::getEditorMode() && _GroupSelection ) { for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- ) { @@ -3510,6 +3510,64 @@ namespace NLGUI return v; } + bool CWidgetManager::groupSelection() + { + std::vector< CInterfaceElement* > elms; + + // Resolve the widget names + for( int i = 0; i < editorSelection.size(); i++ ) + { + CInterfaceElement *e = getElementFromId( editorSelection[ i ] ); + if( e != NULL ) + elms.push_back( e ); + } + + editorSelection.clear(); + + if( elms.empty() ) + return false; + + // Create the group as the subgroup of the top window + CInterfaceGroup *g = static_cast< CInterfaceGroup* >( getParser()->createClass( "interface_group" ) ); + getTopWindow()->addGroup( g ); + g->setParent( getTopWindow() ); + g->setIdRecurse( std::string( "group" ) + NLMISC::toString( _WidgetCount ) ); + _WidgetCount++; + onWidgetAdded( g->getId() ); + + std::string oldId; + + // Reparent the widgets to the new group + for( int i = 0; i < elms.size(); i++ ) + { + CInterfaceElement *e = elms[ i ]; + oldId = e->getId(); + CInterfaceGroup *p = e->getParent(); + if( p != NULL ) + p->takeElement( e ); + + g->addElement( e ); + e->setParent( g ); + e->setParentPos( g ); + e->setParentSize( g ); + e->setIdRecurse( e->getShortId() ); + + onWidgetMoved( oldId, e->getId() ); + } + elms.clear(); + + // Make sure widgets aren't clipped because the group isn't big enough + g->spanElements(); + // Make sure widgets are aligned + g->alignElements(); + // Align the new group to the top window + g->alignTo( getTopWindow() ); + + g->setActive( true ); + + return true; + } + bool CWidgetManager::unGroupSelection() { if( editorSelection.size() != 1 ) @@ -3582,8 +3640,9 @@ namespace NLGUI setScreenWH( 0, 0 ); - groupSelection = false; + _GroupSelection = false; multiSelection = false; + _WidgetCount = 0; } CWidgetManager::~CWidgetManager() diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp index a818cf174..ef99c87fc 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.cpp +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.cpp @@ -141,6 +141,11 @@ namespace GUIEditor CWidgetManager::getInstance()->setGroupSelection( b ); } + void CEditorMessageProcessor::onGroup() + { + CWidgetManager::getInstance()->groupSelection(); + } + void CEditorMessageProcessor::onUngroup() { bool ok = CWidgetManager::getInstance()->unGroupSelection(); diff --git a/code/studio/src/plugins/gui_editor/editor_message_processor.h b/code/studio/src/plugins/gui_editor/editor_message_processor.h index c3483e2ef..ee55fcda7 100644 --- a/code/studio/src/plugins/gui_editor/editor_message_processor.h +++ b/code/studio/src/plugins/gui_editor/editor_message_processor.h @@ -39,6 +39,7 @@ namespace GUIEditor void onDelete(); void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name ); void onSetGroupSelection( bool b ); + void onGroup(); void onUngroup(); void onSetMultiSelection( bool b ); 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 6cc072ce8..ca5e240e7 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -399,6 +399,10 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); + a = new QAction( "Group", this ); + connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onGroup() ) ); + m->addAction( a ); + a = new QAction( "Ungroup", this ); connect( a, SIGNAL( triggered() ), messageProcessor, SLOT( onUngroup() ) ); m->addAction( a );