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/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/interface_element.h b/code/nel/include/nel/gui/interface_element.h
index db7a499c8..0be4c02e3 100644
--- a/code/nel/include/nel/gui/interface_element.h
+++ b/code/nel/include/nel/gui/interface_element.h
@@ -508,7 +508,24 @@ 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
+ virtual void moveBy( sint32 x, sint32 y )
+ {
+ _XReal += x;
+ _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:
diff --git a/code/nel/include/nel/gui/widget_addition_watcher.h b/code/nel/include/nel/gui/interface_factory.h
similarity index 81%
rename from code/nel/include/nel/gui/widget_addition_watcher.h
rename to code/nel/include/nel/gui/interface_factory.h
index a2717e398..bd7f8352a 100644
--- a/code/nel/include/nel/gui/widget_addition_watcher.h
+++ b/code/nel/include/nel/gui/interface_factory.h
@@ -14,19 +14,22 @@
// 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
+#ifndef IFACE_FACTORY
+#define IFACE_FACTORY
#include
namespace NLGUI
{
- class IWidgetAdditionWatcher
+ class CViewBase;
+
+ /// Simple interface element ( widget ) factory
+ class CInterfaceFactory
{
public:
- virtual void widgetAdded( const std::string &name ) = 0;
+ static CViewBase* createClass( const std::string &name );
};
}
-#endif
+#endif
diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h
index ff0efac3b..b9efd3357 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);
@@ -327,6 +328,17 @@ namespace NLGUI
void onWidgetDeleted( CInterfaceElement *e );
+ void moveBy( sint32 x, sint32 y );
+
+ // 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/view_text.h b/code/nel/include/nel/gui/view_text.h
index a14713dcc..d4377f38e 100644
--- a/code/nel/include/nel/gui/view_text.h
+++ b/code/nel/include/nel/gui/view_text.h
@@ -204,7 +204,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;
@@ -382,6 +386,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/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h
index 5d2468e7a..d722a9165 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
{
@@ -493,17 +503,31 @@ 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 );
-
- 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 );
+
+ void setGroupSelection( bool b ){ _GroupSelection = b; }
+ bool groupSelection();
+ bool unGroupSelection();
+ void setMultiSelection( bool b ){ multiSelection = b; }
private:
CWidgetManager();
@@ -532,7 +556,7 @@ namespace NLGUI
NLMISC::CRefPtr< CViewBase > _CapturedView;
- NLMISC::CRefPtr< CInterfaceElement > draggedElement;
+ NLMISC::CRefPtr< CInterfaceElement > draggedElement; // the element that we're currently dragging
bool startDragging();
void stopDragging();
@@ -594,10 +618,12 @@ 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;
+ std::vector< std::string > editorSelection;
+ bool _GroupSelection;
+ bool multiSelection;
+ uint32 _WidgetCount;
};
}
diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp
index d3a0f6765..cdf9ea0d2 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;
@@ -66,8 +67,6 @@ namespace NLGUI
{
if( _ViewText != NULL )
{
- if( _Parent != NULL )
- _Parent->delView( _ViewText, true );
delete _ViewText;
_ViewText = NULL;
}
@@ -569,6 +568,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 +863,8 @@ namespace NLGUI
}
if(getFrozen() && getFrozenHalfTone())
_ViewText->setAlpha(_ViewText->getAlpha()>>2);
+
+ _ViewText->draw();
}
}
@@ -873,6 +875,9 @@ namespace NLGUI
// Should have been setuped with addCtrl
nlassert(_Setuped);
+ if( _Name == "==MARKED==" )
+ bool marked = true;
+
// Compute Size according to bitmap and Text.
if (!(_SizeRef & 1))
{
@@ -886,6 +891,8 @@ namespace NLGUI
}
CViewBase::updateCoords();
+
+ _ViewText->updateCoords();
}
// ***************************************************************************
@@ -901,7 +908,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" );
@@ -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,18 @@ 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;
+ }
+
+ void CCtrlTextButton::moveBy( sint32 x, sint32 y )
+ {
+ CInterfaceElement::moveBy( x, y );
+
+ if( _ViewText != NULL )
+ _ViewText->updateCoords();
}
}
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_element.cpp b/code/nel/src/gui/interface_element.cpp
index 0225d2797..c9b480516 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" )
@@ -1594,6 +1594,105 @@ 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();
+ }
+
+ void CInterfaceElement::onWidgetDeleted( CInterfaceElement *e )
+ {
+ if( e == getParentPos() )
+ setParentPos( NULL );
+ if( e == getParentSize() )
+ setParentSize( NULL );
+ }
+
CStringMapper* CStringShared::_UIStringMapper = NULL;
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() );
+ }
+}
+
+
diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp
index 4d37eda1c..29ad75f8c 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();
}
@@ -2514,5 +2544,101 @@ 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();
+ }
+ }
+
+ 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->setW( e->getWReal() );
+ e->setH( e->getHReal() );
+ e->setSizeRef( "" );
+
+ e->setParent( p );
+
+ e->setParentPos( p );
+ e->setParentSize( 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;
+ }
+
+ 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/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/view_text.cpp b/code/nel/src/gui/view_text.cpp
index 0186938f7..743ba4ce7 100644
--- a/code/nel/src/gui/view_text.cpp
+++ b/code/nel/src/gui/view_text.cpp
@@ -1847,9 +1847,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() ))
{
diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp
index 9b9a74e77..c68a2c963 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
@@ -1036,7 +1035,7 @@ namespace NLGUI
setCapturePointerLeft(NULL);
setCapturePointerRight(NULL);
_CapturedView = NULL;
-
+
resetColorProps();
resetAlphaRolloverSpeedProps();
resetGlobalAlphasProps();
@@ -2079,9 +2078,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();
}
@@ -2304,6 +2303,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
@@ -2402,20 +2409,37 @@ 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() && _GroupSelection )
{
- CCtrlBase *ctrl= _CtrlsUnderPointer[i];
- if (ctrl && ctrl->isCapturable() && ctrl->isInGroup( pNewCurrentWnd ) )
+ for( sint32 i = _GroupsUnderPointer.size() - 1; i >= 0; i-- )
{
- uint d = ctrl->getDepth( pNewCurrentWnd );
- if (d > nMaxDepth)
+ CInterfaceGroup *g = _GroupsUnderPointer[ i ];
+ if( ( g != NULL ) && ( g->isInGroup( pNewCurrentWnd ) ) )
{
- nMaxDepth = d;
- setCapturePointerLeft( ctrl );
+ _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 ) )
+ {
+ uint d = ctrl->getDepth( pNewCurrentWnd );
+ if (d > nMaxDepth)
+ {
+ nMaxDepth = d;
+ setCapturePointerLeft( ctrl );
+ captured = true;
+ }
}
}
}
@@ -2452,6 +2476,11 @@ namespace NLGUI
// handle the capture
_CapturedView->handleEvent( evnt );
}
+ else
+ {
+ if( CInterfaceElement::getEditorMode() )
+ clearEditorSelection();
+ }
}
// Manage RightClick
@@ -2631,9 +2660,10 @@ namespace NLGUI
else
if( draggedElement != NULL )
{
- draggedElement->setXReal( newX );
- draggedElement->setYReal( newY );
- draggedElement->invalidateCoords();
+ sint32 dx = newX - oldX;
+ sint32 dy = newY - oldY;
+
+ draggedElement->moveBy( dx, dy );
}
}
@@ -2660,13 +2690,36 @@ namespace NLGUI
e->setParent( NULL );
draggedElement = e;
-
+
return true;
}
void CWidgetManager::stopDragging()
{
- draggedElement = NULL;
+ if( draggedElement != NULL )
+ {
+ CInterfaceGroup *g = getGroupUnder( draggedElement->getXReal(), draggedElement->getYReal() );
+ CInterfaceElement *e = draggedElement;
+ CInterfaceGroup *tw = getTopWindow();
+
+ if( g == NULL )
+ g = tw;
+
+ std::string oldid = e->getId();
+
+ e->setParent( g );
+ e->setIdRecurse( e->getShortId() );
+ e->setParentPos( g );
+ e->setParentSize( g );
+ g->addElement( e );
+
+ e->alignTo( g );
+ //e->setName( "==MARKED==" );
+
+ draggedElement = NULL;
+
+ onWidgetMoved( oldid, e->getId() );
+ }
}
// ------------------------------------------------------------------------------------------------
@@ -3297,25 +3350,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();
}
@@ -3324,7 +3405,7 @@ namespace NLGUI
std::vector< IEditorSelectionWatcher* >::iterator itr = selectionWatchers.begin();
while( itr != selectionWatchers.end() )
{
- (*itr)->selectionChanged( currentEditorSelection );
+ (*itr)->selectionChanged();
++itr;
}
}
@@ -3353,36 +3434,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 )
@@ -3415,11 +3506,103 @@ namespace NLGUI
else
g->addView( v );
- notifyAdditionWatchers( v->getId() );
+ onWidgetAdded( v->getId() );
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 )
+ return false;
+
+ // Does the element exist?
+ CInterfaceElement *e = getElementFromId( editorSelection[ 0 ] );
+ 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 );
+
+ clearEditorSelection();
+
+ p->updateCoords();
+
+ return true;
+ }
+
CWidgetManager::CWidgetManager()
{
@@ -3458,7 +3641,9 @@ namespace NLGUI
setScreenWH( 0, 0 );
- currentEditorSelection = "";
+ _GroupSelection = false;
+ multiSelection = false;
+ _WidgetCount = 0;
}
CWidgetManager::~CWidgetManager()
@@ -3472,6 +3657,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 691dbdead..ef99c87fc 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 )
@@ -130,5 +135,32 @@ namespace GUIEditor
e->setActive( false );
e->setActive( true );
}
+
+ void CEditorMessageProcessor::onSetGroupSelection( bool b )
+ {
+ CWidgetManager::getInstance()->setGroupSelection( b );
+ }
+
+ void CEditorMessageProcessor::onGroup()
+ {
+ CWidgetManager::getInstance()->groupSelection();
+ }
+
+ void CEditorMessageProcessor::onUngroup()
+ {
+ bool ok = CWidgetManager::getInstance()->unGroupSelection();
+
+ if( !ok )
+ {
+ QMessageBox::critical( NULL,
+ tr( "Ungrouping widgets" ),
+ 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 5c19a03c2..ee55fcda7 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,10 @@ namespace GUIEditor
public Q_SLOTS:
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 );
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 9f6568936..ca5e240e7 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()
@@ -399,6 +399,30 @@ 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 );
+
+
+ // ----------------------------------------------------------------------------------
+ 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 );
+
+ 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 bd73fb7fa..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();
@@ -493,6 +499,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
@@ -514,13 +524,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() )
@@ -531,10 +540,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() )
@@ -545,10 +550,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;
@@ -558,10 +559,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;
@@ -608,10 +605,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;
@@ -621,16 +614,18 @@ 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;
e->setProperty( propName.toUtf8().constData(), v );
}
+
+
+ CInterfaceGroup *g = e->getParent();
+ if( g != NULL )
+ g->updateCoords();
+
}
@@ -643,6 +638,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 +653,10 @@ namespace GUIEditor
return;
e->setProperty( propName.toUtf8().constData(), v.toUtf8().constData() );
+
+ CInterfaceGroup *g = e->getParent();
+ if( g != NULL )
+ g->updateCoords();
}
void CPropBrowserCtrl::enablePropertyWatchers()
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 24208f4a3..343d8efd8 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 )
@@ -177,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
@@ -231,16 +257,62 @@ namespace GUIEditor
widgetHierarchyMap[ id ] = item;
}
+ 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 item from old parent
+ QTreeWidgetItem *p = item->parent();
+ if( p != NULL )
+ p->setExpanded( false );
+ p->removeChild( item );
+
+ // Remove reference to old item
+ widgetHierarchyMap.erase( oldid );
+
+ // Add item to new parent
+ newParent->addChild( item );
+
+ // Add reference to new item
+ widgetHierarchyMap[ newid ] = item;
+
+ 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 )
{
- 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 = "";
@@ -271,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;
@@ -288,18 +368,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;
}
@@ -307,9 +380,11 @@ namespace GUIEditor
{
if( item->parent() == NULL )
return;
+
+ selectItem( item );
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 4641c8ce8..cdfc9a741 100644
--- a/code/studio/src/plugins/gui_editor/widget_hierarchy.h
+++ b/code/studio/src/plugins/gui_editor/widget_hierarchy.h
@@ -44,15 +44,19 @@ 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 );
private:
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();
- void onSelectionChanged( std::string &newSelection );
+ void onSelectionChanged();
private Q_SLOTS:
void onItemDblClicked( QTreeWidgetItem *item );