New lua versions
[ryzomcore.git] / studio / src / plugins / gui_editor / widget_hierarchy.cpp
blob3107b5356338b4e708f948e50f5d0aa0c01cbf78
1 // Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2013-2014 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "widget_hierarchy.h"
23 #include "nel/gui/interface_group.h"
24 #include "nel/gui/widget_manager.h"
26 namespace
28 std::string makeNodeName( const std::string &name )
30 std::string s = name;
31 if( s.empty() )
32 return s;
34 std::string::size_type i = s.find_last_of( ":" );
35 if( i == std::string::npos )
36 return s;
38 if( i == ( s.size() - 1 ) )
39 return s;
41 s = name.substr( i + 1, s.size() - 1 );
42 return s;
45 std::string& makeFullName( QTreeWidgetItem *item, std::string &name )
47 if( item == NULL )
48 return name;
49 QString s;
51 s = item->text( 0 );
52 item = item->parent();
54 while( item != NULL )
56 s.prepend( item->text( 0 ) + ":" );
57 item = item->parent();
60 name = s.toUtf8().constData();
61 return name;
64 class CWidgetDeletionWatcher : public CInterfaceElement::IDeletionWatcher
66 public:
67 CWidgetDeletionWatcher(){ h = NULL; }
69 ~CWidgetDeletionWatcher(){}
71 void onDeleted( const std::string &id ){
72 if( h != NULL )
73 h->onWidgetDeleted( id );
76 void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; }
78 private:
79 GUIEditor::WidgetHierarchy *h;
82 class CWidgetWatcher : public CWidgetManager::IWidgetWatcher
84 public:
85 CWidgetWatcher(){ h = NULL; }
86 ~CWidgetWatcher(){}
88 void onWidgetAdded( const std::string &name )
90 if( h != NULL )
91 h->onWidgetAdded( name );
94 void onWidgetMoved( const std::string &oldid, const std::string &newid )
96 if( h != NULL )
97 h->onWidgetMoved( oldid, newid );
100 void setWidgetHierarchy( GUIEditor::WidgetHierarchy *h ){ this->h = h; }
102 private:
103 GUIEditor::WidgetHierarchy *h;
106 CWidgetDeletionWatcher deletionWatcher;
107 CWidgetWatcher widgetwatcher;
110 namespace GUIEditor
112 WidgetHierarchy::WidgetHierarchy( QWidget *parent ) :
113 QWidget( parent )
115 setupUi( this );
116 connect( widgetHT, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ),
117 this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) );
118 deletionWatcher.setWidgetHierarchy( this );
119 widgetwatcher.setWidgetHierarchy( this );
122 WidgetHierarchy::~WidgetHierarchy()
126 void WidgetHierarchy::clearHierarchy()
128 CInterfaceElement::unregisterDeletionWatcher( &deletionWatcher );
129 CWidgetManager::getInstance()->unregisterWidgetWatcher( &widgetwatcher );
130 widgetHT->clear();
131 widgetHierarchyMap.clear();
134 void WidgetHierarchy::buildHierarchy( std::string &masterGroup )
136 clearHierarchy();
137 CInterfaceElement::registerDeletionWatcher( &deletionWatcher );
138 CWidgetManager::getInstance()->registerWidgetWatcher( &widgetwatcher );
140 CInterfaceGroup *mg = CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup );
141 if( mg != NULL )
143 QTreeWidgetItem *item = new QTreeWidgetItem( static_cast<QTreeWidgetItem*>(NULL) );
144 item->setText( 0, "ui" );
145 widgetHT->addTopLevelItem( item );
146 widgetHierarchyMap[ "ui" ] = item;
148 buildHierarchy( item, mg );
152 void WidgetHierarchy::buildHierarchy( QTreeWidgetItem *parent, CInterfaceGroup *group )
154 // First add ourselves
155 QTreeWidgetItem *item = new QTreeWidgetItem( parent );
157 item->setText( 0, makeNodeName( group->getId() ).c_str() );
158 widgetHierarchyMap[ group->getId() ] = item;
160 // Then add recursively our subgroups
161 const std::vector< CInterfaceGroup* > &groups = group->getGroups();
162 std::vector< CInterfaceGroup* >::const_iterator gitr;
163 for( gitr = groups.begin(); gitr != groups.end(); ++gitr )
165 buildHierarchy( item, *gitr );
168 // Add our controls
169 const std::vector< CCtrlBase* > &controls = group->getControls();
170 std::vector< CCtrlBase* >::const_iterator citr;
171 for( citr = controls.begin(); citr != controls.end(); ++citr )
173 if( !(*citr)->isEditorSelectable() )
174 continue;
176 QTreeWidgetItem *subItem = new QTreeWidgetItem( item );
177 subItem->setText( 0, makeNodeName( (*citr)->getId() ).c_str() );
178 widgetHierarchyMap[ (*citr)->getId() ] = subItem;
181 // Add our views
182 const std::vector< CViewBase* > &views = group->getViews();
183 std::vector< CViewBase* >::const_iterator vitr;
184 for( vitr = views.begin(); vitr != views.end(); ++vitr )
186 if( !(*vitr)->isEditorSelectable() )
187 continue;
189 QTreeWidgetItem *subItem = new QTreeWidgetItem( item );
190 subItem->setText( 0, makeNodeName( (*vitr)->getId() ).c_str() );
191 widgetHierarchyMap[ (*vitr)->getId() ] = subItem;
195 QTreeWidgetItem* WidgetHierarchy::findItem( const std::string &id )
197 std::map< std::string, QTreeWidgetItem* >::iterator itr
198 = widgetHierarchyMap.find( id );
199 if( itr == widgetHierarchyMap.end() )
200 return NULL;
201 else
202 return itr->second;
205 QTreeWidgetItem* WidgetHierarchy::findParent( const std::string &id )
207 // Get the parent's name
208 std::string::size_type p = id.find_last_of( ':' );
209 if( p == std::string::npos )
210 return NULL;
211 std::string parentId = id.substr( 0, p );
213 return findItem( parentId );
216 void WidgetHierarchy::onWidgetDeleted( const std::string &id )
218 std::map< std::string, QTreeWidgetItem* >::iterator itr
219 = widgetHierarchyMap.find( id );
220 if( itr == widgetHierarchyMap.end() )
221 return;
223 if( widgetHT->currentItem() == itr->second )
225 QTreeWidgetItem *item = itr->second;
226 QTreeWidgetItem *p = item;
228 // Deselect item
229 item->setSelected( false );
230 widgetHT->setCurrentItem( NULL );
232 // Collapse the tree
233 while( p != NULL )
235 p->setExpanded( false );
236 p = p->parent();
239 currentSelection = "";
242 itr->second->setSelected( false );
244 delete itr->second;
245 itr->second = NULL;
246 widgetHierarchyMap.erase( itr );
249 void WidgetHierarchy::onWidgetAdded( const std::string &id )
251 // Get the parent's name
252 std::string::size_type p = id.find_last_of( ':' );
253 if( p == std::string::npos )
254 return;
255 std::string parentId = id.substr( 0, p );
257 // Do we have the parent in the hierarchy?
258 std::map< std::string, QTreeWidgetItem* >::iterator itr
259 = widgetHierarchyMap.find( parentId );
260 if( itr == widgetHierarchyMap.end() )
261 return;
263 // Add the new widget to the hierarchy
264 QTreeWidgetItem *parent = itr->second;
265 QTreeWidgetItem *item = new QTreeWidgetItem( parent );
266 item->setText( 0, makeNodeName( id ).c_str() );
267 widgetHierarchyMap[ id ] = item;
270 void WidgetHierarchy::onWidgetMoved( const std::string &oldid, const std::string &newid )
272 QTreeWidgetItem *newParent = NULL;
273 QTreeWidgetItem *item = NULL;
274 QString id;
276 newParent = findParent( newid );
277 item = findItem( oldid );
279 if( ( newParent == NULL ) || ( item == NULL ) )
280 return;
282 // Remove item from old parent
283 QTreeWidgetItem *p = item->parent();
284 if( p != NULL )
285 p->setExpanded( false );
286 p->removeChild( item );
288 // Remove reference to old item
289 widgetHierarchyMap.erase( oldid );
291 // Add item to new parent
292 newParent->addChild( item );
294 // Add reference to new item
295 widgetHierarchyMap[ newid ] = item;
297 selectItem( item );
300 void WidgetHierarchy::selectItem( QTreeWidgetItem *item )
302 widgetHT->collapseAll();
304 QTreeWidgetItem *currItem = item;
305 while( currItem != NULL )
307 currItem->setExpanded( true );
308 currItem = currItem->parent();
311 widgetHT->setCurrentItem( item );
312 item->setSelected( true );
315 void WidgetHierarchy::getCurrentGroup( QString &g )
317 std::vector< std::string > selection;
318 CWidgetManager::getInstance()->getEditorSelection( selection );
319 if( selection.size() != 1 )
321 g = "";
322 return;
325 NLGUI::CInterfaceElement *e = CWidgetManager::getInstance()->getElementFromId( selection[ 0 ] );
326 if( e == NULL )
328 g = "";
329 return;
332 if( e->isGroup() )
334 g = e->getId().c_str();
335 return;
338 NLGUI::CInterfaceGroup *p = e->getParent();
339 if( p == NULL )
341 g = "";
342 return;
345 g = p->getId().c_str();
348 void WidgetHierarchy::onGUILoaded()
350 if( masterGroup.empty() )
351 return;
352 buildHierarchy( masterGroup );
353 currentSelection.clear();
356 void WidgetHierarchy::onSelectionChanged()
358 std::vector< std::string > selection;
359 CWidgetManager::getInstance()->getEditorSelection( selection );
361 if( selection.size() != 1 )
362 return;
364 std::string newSelection = selection[ 0 ];
366 if( newSelection == currentSelection )
367 return;
369 if( newSelection.empty() )
370 return;
372 std::map< std::string, QTreeWidgetItem* >::iterator itr =
373 widgetHierarchyMap.find( newSelection );
374 if( itr == widgetHierarchyMap.end() )
375 return;
377 // deselect current item
378 if( widgetHT->currentItem() != NULL )
379 widgetHT->currentItem()->setSelected( false );
381 widgetHT->collapseAll();
383 // select the current item
384 QTreeWidgetItem *item = itr->second;
385 selectItem( item );
386 currentSelection = newSelection;
389 void WidgetHierarchy::onItemDblClicked( QTreeWidgetItem *item )
391 if( item->parent() == NULL )
392 return;
394 selectItem( item );
396 std::string n = item->text( 0 ).toUtf8().constData();
397 currentSelection = makeFullName( item, n );
398 CWidgetManager::getInstance()->selectWidget( currentSelection );