1 // Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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>
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"
28 std::string
makeNodeName( const std::string
&name
)
34 std::string::size_type i
= s
.find_last_of( ":" );
35 if( i
== std::string::npos
)
38 if( i
== ( s
.size() - 1 ) )
41 s
= name
.substr( i
+ 1, s
.size() - 1 );
45 std::string
& makeFullName( QTreeWidgetItem
*item
, std::string
&name
)
52 item
= item
->parent();
56 s
.prepend( item
->text( 0 ) + ":" );
57 item
= item
->parent();
60 name
= s
.toUtf8().constData();
64 class CWidgetDeletionWatcher
: public CInterfaceElement::IDeletionWatcher
67 CWidgetDeletionWatcher(){ h
= NULL
; }
69 ~CWidgetDeletionWatcher(){}
71 void onDeleted( const std::string
&id
){
73 h
->onWidgetDeleted( id
);
76 void setWidgetHierarchy( GUIEditor::WidgetHierarchy
*h
){ this->h
= h
; }
79 GUIEditor::WidgetHierarchy
*h
;
82 class CWidgetWatcher
: public CWidgetManager::IWidgetWatcher
85 CWidgetWatcher(){ h
= NULL
; }
88 void onWidgetAdded( const std::string
&name
)
91 h
->onWidgetAdded( name
);
94 void onWidgetMoved( const std::string
&oldid
, const std::string
&newid
)
97 h
->onWidgetMoved( oldid
, newid
);
100 void setWidgetHierarchy( GUIEditor::WidgetHierarchy
*h
){ this->h
= h
; }
103 GUIEditor::WidgetHierarchy
*h
;
106 CWidgetDeletionWatcher deletionWatcher
;
107 CWidgetWatcher widgetwatcher
;
112 WidgetHierarchy::WidgetHierarchy( QWidget
*parent
) :
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
);
131 widgetHierarchyMap
.clear();
134 void WidgetHierarchy::buildHierarchy( std::string
&masterGroup
)
137 CInterfaceElement::registerDeletionWatcher( &deletionWatcher
);
138 CWidgetManager::getInstance()->registerWidgetWatcher( &widgetwatcher
);
140 CInterfaceGroup
*mg
= CWidgetManager::getInstance()->getMasterGroupFromId( masterGroup
);
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
);
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() )
176 QTreeWidgetItem
*subItem
= new QTreeWidgetItem( item
);
177 subItem
->setText( 0, makeNodeName( (*citr
)->getId() ).c_str() );
178 widgetHierarchyMap
[ (*citr
)->getId() ] = subItem
;
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() )
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() )
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
)
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() )
223 if( widgetHT
->currentItem() == itr
->second
)
225 QTreeWidgetItem
*item
= itr
->second
;
226 QTreeWidgetItem
*p
= item
;
229 item
->setSelected( false );
230 widgetHT
->setCurrentItem( NULL
);
235 p
->setExpanded( false );
239 currentSelection
= "";
242 itr
->second
->setSelected( false );
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
)
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() )
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
;
276 newParent
= findParent( newid
);
277 item
= findItem( oldid
);
279 if( ( newParent
== NULL
) || ( item
== NULL
) )
282 // Remove item from old parent
283 QTreeWidgetItem
*p
= item
->parent();
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
;
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 )
325 NLGUI::CInterfaceElement
*e
= CWidgetManager::getInstance()->getElementFromId( selection
[ 0 ] );
334 g
= e
->getId().c_str();
338 NLGUI::CInterfaceGroup
*p
= e
->getParent();
345 g
= p
->getId().c_str();
348 void WidgetHierarchy::onGUILoaded()
350 if( masterGroup
.empty() )
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 )
364 std::string newSelection
= selection
[ 0 ];
366 if( newSelection
== currentSelection
)
369 if( newSelection
.empty() )
372 std::map
< std::string
, QTreeWidgetItem
* >::iterator itr
=
373 widgetHierarchyMap
.find( newSelection
);
374 if( itr
== widgetHierarchyMap
.end() )
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
;
386 currentSelection
= newSelection
;
389 void WidgetHierarchy::onItemDblClicked( QTreeWidgetItem
*item
)
391 if( item
->parent() == NULL
)
396 std::string n
= item
->text( 0 ).toUtf8().constData();
397 currentSelection
= makeFullName( item
, n
);
398 CWidgetManager::getInstance()->selectWidget( currentSelection
);