diff --git a/code/nel/include/nel/gui/ctrl_base.h b/code/nel/include/nel/gui/ctrl_base.h
index fe8d5ea60..28eeb2cd0 100644
--- a/code/nel/include/nel/gui/ctrl_base.h
+++ b/code/nel/include/nel/gui/ctrl_base.h
@@ -68,9 +68,7 @@ namespace NLGUI
// special parse
virtual bool parse(xmlNodePtr cur, CInterfaceGroup *parentGroup);
-
- /// Handle all events (implemented by derived classes) (return true to signal event handled)
- virtual bool handleEvent (const NLGUI::CEventDescriptor &event);
+ bool handleEvent (const NLGUI::CEventDescriptor &event);
virtual CCtrlBase *getSubCtrl (sint32 /* x */, sint32 /* y */) { return this; }
diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h
index 2df1dee5d..183b6a65e 100644
--- a/code/nel/include/nel/gui/ctrl_text_button.h
+++ b/code/nel/include/nel/gui/ctrl_text_button.h
@@ -42,6 +42,7 @@ namespace NLGUI
/// Constructor
CCtrlTextButton(const TCtorParam ¶m);
+ ~CCtrlTextButton();
std::string getProperty( const std::string &name ) const;
void setProperty( const std::string &name, const std::string &value );
@@ -123,6 +124,9 @@ namespace NLGUI
REFLECT_LUA_METHOD("getViewText", luaGetViewText)
REFLECT_EXPORT_END
+ void onRemoved();
+ void onWidgetDeleted( CInterfaceElement *e );
+
protected:
enum {NumTexture= 3};
diff --git a/code/nel/include/nel/gui/editor_selection_watcher.h b/code/nel/include/nel/gui/editor_selection_watcher.h
new file mode 100644
index 000000000..415f4f9db
--- /dev/null
+++ b/code/nel/include/nel/gui/editor_selection_watcher.h
@@ -0,0 +1,30 @@
+// 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
+
+namespace NLGUI
+{
+ /// Watches the currently selected GUI widget
+ class IEditorSelectionWatcher
+ {
+ public:
+
+ /// Notifies the watcher about the change
+ virtual void selectionChanged( std::string &newSelection ) = 0;
+ };
+}
+
diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h
index 210c24b2e..764d165ef 100644
--- a/code/nel/include/nel/gui/interface_element.h
+++ b/code/nel/include/nel/gui/interface_element.h
@@ -70,6 +70,14 @@ namespace NLGUI
{
public:
+ /// Watches CInterfaceElement deletions
+ class IDeletionWatcher
+ {
+ public:
+ IDeletionWatcher(){}
+ virtual ~IDeletionWatcher(){}
+ virtual void onDeleted( const std::string &name ){}
+ };
enum EStrech
{
@@ -424,6 +432,8 @@ namespace NLGUI
void drawHotSpot(THotSpot hs, NLMISC::CRGBA col);
+ void drawHighlight();
+
// Returns 'true' if that element can be downcasted to a view
virtual bool isView() const { return false; }
@@ -473,6 +483,7 @@ namespace NLGUI
bool isInGroup( CInterfaceGroup *group );
static void setEditorMode( bool b ){ editorMode = b; }
+ static bool getEditorMode(){ return editorMode; }
void setEditorSelected( bool b ){ editorSelected = b; }
bool isEditorSelected() const{ return editorSelected; }
@@ -483,6 +494,19 @@ namespace NLGUI
void setSerializable( bool b ){ serializable = b; }
bool IsSerializable() const{ return serializable; }
+ /// Called when the widget is removed from it's parent group
+ virtual void onRemoved(){}
+
+ /// Registers a deletion watcher
+ static void registerDeletionWatcher( IDeletionWatcher *watcher );
+
+ /// Unregisters a deletion watcher
+ static void unregisterDeletionWatcher( IDeletionWatcher *watcher );
+
+ /// Called when the widget is deleted,
+ /// so other widgets in the group can check if it belongs to them
+ virtual void onWidgetDeleted( CInterfaceElement *e ){}
+
protected:
bool editorSelected;
@@ -543,6 +567,11 @@ namespace NLGUI
void parseSizeRef(const char *sizeRefStr, sint32 &sizeref, sint32 &sizeDivW, sint32 &sizeDivH);
private:
+ /// Notifies the deletion watchers that this interface element is being deleted
+ void notifyDeletionWatchers();
+
+ static std::vector< IDeletionWatcher* > deletionWatchers;
+
//void snapSize();
bool serializable;
diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h
index 61cdc2c9b..f72bc6f1f 100644
--- a/code/nel/include/nel/gui/interface_group.h
+++ b/code/nel/include/nel/gui/interface_group.h
@@ -322,6 +322,8 @@ namespace NLGUI
// Return the current Depth, with no ZBias applied.
float getDepthForZSort() const { return _DepthForZSort; }
+ void onWidgetDeleted( CInterfaceElement *e );
+
protected:
void makeNewClip (sint32 &oldClipX, sint32 &oldClipY, sint32 &oldClipW, sint32 &oldClipH);
diff --git a/code/nel/include/nel/gui/interface_parser.h b/code/nel/include/nel/gui/interface_parser.h
index eb602b8ca..2bf1df9a8 100644
--- a/code/nel/include/nel/gui/interface_parser.h
+++ b/code/nel/include/nel/gui/interface_parser.h
@@ -382,6 +382,7 @@ namespace NLGUI
bool serializeProcs( xmlNodePtr parentNode ) const;
bool serializePointerSettings( xmlNodePtr parentNode ) const;
bool serializeKeySettings( xmlNodePtr parentNode ) const;
+ CViewBase* createClass( const std::string &name );
};
}
diff --git a/code/nel/include/nel/gui/parser.h b/code/nel/include/nel/gui/parser.h
index dc6d00767..db868f70d 100644
--- a/code/nel/include/nel/gui/parser.h
+++ b/code/nel/include/nel/gui/parser.h
@@ -27,6 +27,7 @@
namespace NLGUI
{
class CInterfaceElement;
+ class CViewBase;
class CInterfaceGroup;
class CInterfaceAnim;
class CCtrlSheetSelection;
@@ -86,6 +87,7 @@ namespace NLGUI
virtual bool serializeProcs( xmlNodePtr parentNode ) const = 0;
virtual bool serializePointerSettings( xmlNodePtr parentNode ) const = 0;
virtual bool serializeKeySettings( xmlNodePtr parentNode ) const = 0;
+ virtual CViewBase* createClass( const std::string &name ) = 0;
};
}
diff --git a/code/nel/include/nel/gui/view_base.h b/code/nel/include/nel/gui/view_base.h
index b7d2aceab..f64803720 100644
--- a/code/nel/include/nel/gui/view_base.h
+++ b/code/nel/include/nel/gui/view_base.h
@@ -25,6 +25,7 @@
namespace NLGUI
{
+ class CEventDescriptor;
class CViewBase : public CInterfaceElement
{
@@ -76,6 +77,9 @@ namespace NLGUI
// special for mouse over : return true and fill the name of the cursor to display
virtual bool getMouseOverShape(std::string &/* texName */, uint8 &/* rot */, NLMISC::CRGBA &/* col */) { return false; }
+
+ /// Handle all events (implemented by derived classes) (return true to signal event handled)
+ virtual bool handleEvent (const NLGUI::CEventDescriptor &evnt);
};
diff --git a/code/nel/include/nel/gui/widget_addition_watcher.h b/code/nel/include/nel/gui/widget_addition_watcher.h
new file mode 100644
index 000000000..f4371ed5b
--- /dev/null
+++ b/code/nel/include/nel/gui/widget_addition_watcher.h
@@ -0,0 +1,32 @@
+// 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 00723faea..5fd75ac8a 100644
--- a/code/nel/include/nel/gui/widget_manager.h
+++ b/code/nel/include/nel/gui/widget_manager.h
@@ -47,6 +47,8 @@ namespace NLGUI
class CInterfaceOptions;
class CInterfaceAnim;
class CProcedure;
+ class IEditorSelectionWatcher;
+ class IWidgetAdditionWatcher;
/**
GUI Widget Manager
@@ -341,6 +343,7 @@ namespace NLGUI
/**
* Capture
*/
+ CViewBase *getCapturedView(){ return _CapturedView; }
CCtrlBase *getCapturePointerLeft() { return _CapturePointerLeft; }
CCtrlBase *getCapturePointerRight() { return _CapturePointerRight; }
CCtrlBase *getCaptureKeyboard() { return _CaptureKeyboard; }
@@ -484,7 +487,17 @@ namespace NLGUI
IParser* getParser() const{ return parser; }
+ std::string& getCurrentEditorSelection(){ return currentEditorSelection; }
void setCurrentEditorSelection( const std::string &name );
+ void notifySelectionWatchers();
+ void registerSelectionWatcher( IEditorSelectionWatcher *watcher );
+ void unregisterSelectionWatcher( IEditorSelectionWatcher *watcher );
+
+ void notifyAdditionWatchers( const std::string &widgetName );
+ void registerAdditionWatcher( IWidgetAdditionWatcher *watcher );
+ void unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher );
+
+ CInterfaceElement* addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName );
private:
CWidgetManager();
@@ -511,6 +524,8 @@ namespace NLGUI
NLMISC::CRefPtr _CapturePointerLeft;
NLMISC::CRefPtr _CapturePointerRight;
+ NLMISC::CRefPtr< CViewBase > _CapturedView;
+
// What is under pointer
std::vector< CViewBase* > _ViewsUnderPointer;
std::vector< CCtrlBase* > _CtrlsUnderPointer;
@@ -567,6 +582,9 @@ namespace NLGUI
std::vector< INewScreenSizeHandler* > newScreenSizeHandlers;
std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers;
+ std::vector< IEditorSelectionWatcher* > selectionWatchers;
+ std::vector< IWidgetAdditionWatcher* > additionWatchers;
+
std::string currentEditorSelection;
};
diff --git a/code/nel/src/gui/ctrl_base.cpp b/code/nel/src/gui/ctrl_base.cpp
index f3dcd3712..4f9b616b8 100644
--- a/code/nel/src/gui/ctrl_base.cpp
+++ b/code/nel/src/gui/ctrl_base.cpp
@@ -39,6 +39,9 @@ namespace NLGUI
// ***************************************************************************
bool CCtrlBase::handleEvent(const NLGUI::CEventDescriptor &event)
{
+ if( CViewBase::handleEvent( event ) )
+ return true;
+
if (event.getType() == NLGUI::CEventDescriptor::system)
{
NLGUI::CEventDescriptorSystem &eds = (NLGUI::CEventDescriptorSystem&)event;
diff --git a/code/nel/src/gui/ctrl_base_button.cpp b/code/nel/src/gui/ctrl_base_button.cpp
index 4a0c53cf4..f7d452ca0 100644
--- a/code/nel/src/gui/ctrl_base_button.cpp
+++ b/code/nel/src/gui/ctrl_base_button.cpp
@@ -669,12 +669,6 @@ namespace NLGUI
if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
return false;
- if( editorMode )
- {
- CWidgetManager::getInstance()->setCurrentEditorSelection( getId() );
- return true;
- }
-
if (_LeftDblClickHandled) // no effect on mouse up after double click has been handled
{
_LeftDblClickHandled = false;
diff --git a/code/nel/src/gui/ctrl_button.cpp b/code/nel/src/gui/ctrl_button.cpp
index 3f30105cc..bc54003da 100644
--- a/code/nel/src/gui/ctrl_button.cpp
+++ b/code/nel/src/gui/ctrl_button.cpp
@@ -356,7 +356,7 @@ namespace NLGUI
- if ( ( _Over && !editorMode ) || editorSelected )
+ if ( ( _Over && !editorMode ) )
{
if( !editorMode && (lastOver == false) && (_AHOnOver != NULL))
diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp
index ad0ba93aa..cdf006a51 100644
--- a/code/nel/src/gui/ctrl_text_button.cpp
+++ b/code/nel/src/gui/ctrl_text_button.cpp
@@ -62,6 +62,17 @@ namespace NLGUI
_ForceTextOver = false;
}
+ CCtrlTextButton::~CCtrlTextButton()
+ {
+ if( _ViewText != NULL )
+ {
+ if( _Parent != NULL )
+ _Parent->delView( _ViewText, true );
+ delete _ViewText;
+ _ViewText = NULL;
+ }
+ }
+
std::string CCtrlTextButton::getProperty( const std::string &name ) const
{
std::string prop;
@@ -113,7 +124,10 @@ namespace NLGUI
else
if( name == "hardtext" )
{
- return _ViewText->getText().toString();
+ if( _ViewText != NULL )
+ return _ViewText->getText().toString();
+ else
+ return std::string( "" );
}
else
if( name == "text_y" )
@@ -128,7 +142,10 @@ namespace NLGUI
else
if( name == "text_underlined" )
{
- return toString( _ViewText->getUnderlined() );
+ if( _ViewText != NULL )
+ return toString( _ViewText->getUnderlined() );
+ else
+ return std::string( "" );
}
else
if( name == "text_posref" )
@@ -220,6 +237,11 @@ namespace NLGUI
_TextureIdNormal[ 0 ].setTexture( std::string( value + "_l.tga" ).c_str() );
_TextureIdNormal[ 1 ].setTexture( std::string( value + "_m.tga" ).c_str() );
_TextureIdNormal[ 2 ].setTexture( std::string( value + "_r.tga" ).c_str() );
+
+ CViewRenderer &rVR = *CViewRenderer::getInstance();
+ rVR.getTextureSizeFromId(_TextureIdNormal[0], _BmpLeftW, _BmpH);
+ rVR.getTextureSizeFromId(_TextureIdNormal[1], _BmpMiddleW, _BmpH);
+ rVR.getTextureSizeFromId(_TextureIdNormal[2], _BmpRightW, _BmpH);
return;
}
else
@@ -269,7 +291,8 @@ namespace NLGUI
else
if( name == "hardtext" )
{
- _ViewText->setText( value );
+ if( _ViewText != NULL )
+ _ViewText->setText( value );
return;
}
else
@@ -292,8 +315,10 @@ namespace NLGUI
if( name == "text_underlined" )
{
bool b;
- if( fromString( value, b ) )
- _ViewText->setUnderlined( b );
+ if( _ViewText != NULL )
+ if( fromString( value, b ) )
+ _ViewText->setUnderlined( b );
+
return;
}
else
@@ -766,8 +791,7 @@ namespace NLGUI
CCtrlBase *capturePointerLeft = CWidgetManager::getInstance()->getCapturePointerLeft();
// *** Draw Over
- if( editorSelected ||
- ( !editorMode && _Over && (_OverWhenPushed || !(_Pushed || capturePointerLeft == this ) ) )
+ if( ( !editorMode && _Over && (_OverWhenPushed || !(_Pushed || capturePointerLeft == this ) ) )
)
{
if( !editorMode && (lastOver == false) && (_AHOnOver != NULL) )
@@ -803,32 +827,35 @@ namespace NLGUI
}
}
// Setup ViewText color
- if ( pTxId==_TextureIdNormal || editorMode )
+ if( _ViewText != NULL )
{
- if(_TextHeaderColor) viewTextColor.A= _TextColorNormal.A;
- else viewTextColor= _TextColorNormal;
- _ViewText->setColor(viewTextColor);
- _ViewText->setShadowColor(_TextShadowColorNormal);
- _ViewText->setModulateGlobalColor(_TextModulateGlobalColorNormal);
+ if ( pTxId==_TextureIdNormal || editorMode )
+ {
+ if(_TextHeaderColor) viewTextColor.A= _TextColorNormal.A;
+ else viewTextColor= _TextColorNormal;
+ _ViewText->setColor(viewTextColor);
+ _ViewText->setShadowColor(_TextShadowColorNormal);
+ _ViewText->setModulateGlobalColor(_TextModulateGlobalColorNormal);
+ }
+ else if ( pTxId==_TextureIdPushed )
+ {
+ if(_TextHeaderColor) viewTextColor.A= _TextColorPushed.A;
+ else viewTextColor= _TextColorPushed;
+ _ViewText->setColor(viewTextColor);
+ _ViewText->setShadowColor(_TextShadowColorPushed);
+ _ViewText->setModulateGlobalColor(_TextModulateGlobalColorPushed);
+ }
+ else if ( pTxId==_TextureIdOver )
+ {
+ if(_TextHeaderColor) viewTextColor.A= _TextColorOver.A;
+ else viewTextColor= _TextColorOver;
+ _ViewText->setColor(viewTextColor);
+ _ViewText->setShadowColor(_TextShadowColorOver);
+ _ViewText->setModulateGlobalColor(_TextModulateGlobalColorOver);
+ }
+ if(getFrozen() && getFrozenHalfTone())
+ _ViewText->setAlpha(_ViewText->getAlpha()>>2);
}
- else if ( pTxId==_TextureIdPushed )
- {
- if(_TextHeaderColor) viewTextColor.A= _TextColorPushed.A;
- else viewTextColor= _TextColorPushed;
- _ViewText->setColor(viewTextColor);
- _ViewText->setShadowColor(_TextShadowColorPushed);
- _ViewText->setModulateGlobalColor(_TextModulateGlobalColorPushed);
- }
- else if ( pTxId==_TextureIdOver )
- {
- if(_TextHeaderColor) viewTextColor.A= _TextColorOver.A;
- else viewTextColor= _TextColorOver;
- _ViewText->setColor(viewTextColor);
- _ViewText->setShadowColor(_TextShadowColorOver);
- _ViewText->setModulateGlobalColor(_TextModulateGlobalColorOver);
- }
- if(getFrozen() && getFrozenHalfTone())
- _ViewText->setAlpha(_ViewText->getAlpha()>>2);
}
@@ -864,6 +891,16 @@ namespace NLGUI
{
_Setuped= true;
+ if( _ViewText == NULL )
+ {
+ CViewBase *v = CWidgetManager::getInstance()->getParser()->createClass( "text" );
+ nlassert( v != NULL );
+ _ViewText = dynamic_cast< CViewText* >( v );
+ _ViewText->setId( _Id + "_text" );
+ _ViewText->setText( ucstring( "text" ) );
+ _ViewText->setSerializable( false );
+ }
+
// setup the viewText and add to parent
_ViewText->setParent (getParent());
_ViewText->setParentPos (this);
@@ -960,6 +997,19 @@ 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/group_editbox.cpp b/code/nel/src/gui/group_editbox.cpp
index 5c2f3bf1d..bfd56dbb4 100644
--- a/code/nel/src/gui/group_editbox.cpp
+++ b/code/nel/src/gui/group_editbox.cpp
@@ -1411,7 +1411,8 @@ namespace NLGUI
// ----------------------------------------------------------------------------
void CGroupEditBox::checkCoords()
{
- setupDisplayText();
+ if( !editorMode )
+ setupDisplayText();
CInterfaceGroup::checkCoords();
}
@@ -1530,7 +1531,29 @@ namespace NLGUI
_ViewText = dynamic_cast(CInterfaceGroup::getView("edit_text"));
if(_ViewText == NULL)
+ {
nlwarning("Interface: CGroupEditBox: text 'edit_text' missing or bad type");
+ if( editorMode )
+ {
+ nlwarning( "Trying to create a new 'edit_text' for %s", getId().c_str() );
+ _ViewText = dynamic_cast< CViewText* >( CWidgetManager::getInstance()->getParser()->createClass( "text" ) );
+ if( _ViewText != NULL )
+ {
+ _ViewText->setParent( this );
+ _ViewText->setIdRecurse( "edit_text" );
+ _ViewText->setHardText( "sometext" );
+ _ViewText->setPosRef( Hotspot_TL );
+ _ViewText->setParentPosRef( Hotspot_TL );
+ addView( _ViewText );
+
+ setH( _ViewText->getFontHeight() );
+ setW( _ViewText->getFontWidth() * _ViewText->getText().size() );
+
+ }
+ else
+ nlwarning( "Failed to create new 'edit_text' for %s", getId().c_str() );
+ }
+ }
// For MultiLine editbox, clip the end space, else weird when edit space at end of line (nothing happens)
if(_ViewText)
diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp
index c7a0c234b..93705074a 100644
--- a/code/nel/src/gui/interface_element.cpp
+++ b/code/nel/src/gui/interface_element.cpp
@@ -34,6 +34,7 @@ using namespace NLMISC;
namespace NLGUI
{
bool CInterfaceElement::editorMode = false;
+ std::vector< CInterfaceElement::IDeletionWatcher* > CInterfaceElement::deletionWatchers;
// ------------------------------------------------------------------------------------------------
CInterfaceElement::~CInterfaceElement()
@@ -46,6 +47,13 @@ namespace NLGUI
}
delete _Links;
}
+
+ if( editorMode )
+ {
+ notifyDeletionWatchers();
+ if( _Parent != NULL )
+ _Parent->onWidgetDeleted( this );
+ }
}
// ------------------------------------------------------------------------------------------------
@@ -1296,6 +1304,11 @@ namespace NLGUI
}
+ void CInterfaceElement::drawHighlight()
+ {
+ CViewRenderer::getInstance()->drawWiredQuad( _XReal, _YReal, _WReal, _HReal );
+ }
+
// ***************************************************************************
void CInterfaceElement::invalidateContent()
{
@@ -1542,6 +1555,36 @@ namespace NLGUI
}
}
+ void CInterfaceElement::registerDeletionWatcher( IDeletionWatcher *watcher )
+ {
+ std::vector< IDeletionWatcher* >::iterator itr
+ = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher );
+ // Already registered
+ if( itr != deletionWatchers.end() )
+ return;
+ deletionWatchers.push_back( watcher );
+ }
+
+ void CInterfaceElement::unregisterDeletionWatcher( IDeletionWatcher *watcher )
+ {
+ std::vector< IDeletionWatcher* >::iterator itr
+ = std::find( deletionWatchers.begin(), deletionWatchers.end(), watcher );
+ // Not registered
+ if( itr == deletionWatchers.end() )
+ return;
+ deletionWatchers.erase( itr );
+ }
+
+ void CInterfaceElement::notifyDeletionWatchers()
+ {
+ std::vector< IDeletionWatcher* >::iterator itr = deletionWatchers.begin();
+ while( itr != deletionWatchers.end() )
+ {
+ (*itr)->onDeleted( _Id );
+ ++itr;
+ }
+ }
+
CStringMapper* CStringShared::_UIStringMapper = NULL;
diff --git a/code/nel/src/gui/interface_group.cpp b/code/nel/src/gui/interface_group.cpp
index b2de26527..5fa83e1c5 100644
--- a/code/nel/src/gui/interface_group.cpp
+++ b/code/nel/src/gui/interface_group.cpp
@@ -143,12 +143,12 @@ namespace NLGUI
// initStart = ryzomGetLocalTime ();
clearGroups();
// nlinfo ("%d seconds for clearGroups '%s'", (uint32)(ryzomGetLocalTime ()-initStart)/1000, _Id.c_str());
- // initStart = ryzomGetLocalTime ();
- clearViews();
- // nlinfo ("%d seconds for clearViews '%s'", (uint32)(ryzomGetLocalTime ()-initStart)/1000, _Id.c_str());
// initStart = ryzomGetLocalTime ();
clearControls();
// nlinfo ("%d seconds for clearControls '%s'", (uint32)(ryzomGetLocalTime ()-initStart)/1000, _Id.c_str());
+ // initStart = ryzomGetLocalTime ();
+ clearViews();
+ // nlinfo ("%d seconds for clearViews '%s'", (uint32)(ryzomGetLocalTime ()-initStart)/1000, _Id.c_str());
CWidgetManager::getInstance()->removeRefOnGroup (this);
#ifdef AJM_DEBUG_TRACK_INTERFACE_GROUPS
@@ -1086,9 +1086,11 @@ namespace NLGUI
{
if (_Views[i] == child)
{
- if (!dontDelete) delete _Views[i];
+ CViewBase *v = _Views[i];
_Views.erase(_Views.begin()+i);
delEltOrder (child);
+ child->onRemoved();
+ if (!dontDelete) delete v;
return true;
}
}
@@ -1102,9 +1104,11 @@ namespace NLGUI
{
if (_Controls[i] == child)
{
- if (!dontDelete) delete _Controls[i];
+ CCtrlBase *c = _Controls[i];
_Controls.erase(_Controls.begin()+i);
delEltOrder (child);
+ child->onRemoved();
+ if (!dontDelete) delete c;
return true;
}
}
@@ -1118,9 +1122,11 @@ namespace NLGUI
{
if (_ChildrenGroups[i] == child)
{
- if (!dontDelete) delete _ChildrenGroups[i];
+ CInterfaceGroup *g = _ChildrenGroups[i];
_ChildrenGroups.erase(_ChildrenGroups.begin()+i);
delEltOrder (child);
+ child->onRemoved();
+ if (!dontDelete) delete g;
return true;
}
}
@@ -2471,4 +2477,16 @@ namespace NLGUI
return "IMPLEMENT ME!";
}
-}
\ No newline at end of file
+ void CInterfaceGroup::onWidgetDeleted( CInterfaceElement *e )
+ {
+ for( std::vector< CViewBase* >::iterator itr = _Views.begin(); itr != _Views.end(); ++itr )
+ (*itr)->onWidgetDeleted( e );
+
+ for( std::vector< CCtrlBase* >::iterator itr = _Controls.begin(); itr != _Controls.end(); ++itr )
+ (*itr)->onWidgetDeleted( e );
+
+ for( std::vector< CInterfaceGroup* >::iterator itr = _ChildrenGroups.begin(); itr != _ChildrenGroups.end(); ++itr )
+ (*itr)->onWidgetDeleted( e );
+ }
+}
+
diff --git a/code/nel/src/gui/interface_parser.cpp b/code/nel/src/gui/interface_parser.cpp
index 2bc1a70dd..3d7a1c849 100644
--- a/code/nel/src/gui/interface_parser.cpp
+++ b/code/nel/src/gui/interface_parser.cpp
@@ -3149,5 +3149,10 @@ namespace NLGUI
return true;
}
+
+ CViewBase* CInterfaceParser::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/view_base.cpp b/code/nel/src/gui/view_base.cpp
index a4c8f6643..05d958d3e 100644
--- a/code/nel/src/gui/view_base.cpp
+++ b/code/nel/src/gui/view_base.cpp
@@ -47,5 +47,23 @@ namespace NLGUI
CInterfaceElement::visit(visitor);
}
+
+ bool CViewBase::handleEvent( const NLGUI::CEventDescriptor &evnt )
+ {
+ if( evnt.getType() == NLGUI::CEventDescriptor::mouse )
+ {
+ const NLGUI::CEventDescriptorMouse &eventDesc = ( const NLGUI::CEventDescriptorMouse& )evnt;
+ if( eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown )
+ {
+ if( editorMode )
+ {
+ CWidgetManager::getInstance()->setCurrentEditorSelection( getId() );
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
}
diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp
index ccfa14c63..16357d373 100644
--- a/code/nel/src/gui/widget_manager.cpp
+++ b/code/nel/src/gui/widget_manager.cpp
@@ -33,6 +33,8 @@
#include "nel/gui/proc.h"
#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
@@ -1033,6 +1035,7 @@ namespace NLGUI
_OldCaptureKeyboard = NULL;
setCapturePointerLeft(NULL);
setCapturePointerRight(NULL);
+ _CapturedView = NULL;
resetColorProps();
resetAlphaRolloverSpeedProps();
@@ -2067,6 +2070,16 @@ namespace NLGUI
getPointer()->draw ();
}
+ if( CInterfaceElement::getEditorMode() )
+ {
+ if( !currentEditorSelection.empty() )
+ {
+ CInterfaceElement *e = getElementFromId( currentEditorSelection );
+ if( e != NULL )
+ e->drawHighlight();
+ }
+ }
+
// flush layers
CViewRenderer::getInstance()->flush();
@@ -2099,6 +2112,12 @@ namespace NLGUI
getCapturePointerRight()->handleEvent( evnt );
setCapturePointerRight( NULL );
}
+
+ if( _CapturedView != NULL )
+ {
+ _CapturedView->handleEvent( evnt );
+ _CapturedView = NULL;
+ }
}
}
@@ -2262,6 +2281,9 @@ namespace NLGUI
getCapturePointerLeft() != getCapturePointerRight() )
handled|= getCapturePointerRight()->handleEvent(evnt);
+ if( _CapturedView != NULL )
+ _CapturedView->handleEvent( evnt );
+
CInterfaceGroup *ptr = getWindowUnder (eventDesc.getX(), eventDesc.getY());
setCurrentWindowUnder( ptr );
@@ -2339,6 +2361,8 @@ namespace NLGUI
}
}
+ bool captured = false;
+
// must not capture a new element if a sheet is currentlty being dragged.
// This may happen when alt-tab has been used => the sheet is dragged but the left button is up
if (!CCtrlDraggable::getDraggedSheet())
@@ -2356,9 +2380,25 @@ namespace NLGUI
{
nMaxDepth = d;
setCapturePointerLeft( ctrl );
+ captured = true;
}
}
}
+
+ if( CInterfaceElement::getEditorMode() && !captured )
+ {
+ for( sint32 i = _ViewsUnderPointer.size()-1; i >= 0; i-- )
+ {
+ CViewBase *v = _ViewsUnderPointer[i];
+ if( ( v != NULL ) && v->isInGroup( pNewCurrentWnd ) )
+ {
+ _CapturedView = v;
+ captured = true;
+ break;
+ }
+ }
+ }
+
notifyElementCaptured( getCapturePointerLeft() );
if (clickedOutModalWindow && !clickedOutModalWindow->OnPostClickOut.empty())
{
@@ -2366,13 +2406,16 @@ namespace NLGUI
}
}
//if found
- if ( getCapturePointerLeft() != NULL)
+ if ( captured )
{
// consider clicking on a control implies handling of the event.
handled= true;
// handle the capture
- getCapturePointerLeft()->handleEvent(evnt);
+ if( getCapturePointerLeft() != NULL )
+ getCapturePointerLeft()->handleEvent(evnt);
+ else
+ _CapturedView->handleEvent( evnt );
}
}
@@ -2601,6 +2644,8 @@ namespace NLGUI
// ***************************************************************************
void CWidgetManager::setCapturePointerLeft(CCtrlBase *c)
{
+ _CapturedView = NULL;
+
// additionally, abort any dragging
if( CCtrlDraggable::getDraggedSheet() != NULL )
CCtrlDraggable::getDraggedSheet()->abortDragging();
@@ -3179,8 +3224,114 @@ namespace NLGUI
prev->setEditorSelected( false );
}
e->setEditorSelected( true );
- currentEditorSelection = name;
}
+ else
+ if( !name.empty() )
+ return;
+
+ currentEditorSelection = name;
+ notifySelectionWatchers();
+ }
+
+ void CWidgetManager::notifySelectionWatchers()
+ {
+ std::vector< IEditorSelectionWatcher* >::iterator itr = selectionWatchers.begin();
+ while( itr != selectionWatchers.end() )
+ {
+ (*itr)->selectionChanged( currentEditorSelection );
+ ++itr;
+ }
+ }
+
+ void CWidgetManager::registerSelectionWatcher( IEditorSelectionWatcher *watcher )
+ {
+ std::vector< IEditorSelectionWatcher* >::iterator itr =
+ std::find( selectionWatchers.begin(), selectionWatchers.end(), watcher );
+
+ // We already have this watcher
+ if( itr != selectionWatchers.end() )
+ return;
+
+ selectionWatchers.push_back( watcher );
+ }
+
+ void CWidgetManager::unregisterSelectionWatcher( IEditorSelectionWatcher *watcher )
+ {
+ std::vector< IEditorSelectionWatcher* >::iterator itr =
+ std::find( selectionWatchers.begin(), selectionWatchers.end(), watcher );
+
+ // We don't have this watcher
+ if( itr == selectionWatchers.end() )
+ return;
+
+ selectionWatchers.erase( itr );
+ }
+
+ void CWidgetManager::notifyAdditionWatchers( const std::string &widgetName )
+ {
+ std::vector< IWidgetAdditionWatcher* >::const_iterator itr = additionWatchers.begin();
+ while( itr != additionWatchers.end() )
+ {
+ (*itr)->widgetAdded( widgetName );
+ ++itr;
+ }
+ }
+
+ void CWidgetManager::registerAdditionWatcher( IWidgetAdditionWatcher *watcher )
+ {
+ std::vector< IWidgetAdditionWatcher* >::const_iterator itr
+ = std::find( additionWatchers.begin(), additionWatchers.end(), watcher );
+ // already exists
+ if( itr != additionWatchers.end() )
+ return;
+
+ additionWatchers.push_back( watcher );
+ }
+
+ void CWidgetManager::unregisterAdditionWatcher( IWidgetAdditionWatcher *watcher )
+ {
+ std::vector< IWidgetAdditionWatcher* >::iterator itr
+ = std::find( additionWatchers.begin(), additionWatchers.end(), watcher );
+ // doesn't exist
+ if( itr == additionWatchers.end() )
+ return;
+
+ additionWatchers.erase( itr );
+ }
+
+ CInterfaceElement* CWidgetManager::addWidgetToGroup( std::string &group, std::string &widgetClass, std::string &widgetName )
+ {
+ // Check if this group exists
+ CInterfaceElement *e = getElementFromId( group );
+ if( e == NULL )
+ return NULL;
+ CInterfaceGroup *g = dynamic_cast< CInterfaceGroup* >( e );
+ if( g == NULL )
+ return NULL;
+
+ // Check if an element already exists with that name
+ if( g->getElement( widgetName ) != NULL )
+ return NULL;
+
+ // Create and add the new widget
+ CViewBase *v = getParser()->createClass( widgetClass );
+ if( v == NULL )
+ return NULL;
+
+ v->setId( std::string( g->getId() + ":" + widgetName ) );
+ v->setParent( g );
+
+ if( v->isGroup() )
+ g->addGroup( dynamic_cast< CInterfaceGroup* >( v ) );
+ else
+ if( v->isCtrl() )
+ g->addCtrl( dynamic_cast< CCtrlBase* >( v ) );
+ else
+ g->addView( v );
+
+ notifyAdditionWatchers( v->getId() );
+
+ return v;
}
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt
index 1e1cbced3..fd1283db8 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/CMakeLists.txt
@@ -28,6 +28,9 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR
nelgui_widget.h
new_property_widget.h
new_widget_widget.h
+ add_widget_widget.h
+ editor_selection_watcher.h
+ editor_message_processor.h
)
SET(OVQT_PLUGIN_GUI_EDITOR_UIS
@@ -42,6 +45,7 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS
project_window.ui
new_property_widget.ui
new_widget_widget.ui
+ add_widget_widget.ui
)
SET(QT_USE_QTGUI TRUE)
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.cpp
new file mode 100644
index 000000000..3f32586b6
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.cpp
@@ -0,0 +1,77 @@
+#include "add_widget_widget.h"
+#include "widget_info_tree.h"
+#include
+#include
+#include
+
+namespace GUIEditor
+{
+
+ AddWidgetWidget::AddWidgetWidget( QWidget *parent ) :
+ QWidget( parent )
+ {
+ setupUi( this );
+ setupConnections();
+ }
+
+ AddWidgetWidget::~AddWidgetWidget()
+ {
+ }
+
+ void AddWidgetWidget::setCurrentGroup( const QString &g )
+ {
+ groupEdit->setText( g );
+ }
+
+ void AddWidgetWidget::setupWidgetInfo( const CWidgetInfoTree *tree )
+ {
+ std::vector< std::string > names;
+ tree->getNames( names, false );
+
+ widgetCB->clear();
+
+ std::sort( names.begin(), names.end() );
+
+ std::vector< std::string >::const_iterator itr = names.begin();
+ while( itr != names.end() )
+ {
+ widgetCB->addItem( QString( itr->c_str() ) );
+ ++itr;
+ }
+
+ }
+
+ void AddWidgetWidget::setupConnections()
+ {
+ connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( close() ) );
+ connect( addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) );
+ }
+
+ void AddWidgetWidget::onAddClicked()
+ {
+ if( groupEdit->text().isEmpty() )
+ {
+ QMessageBox::warning( NULL,
+ tr( "WARNING" ),
+ tr( "You need to be adding the new widget into a group!" ),
+ QMessageBox::Ok );
+
+ return;
+ }
+
+ if( nameEdit->text().isEmpty() )
+ {
+ QMessageBox::warning( NULL,
+ tr( "WARNING" ),
+ tr( "You need to specify a name for your new widget!" ),
+ QMessageBox::Ok );
+
+ return;
+ }
+
+ close();
+
+ Q_EMIT adding( groupEdit->text(), widgetCB->currentText(), nameEdit->text() );
+ }
+}
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.h
new file mode 100644
index 000000000..8f9f6a0be
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.h
@@ -0,0 +1,32 @@
+#ifndef ADD_WIDGET_WIDGET_H
+#define ADD_WIDGET_WIDGET_H
+
+#include "ui_add_widget_widget.h"
+
+namespace GUIEditor
+{
+ class CWidgetInfoTree;
+
+ class AddWidgetWidget : public QWidget, public Ui::AddWidgetWidget
+ {
+ Q_OBJECT
+ public:
+ AddWidgetWidget( QWidget *parent = NULL );
+ ~AddWidgetWidget();
+
+ void setCurrentGroup( const QString &g );
+ void setupWidgetInfo( const CWidgetInfoTree *tree );
+
+ private:
+ void setupConnections();
+
+ private Q_SLOTS:
+ void onAddClicked();
+
+ Q_SIGNALS:
+ void adding( const QString &parentGroup, const QString &widgetType, const QString &name );
+ };
+
+}
+
+#endif
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.ui
new file mode 100644
index 000000000..58a1890f4
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/add_widget_widget.ui
@@ -0,0 +1,79 @@
+
+
+ AddWidgetWidget
+
+
+ Qt::ApplicationModal
+
+
+
+ 0
+ 0
+ 318
+ 132
+
+
+
+ Add new widget
+
+
+ -
+
+
-
+
+
+ Group
+
+
+
+ -
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ Widget
+
+
+
+ -
+
+
+ -
+
+
+ Name
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Add
+
+
+
+ -
+
+
+ Cancel
+
+
+
+
+
+
+
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.cpp
new file mode 100644
index 000000000..691dbdead
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.cpp
@@ -0,0 +1,134 @@
+// Object Viewer Qt GUI Editor plugin
+// 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
+#include "editor_message_processor.h"
+
+#include "nel/gui/interface_group.h"
+#include "nel/gui/widget_manager.h"
+#include "widget_info_tree.h"
+
+namespace GUIEditor
+{
+ void CEditorMessageProcessor::onDelete()
+ {
+ std::string selection = CWidgetManager::getInstance()->getCurrentEditorSelection();
+ 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() ),
+ 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 ) )
+ {
+ CWidgetManager::getInstance()->setCurrentEditorSelection( "" );
+ }
+ }
+
+ void CEditorMessageProcessor::onAdd( const QString &parentGroup, const QString &widgetType, const QString &name )
+ {
+ CWidgetInfoTreeNode *node = tree->findNodeByName( std::string( widgetType.toUtf8() ) );
+ // No such widget
+ if( node == NULL )
+ {
+ QMessageBox::critical(
+ NULL,
+ tr( "Error" ),
+ tr( "Error adding the new widget! No such widget type!" ),
+ QMessageBox::Ok
+ );
+
+ return;
+ }
+
+ // No class name defined
+ std::string className = node->getInfo().className;
+ if( className.empty() )
+ {
+ QMessageBox::critical(
+ NULL,
+ tr( "Error" ),
+ tr( "Error adding the new widget! Missing classname!" ),
+ QMessageBox::Ok
+ );
+
+ return;
+ }
+
+ std::string pgName = std::string( parentGroup.toUtf8() );
+ std::string wName = std::string( name.toUtf8() );
+
+ CInterfaceElement *e =
+ CWidgetManager::getInstance()->addWidgetToGroup(
+ pgName,
+ className,
+ wName
+ );
+
+ // Failed to add widget
+ if( e == NULL )
+ {
+ QMessageBox::critical(
+ NULL,
+ tr( "Error" ),
+ tr( "Error adding the new widget!" ),
+ QMessageBox::Ok
+ );
+
+ return;
+ }
+
+ // Setting the defaults will override the Id too
+ std::string id = e->getId();
+
+ // Set up the defaults
+ std::vector< SPropEntry >::const_iterator itr = node->getInfo().props.begin();
+ while( itr != node->getInfo().props.end() )
+ {
+ e->setProperty( itr->propName, itr->propDefault );
+ ++itr;
+ }
+
+ // Restore the Id
+ e->setId( id );
+ // Make the widget aligned to the top left corner
+ e->setParentPosRef( Hotspot_TL );
+ e->setPosRef( Hotspot_TL );
+
+ // Apply the new settings
+ e->setActive( false );
+ e->setActive( true );
+ }
+}
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.h
new file mode 100644
index 000000000..ffeedd7f1
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_message_processor.h
@@ -0,0 +1,46 @@
+// Object Viewer Qt GUI Editor plugin
+// 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
+
+namespace GUIEditor
+{
+ class CWidgetInfoTree;
+
+ /// Processes the GUI Editor's editor messages like delete, new, etc...
+ class CEditorMessageProcessor : public QObject
+ {
+ Q_OBJECT
+ public:
+ CEditorMessageProcessor( QObject *parent = NULL ) :
+ QObject( parent )
+ {
+ tree = NULL;
+ }
+
+ ~CEditorMessageProcessor(){}
+
+ void setTree( CWidgetInfoTree *tree ){ this->tree = tree; }
+
+ public Q_SLOTS:
+ void onDelete();
+ void onAdd( const QString &parentGroup, const QString &widgetType, const QString &name );
+
+ private:
+ CWidgetInfoTree *tree;
+ };
+}
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.cpp
new file mode 100644
index 000000000..ee3a079ad
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.cpp
@@ -0,0 +1,26 @@
+// 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 "editor_selection_watcher.h"
+
+namespace GUIEditor
+{
+ void CEditorSelectionWatcher::selectionChanged( std::string &newSelection )
+ {
+ Q_EMIT sgnSelectionChanged( newSelection );
+ }
+}
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.h
new file mode 100644
index 000000000..61218c0cd
--- /dev/null
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/editor_selection_watcher.h
@@ -0,0 +1,36 @@
+// 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/editor_selection_watcher.h"
+#include
+
+namespace GUIEditor
+{
+ /// Watches the Editor selection, and emits a signal when it changes
+ class CEditorSelectionWatcher : public QObject, public NLGUI::IEditorSelectionWatcher
+ {
+ Q_OBJECT
+
+ public:
+ CEditorSelectionWatcher() : QObject( NULL ){}
+
+ void selectionChanged( std::string &newSelection );
+
+ Q_SIGNALS:
+ void sgnSelectionChanged( std::string &id );
+ };
+}
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.cpp
index 5a0aff4de..341338d8d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.cpp
@@ -41,6 +41,9 @@
#include "project_file_serializer.h"
#include "project_window.h"
#include "nelgui_widget.h"
+#include "editor_selection_watcher.h"
+#include "editor_message_processor.h"
+#include "add_widget_widget.h"
namespace GUIEditor
{
@@ -53,11 +56,13 @@ namespace GUIEditor
QMainWindow(parent)
{
m_ui.setupUi(this);
+ messageProcessor = new CEditorMessageProcessor;
m_undoStack = new QUndoStack(this);
widgetProps = new CWidgetProperties;
linkList = new LinkList;
procList = new ProcList;
projectWindow = new ProjectWindow;
+ addWidgetWidget = new AddWidgetWidget;
connect( projectWindow, SIGNAL( projectFilesChanged() ), this, SLOT( onProjectFilesChanged() ) );
viewPort = new NelGUIWidget;
setCentralWidget( viewPort );
@@ -73,6 +78,8 @@ namespace GUIEditor
parser.setWidgetInfoTree( widgetInfoTree );
parser.parseGUIWidgets();
widgetProps->setupWidgetInfo( widgetInfoTree );
+ addWidgetWidget->setupWidgetInfo( widgetInfoTree );
+ messageProcessor->setTree( widgetInfoTree );
QDockWidget *dock = new QDockWidget( "Widget Hierarchy", this );
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
@@ -91,17 +98,23 @@ namespace GUIEditor
viewPort->init();
- connect( viewPort, SIGNAL( guiLoadComplete() ), hierarchyView, SLOT( onGUILoaded() ) );
- connect( viewPort, SIGNAL( guiLoadComplete() ), procList, SLOT( onGUILoaded() ) );
- connect( viewPort, SIGNAL( guiLoadComplete() ), linkList, SLOT( onGUILoaded() ) );
- connect( hierarchyView, SIGNAL( selectionChanged( std::string& ) ),
- &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) );
+ connect( viewPort, SIGNAL( guiLoadComplete() ), this, SLOT( onGUILoaded() ) );
+ connect( widgetProps, SIGNAL( treeChanged() ), this, SLOT( onTreeChanged() ) );
+ connect(
+ addWidgetWidget,
+ SIGNAL( adding( const QString&, const QString&, const QString& ) ),
+ messageProcessor,
+ SLOT( onAdd( const QString&, const QString&, const QString& ) )
+ );
}
GUIEditorWindow::~GUIEditorWindow()
{
writeSettings();
+ delete messageProcessor;
+ messageProcessor = NULL;
+
delete widgetProps;
widgetProps = NULL;
@@ -117,6 +130,9 @@ namespace GUIEditor
delete viewPort;
viewPort = NULL;
+ delete addWidgetWidget;
+ addWidgetWidget = NULL;
+
// no deletion needed for these, since dockwidget owns them
hierarchyView = NULL;
propBrowser = NULL;
@@ -262,6 +278,11 @@ namespace GUIEditor
if( reply != QMessageBox::Yes )
return false;
+
+ CEditorSelectionWatcher *w = viewPort->getWatcher();
+ disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) );
+ disconnect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) );
+
projectFiles.clearAll();
projectWindow->clear();
hierarchyView->clearHierarchy();
@@ -291,6 +312,30 @@ namespace GUIEditor
setCursor( Qt::ArrowCursor );
}
+ void GUIEditorWindow::onGUILoaded()
+ {
+ hierarchyView->onGUILoaded();
+ procList->onGUILoaded();
+ linkList->onGUILoaded();
+
+ CEditorSelectionWatcher *w = viewPort->getWatcher();
+ connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), hierarchyView, SLOT( onSelectionChanged( std::string& ) ) );
+ connect( w, SIGNAL( sgnSelectionChanged( std::string& ) ), &browserCtrl, SLOT( onSelectionChanged( std::string& ) ) );
+ }
+
+ void GUIEditorWindow::onAddWidgetClicked()
+ {
+ QString g;
+ hierarchyView->getCurrentGroup( g );
+
+ addWidgetWidget->setCurrentGroup( g );
+ addWidgetWidget->show();
+ }
+
+ void GUIEditorWindow::onTreeChanged()
+ {
+ addWidgetWidget->setupWidgetInfo( widgetInfoTree );
+ }
void GUIEditorWindow::createMenus()
{
@@ -299,6 +344,7 @@ namespace GUIEditor
QAction *saveAction = mm->action( Core::Constants::SAVE );
QAction *saveAsAction = mm->action( Core::Constants::SAVE_AS );
QAction *closeAction = mm->action( Core::Constants::CLOSE );
+ QAction *delAction = mm->action( Core::Constants::DEL );
//if( newAction != NULL )
// newAction->setEnabled( true );
@@ -308,6 +354,11 @@ namespace GUIEditor
saveAsAction->setEnabled( true );
if( closeAction != NULL )
closeAction->setEnabled( true );
+ if( delAction != NULL )
+ {
+ delAction->setEnabled( true );
+ connect( delAction, SIGNAL( triggered( bool ) ), messageProcessor, SLOT( onDelete() ) );
+ }
QMenu *menu = mm->menu( Core::Constants::M_TOOLS );
if( menu != NULL )
@@ -329,6 +380,10 @@ namespace GUIEditor
a = new QAction( "Project Window", this );
connect( a, SIGNAL( triggered( bool ) ), projectWindow, SLOT( show() ) );
m->addAction( a );
+
+ a = new QAction( "Add Widget", this );
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) );
+ m->addAction( a );
}
}
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.h
index d4327d3d9..e1a8b8b2d 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/gui_editor_window.h
@@ -36,6 +36,8 @@ namespace GUIEditor
class ProjectWindow;
class NelGUIWidget;
class CWidgetInfoTree;
+ class CEditorMessageProcessor;
+ class AddWidgetWidget;
class GUIEditorWindow: public QMainWindow
{
@@ -58,6 +60,9 @@ public Q_SLOTS:
private Q_SLOTS:
void onProjectFilesChanged();
+ void onGUILoaded();
+ void onAddWidgetClicked();
+ void onTreeChanged();
private:
void createMenus();
@@ -76,8 +81,9 @@ private:
ProcList *procList;
ProjectWindow *projectWindow;
NelGUIWidget *viewPort;
-
CWidgetInfoTree *widgetInfoTree;
+ CEditorMessageProcessor *messageProcessor;
+ AddWidgetWidget *addWidgetWidget;
CPropBrowserCtrl browserCtrl;
QString currentProject;
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.cpp
index 85525e428..d86d31269 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include "editor_selection_watcher.h"
namespace GUIEditor
{
@@ -37,6 +38,7 @@ namespace GUIEditor
{
timerID = 0;
guiLoaded = false;
+ watcher = NULL;
}
NelGUIWidget::~NelGUIWidget()
@@ -70,6 +72,8 @@ namespace GUIEditor
NLGUI::CViewRenderer::getInstance()->init();
CWidgetManager::getInstance()->getParser()->setEditorMode( true );
+
+ watcher = new CEditorSelectionWatcher();
}
bool NelGUIWidget::parse( SProjectFiles &files )
@@ -106,6 +110,8 @@ namespace GUIEditor
guiLoaded = true;
Q_EMIT guiLoadComplete();
+ CWidgetManager::getInstance()->registerSelectionWatcher( watcher );
+
return true;
}
@@ -115,6 +121,7 @@ namespace GUIEditor
if( timerID != 0 )
killTimer( timerID );
timerID = 0;
+ CWidgetManager::getInstance()->unregisterSelectionWatcher( watcher );
CWidgetManager::getInstance()->reset();
CWidgetManager::getInstance()->getParser()->removeAll();
CViewRenderer::getInstance()->reset();
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.h
index 5a45cc351..34c510507 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/nelgui_widget.h
@@ -23,6 +23,8 @@
namespace GUIEditor
{
+ class CEditorSelectionWatcher;
+
/// Qt viewport for the Nel GUI library
class NelGUIWidget : public Nel3DWidget
{
@@ -35,6 +37,7 @@ namespace GUIEditor
bool parse( SProjectFiles &files );
void draw();
void reset();
+ CEditorSelectionWatcher* getWatcher(){ return watcher; }
Q_SIGNALS:
void guiLoadComplete();
@@ -49,6 +52,7 @@ Q_SIGNALS:
private:
int timerID;
bool guiLoaded;
+ CEditorSelectionWatcher *watcher;
};
}
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/property_browser_ctrl.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/property_browser_ctrl.cpp
index 1612ea803..82330bfaf 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/property_browser_ctrl.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/property_browser_ctrl.cpp
@@ -78,7 +78,12 @@ namespace GUIEditor
CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( id );
if( e == NULL )
+ {
+ connect( propertyMgr, SIGNAL( propertyChanged( QtProperty* ) ),
+ this, SLOT( onPropertyChanged( QtProperty* ) ) );
+
return;
+ }
currentElement = id;
@@ -106,6 +111,12 @@ namespace GUIEditor
if( e == NULL )
return;
e->setProperty( propName.toUtf8().constData(), propValue.toUtf8().constData() );
+
+
+ // Make sure the changes are applied
+ bool active = e->getActive();
+ e->setActive( !active );
+ e->setActive( active );
}
void CPropBrowserCtrl::setupProperties( const std::string &type, const CInterfaceElement *element )
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp
index 9c3a74fd7..24208f4a3 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.cpp
@@ -18,6 +18,7 @@
#include "widget_hierarchy.h"
#include "nel/gui/interface_group.h"
#include "nel/gui/widget_manager.h"
+#include "nel/gui/widget_addition_watcher.h"
namespace
{
@@ -56,6 +57,45 @@ namespace
name = s.toUtf8().constData();
return name;
}
+
+ class CWidgetDeletionWatcher : public CInterfaceElement::IDeletionWatcher
+ {
+ public:
+ CWidgetDeletionWatcher(){ h = NULL; }
+
+ ~CWidgetDeletionWatcher(){}
+
+ void onDeleted( const std::string &id ){
+ if( h != NULL )
+ h->onWidgetDeleted( id );
+ }
+
+ void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; }
+
+ private:
+ GUIEditor::WidgetHierarchy *h;
+ };
+
+ class CWidgetAdditionWatcher : public IWidgetAdditionWatcher
+ {
+ public:
+ CWidgetAdditionWatcher(){ h = NULL; }
+ ~CWidgetAdditionWatcher(){}
+
+ void widgetAdded( const std::string &name )
+ {
+ if( h != NULL )
+ h->onWidgetAdded( name );
+ }
+
+ void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; }
+
+ private:
+ GUIEditor::WidgetHierarchy *h;
+ };
+
+ CWidgetDeletionWatcher deletionWatcher;
+ CWidgetAdditionWatcher additionWatcher;
}
namespace GUIEditor
@@ -66,6 +106,8 @@ namespace GUIEditor
setupUi( this );
connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ),
this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) );
+ deletionWatcher.setWidgetHierarchy( this );
+ additionWatcher.setWidgetHierarchy( this );
}
WidgetHierarchy::~WidgetHierarchy()
@@ -74,12 +116,17 @@ namespace GUIEditor
void WidgetHierarchy::clearHierarchy()
{
+ CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher );
+ CWidgetManager::getInstance()->unregisterAdditionWatcher( &additionWatcher );
widgetHT->clear();
+ widgetHierarchyMap.clear();
}
void WidgetHierarchy::buildHierarchy( std::string &masterGroup )
{
clearHierarchy();
+ CInterfaceElement::registerDeletionWatcher( &deletionWatcher );
+ CWidgetManager::getInstance()->registerAdditionWatcher( &additionWatcher );
CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup );
if( mg != NULL )
@@ -87,6 +134,7 @@ namespace GUIEditor
QTreeWidgetItem *item = new QTreeWidgetItem( static_cast(NULL) );
item->setText( 0, "ui" );
widgetHT->addTopLevelItem( item );
+ widgetHierarchyMap[ "ui" ] = item;
buildHierarchy( item, mg );
}
@@ -96,7 +144,9 @@ namespace GUIEditor
{
// First add ourselves
QTreeWidgetItem *item = new QTreeWidgetItem( parent );
+
item->setText( 0, makeNodeName( group->getId() ).c_str() );
+ widgetHierarchyMap[ group->getId() ] = item;
// Then add recursively our subgroups
const std::vector< CInterfaceGroup* > &groups = group->getGroups();
@@ -113,6 +163,7 @@ namespace GUIEditor
{
QTreeWidgetItem *subItem = new QTreeWidgetItem( item );
subItem->setText( 0, makeNodeName( (*citr)->getId() ).c_str() );
+ widgetHierarchyMap[ (*citr)->getId() ] = subItem;
}
// Add our views
@@ -122,14 +173,134 @@ namespace GUIEditor
{
QTreeWidgetItem *subItem = new QTreeWidgetItem( item );
subItem->setText( 0, makeNodeName( (*vitr)->getId() ).c_str() );
+ widgetHierarchyMap[ (*vitr)->getId() ] = subItem;
}
}
+ void WidgetHierarchy::onWidgetDeleted( const std::string &id )
+ {
+ std::map< std::string, QTreeWidgetItem* >::iterator itr
+ = widgetHierarchyMap.find( id );
+ if( itr == widgetHierarchyMap.end() )
+ return;
+
+ if( widgetHT->currentItem() == itr->second )
+ {
+ QTreeWidgetItem *item = itr->second;
+ QTreeWidgetItem *p = item;
+
+ // Deselect item
+ item->setSelected( false );
+ widgetHT->setCurrentItem( NULL );
+
+ // Collapse the tree
+ while( p != NULL )
+ {
+ p->setExpanded( false );
+ p = p->parent();
+ }
+
+ currentSelection = "";
+ }
+
+ itr->second->setSelected( false );
+
+ delete itr->second;
+ itr->second = NULL;
+ widgetHierarchyMap.erase( itr );
+ }
+
+ void WidgetHierarchy::onWidgetAdded( const std::string &id )
+ {
+ // Get the parent's name
+ std::string::size_type p = id.find_last_of( ':' );
+ if( p == std::string::npos )
+ return;
+ std::string parentId = id.substr( 0, p );
+
+ // Do we have the parent in the hierarchy?
+ std::map< std::string, QTreeWidgetItem* >::iterator itr
+ = widgetHierarchyMap.find( parentId );
+ if( itr == widgetHierarchyMap.end() )
+ return;
+
+ // Add the new widget to the hierarchy
+ QTreeWidgetItem *parent = itr->second;
+ QTreeWidgetItem *item = new QTreeWidgetItem( parent );
+ item->setText( 0, makeNodeName( id ).c_str() );
+ widgetHierarchyMap[ id ] = item;
+ }
+
+ void WidgetHierarchy::getCurrentGroup( QString &g )
+ {
+ std::string s = CWidgetManager::getInstance()->getCurrentEditorSelection();
+ if( s.empty() )
+ {
+ g = "";
+ return;
+ }
+
+ NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( s );
+ if( e == NULL )
+ {
+ g = "";
+ return;
+ }
+
+ if( e->isGroup() )
+ {
+ g = e->getId().c_str();
+ return;
+ }
+
+ NLGUI::CInterfaceGroup *p = e->getParent();
+ if( p == NULL )
+ {
+ g = "";
+ return;
+ }
+
+ g = p->getId().c_str();
+ }
+
void WidgetHierarchy::onGUILoaded()
{
if( masterGroup.empty() )
return;
buildHierarchy( masterGroup );
+ currentSelection.clear();
+ }
+
+ void WidgetHierarchy::onSelectionChanged( std::string &newSelection )
+ {
+ if( newSelection == currentSelection )
+ return;
+
+ if( newSelection.empty() )
+ return;
+
+ std::map< std::string, QTreeWidgetItem* >::iterator itr =
+ widgetHierarchyMap.find( newSelection );
+ if( itr == widgetHierarchyMap.end() )
+ return;
+
+ // deselect current item
+ 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();
+ }
+
+ // select the current item
+ item->setSelected( true );
+ widgetHT->setCurrentItem( item );
+ currentSelection = newSelection;
}
void WidgetHierarchy::onItemDblClicked( QTreeWidgetItem *item )
@@ -138,9 +309,7 @@ namespace GUIEditor
return;
std::string n = item->text( 0 ).toUtf8().constData();
- std::string selection = makeFullName( item, n );
- CWidgetManager::getInstance()->setCurrentEditorSelection( selection );
-
- Q_EMIT selectionChanged( selection );
+ currentSelection = makeFullName( item, n );
+ CWidgetManager::getInstance()->setCurrentEditorSelection( currentSelection );
}
}
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h
index 493fd2a08..4641c8ce8 100644
--- a/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h
+++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/gui_editor/widget_hierarchy.h
@@ -18,6 +18,8 @@
#define WIDGET_HA_H
#include "ui_widget_hierarchy.h"
+#include
+#include