Torque3D Documentation / _generateds / guiTreeViewCtrl.h

guiTreeViewCtrl.h

Engine/source/gui/controls/guiTreeViewCtrl.h

More...

Classes:

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _GUI_TREEVIEWCTRL_H
 25#define _GUI_TREEVIEWCTRL_H
 26
 27#include "core/bitSet.h"
 28#include "math/mRect.h"
 29#include "gfx/gFont.h"
 30#include "gui/core/guiControl.h"
 31#include "gui/core/guiArrayCtrl.h"
 32
 33
 34class GuiTextEditCtrl;
 35
 36//------------------------------------------------------------------------------
 37
 38class GuiTreeViewCtrl : public GuiArrayCtrl
 39{
 40   private:
 41      typedef GuiArrayCtrl Parent;
 42
 43   public:
 44      /// @section GuiControl_Intro Introduction
 45      /// @nosubgrouping
 46
 47      ///
 48      class Item
 49      {
 50         public:
 51
 52            enum ItemState
 53            {
 54               Selected       = BIT( 0 ),
 55               Expanded       = BIT( 1 ),
 56               Marked         = BIT( 2 ), ///< Marked items are drawn with a border around them. This is
 57                                        ///  different than "Selected" because it can only be set by script.
 58               Filtered       = BIT( 3 ), ///< Whether the item is currently filtered out.
 59               MouseOverBmp   = BIT( 4 ),
 60               MouseOverText  = BIT( 5 ),
 61               MouseOverIcon  = BIT( 6 ),
 62               InspectorData  = BIT( 7 ), ///< Set if we're representing some inspector
 63                                        /// info (ie, use mInspectorInfo, not mScriptInfo)
 64
 65               VirtualParent  = BIT( 8 ), ///< This indicates that we should be rendered as
 66                                        ///  a parent even though we don't have any children.
 67                                        ///  This is useful for preventing scenarios where
 68                                        ///  we might want to create thousands of
 69                                        ///  Items that might never be shown (for instance
 70                                        ///  if we're browsing the object hierarchy in
 71                                        ///  Torque, which might have thousands of objects).
 72
 73               RebuildVisited    = BIT( 9 ), ///< Rebuild traversal for virtual parents has visited and validated this item.
 74               
 75               ShowObjectId      = BIT( 10 ),
 76               ShowClassName     = BIT( 11 ),
 77               ShowObjectName    = BIT( 12 ),
 78               ShowInternalName  = BIT( 13 ),
 79               ShowClassNameForUnnamed = BIT( 14 ),
 80               ForceItemName = BIT(15),
 81               ForceDragTarget = BIT(16),
 82               DenyDrag = BIT(17),
 83            };
 84
 85            GuiTreeViewCtrl* mParentControl;
 86            BitSet32 mState;
 87            SimObjectPtr< GuiControlProfile> mProfile;
 88            S16 mId;
 89            U16 mTabLevel;
 90            Item* mParent;
 91            Item* mChild;
 92            Item* mNext;
 93            Item* mPrevious;
 94            String mTooltip;
 95            S32 mIcon; //stores the icon that will represent the item in the tree
 96            S32 mDataRenderWidth; /// this stores the pixel width needed
 97                                  /// to render the item's data in the 
 98                                  /// onRenderCell function to optimize
 99                                  /// for speed.
100
101            Item( GuiTreeViewCtrl* parent, GuiControlProfile *pProfile );
102            ~Item();
103
104            struct ScriptTag
105            {
106               S8 mNormalImage;
107               S8 mExpandedImage;
108               StringTableEntry mText;
109               StringTableEntry mValue;
110            } mScriptInfo;
111            struct InspectorTag
112            {
113               SimObjectPtr<SimObject> mObject;
114            } mInspectorInfo;
115
116            /// @name Get Methods
117            /// @{
118
119            ///
120            S8 getNormalImage() const;
121            S8 getExpandedImage() const;
122            StringTableEntry getText();
123            StringTableEntry getValue();
124            inline const S16 getID() const { return mId; };
125            SimObject *getObject();
126            U32 getDisplayTextLength();
127            S32 getDisplayTextWidth(GFont *font);
128            void getDisplayText(U32 bufLen, char *buf);
129            bool hasObjectBasedTooltip();
130            void getTooltipText(U32 bufLen, char *buf);
131
132            /// @}
133
134
135            /// @name Set Methods
136            /// @{
137
138            /// Set whether an item is expanded or not (showing children or having them hidden)
139            void setExpanded( const bool f = true );
140            /// Set the image to display when an item IS expanded
141            void setExpandedImage(const S8 id);
142            /// Set the image to display when an item is NOT expanded
143            void setNormalImage(const S8 id);
144            /// Assign a SimObject pointer to an inspector data item
145            void setObject(SimObject *obj);
146            /// Set the items displayable text (caption)
147            void setText(StringTableEntry txt);
148            /// Set the items script value (data)
149            void setValue(StringTableEntry val);
150            /// Set the items virtual parent flag
151            void setVirtualParent( bool value );
152            /// Set whether the item is filtered out or not.
153            void setFiltered( bool value ) { mState.set( Filtered ); }
154
155            /// @}
156
157
158            /// @name State Retrieval
159            /// @{
160
161            /// Returns true if this item is expanded. For
162            /// inspector objects, the expansion is stored
163            /// on the SimObject, for other things we use our
164            /// bit vector.
165            bool isExpanded() const;
166
167            /// Return whether the item is current filtered out or not.
168            /// @note Parent items may be filtered and yet still be visible if they have
169            ///   children that are not filtered.
170            bool isFiltered() const { return mState.test( Filtered ); }
171
172            /// Returns true if an item is inspector data
173            /// or false if it's just an item.
174            bool isInspectorData() const { return mState.test(InspectorData); };
175
176            /// Returns true if we've been manually set to allow dragging overrides.
177            /// As it's a manually set flag, by default it is false.
178            bool isDragTargetAllowed() const { return mState.test(ForceDragTarget); };
179
180            /// Returns true if we've been manually set to allow dragging overrides.
181            /// As it's a manually set flag, by default it is false.
182            bool isDragAllowed() const { return !mState.test(DenyDrag); };
183
184            /// Returns true if we should show the expand art
185            /// and make the item interact with the mouse as if
186            /// it were a parent.
187            bool isParent() const;
188            
189            /// Return true if text label for inspector item should include internal name only.
190            bool showInternalNameOnly() const { return mState.test( ShowInternalName ) && !mState.test( ShowObjectName | ShowClassName | ShowObjectId ); }
191
192            /// Return true if text label for inspector item should include object name only.
193            bool showObjectNameOnly() const { return mState.test( ShowObjectName ) && !mState.test( ShowInternalName | ShowClassName | ShowObjectId ); }
194
195            /// @}
196
197            /// @name Searching Methods
198            /// @{
199            
200            /// Find a regular data item by it's script name.
201            Item* findChildByName( const char* name );
202
203            /// Find an inspector data item by it's SimObject pointer
204            Item* findChildByValue(const SimObject *obj);
205
206            /// Find a regular data item by it's script value
207            Item* findChildByValue(StringTableEntry Value);
208
209            /// @}
210            
211            /// Sort the childs of the item by their text.
212            ///
213            /// @param caseSensitive If true, sorting is case-sensitive.
214            /// @param traverseHierarchy If true, also triggers a sort() on all child items.
215            /// @param parentsFirst If true, parents are grouped before children in the resulting sort.
216            void sort( bool caseSensitive = true, bool traverseHierarchy = false, bool parentsFirst = false );
217
218         private:
219            void _connectMonitors();
220            void _disconnectMonitors();
221      };
222
223      friend class Item; // _onInspectorSetObjectModified
224
225      /// @name Enums
226      /// @{
227
228      ///
229      enum TreeState
230      {
231         RebuildVisible    = BIT(0), ///< Temporary flag, we have to rebuild the tree.
232         IsInspector       = BIT(1), ///< We are mapping a SimObject hierarchy.
233         IsEditable        = BIT(2), ///< We allow items to be moved around.
234         ShowTreeLines     = BIT(3), ///< Should we render tree lines or just icons?
235         BuildingVisTree   = BIT(4), ///< We are currently building the visible tree (prevent recursion)
236      };
237
238   protected:
239
240      enum
241      {
242         MaxIcons = 32,
243      };
244
245      enum Icons
246      {
247         Default1 = 0,
248         SimGroup1,
249         SimGroup2,
250         SimGroup3,
251         SimGroup4,         
252         Hidden,         
253         Lock1,
254         Lock2,         
255         Default,
256         Icon31,
257         Icon32
258      };
259
260      enum mDragMidPointFlags
261      {
262            NomDragMidPoint,
263            AbovemDragMidPoint,
264            BelowmDragMidPoint
265      };
266
267      ///
268      enum HitFlags
269      {
270         OnIndent       = BIT(0),
271         OnImage        = BIT(1),
272         OnIcon         = BIT(2),
273         OnText         = BIT(3),         
274         OnRow          = BIT(4),
275      };
276
277      ///
278      enum BmpIndices
279      {
280         BmpFirstChild,
281         BmpLastChild,
282         BmpChild,
283         BmpExp,
284         BmpExpN,
285         BmpExpP,
286         BmpExpPN,
287         BmpCon,
288         BmpConN,
289         BmpConP,
290         BmpConPN,
291         BmpLine,
292         BmpGlow,
293      };
294
295      /// @}
296
297      /// @name Callbacks
298      /// @{
299
300      DECLARE_CALLBACK( bool, onDeleteObject, ( SimObject* object ) );
301      DECLARE_CALLBACK( bool, isValidDragTarget, ( S32 id, const char* value ) );
302      DECLARE_CALLBACK( void, onDefineIcons, () );
303      DECLARE_CALLBACK( void, onAddGroupSelected, ( SimGroup* group ) );
304      DECLARE_CALLBACK( void, onAddSelection, ( S32 itemOrObjectId, bool isLastSelection ) );
305      DECLARE_CALLBACK( void, onSelect, ( S32 itemOrObjectId ) );
306      DECLARE_CALLBACK( void, onInspect, ( S32 itemOrObjectId ) );
307      DECLARE_CALLBACK( void, onRemoveSelection, ( S32 itemOrObjectId ) );
308      DECLARE_CALLBACK( void, onUnselect, ( S32 itemOrObjectId ) );
309      DECLARE_CALLBACK( void, onDeleteSelection, () );
310      DECLARE_CALLBACK( void, onObjectDeleteCompleted, () );
311      DECLARE_CALLBACK( void, onKeyDown, ( S32 modifier, S32 keyCode ) );
312      DECLARE_CALLBACK( void, onMouseUp, ( S32 hitItemId, S32 mouseClickCount ) );
313      DECLARE_CALLBACK( void, onMouseDragged, () );
314      DECLARE_CALLBACK( void, onRightMouseDown, ( S32 itemId, const Point2I& mousePos, SimObject* object = NULL ) );
315      DECLARE_CALLBACK( void, onRightMouseUp, ( S32 itemId, const Point2I& mousePos, SimObject* object = NULL ) );
316      DECLARE_CALLBACK( void, onBeginReparenting, () );
317      DECLARE_CALLBACK( void, onEndReparenting, () );
318      DECLARE_CALLBACK( void, onReparent, ( S32 itemOrObjectId, S32 oldParentItemOrObjectId, S32 newParentItemOrObjectId ) );
319      DECLARE_CALLBACK( void, onDragDropped, () );
320      DECLARE_CALLBACK( void, onAddMultipleSelectionBegin, () );
321      DECLARE_CALLBACK( void, onAddMultipleSelectionEnd, () );
322      DECLARE_CALLBACK( bool, canRenameObject, ( SimObject* object ) );
323      DECLARE_CALLBACK( bool, handleRenameObject, ( const char* newName, SimObject* object ) );
324      DECLARE_CALLBACK( void, onClearSelection, () );
325
326      /// @}
327
328      ///
329      Vector<Item*> mItems;
330      Vector<Item*> mVisibleItems;
331      Vector<Item*> mSelectedItems;
332
333      /// Used for tracking stuff that was selected, but may not have been
334      /// created at time of selection.
335      Vector<S32> mSelected;
336
337      S32 mItemCount;
338
339      /// We do our own free list, as we we want to be able to recycle
340      /// item ids and do some other clever things.
341      Item* mItemFreeList;
342
343      Item* mRoot;
344      S32 mMaxWidth;
345      S32 mSelectedItem;
346      S32 mDraggedToItem;
347      S32 mStart;      
348
349      /// A combination of TreeState flags.
350      BitSet32 mFlags;
351
352      Item* mPossibleRenameItem;
353      Item* mRenamingItem;
354      Item* mTempItem;
355      GuiTextEditCtrl* mRenameCtrl;
356
357      /// Current filter that determines which items in the tree are displayed and which are hidden.
358      String mFilterText;
359
360      /// If true, all items are filtered. If false, then children of items that successfully pass filter are not filtered
361      bool mDoFilterChildren;
362
363      Vector<U32> mItemFilterExceptionList;
364      Vector<U32> mHiddenItemsList;
365
366      /// If true, a trace of actions taken by the control is logged to the console.  Can
367      /// be turned on with the setDebug() script method.
368      bool mDebug;
369
370      GFXTexHandle mIconTable[MaxIcons];
371
372      S32 mTabSize;
373      S32 mTextOffset;
374      bool mFullRowSelect;
375      S32 mItemHeight;
376      bool mDestroyOnSleep;
377      bool mSupportMouseDragging;
378      bool mMultipleSelections;
379      bool mDeleteObjectAllowed;
380      bool mDragToItemAllowed;
381      bool mClearAllOnSingleSelection;   ///< When clicking on an already selected item, clear all other selections
382      bool mCompareToObjectID;
383      
384      /// Used to hide the root tree element, defaults to true.
385      bool mShowRoot;
386      
387      /// If true, object IDs will be included in inspector tree item labels.
388      bool mShowObjectIds;
389      
390      /// If true, class names will be included in inspector tree item labels.
391      bool mShowClassNames;
392      
393      /// If true, object names will be included in inspector tree item labels.
394      bool mShowObjectNames;
395      
396      /// If true, internal names will be included in inspector tree item labels.
397      bool mShowInternalNames;
398
399      /// If true, class names will be used as object names for unnamed objects.
400      bool mShowClassNameForUnnamedObjects;
401
402      /// If true then tooltips will be automatically
403      /// generated for all Inspector items
404      bool mUseInspectorTooltips;
405
406      /// If true then only render item tooltips if the item
407      /// extends past the displayable width
408      bool mTooltipOnWidthOnly;
409
410      /// If true clicking on a selected item ( that is an object )
411      /// will allow you to rename it.
412      bool mCanRenameObjects;
413      
414      /// If true then object renaming operates on the internalName rather than
415      /// the object name.
416      bool mRenameInternal;
417      
418      S32 mCurrentDragCell;
419      S32 mPreviousDragCell;
420      S32 mDragMidPoint;
421      bool mMouseDragged;
422      bool mDragStartInSelection;
423      Point2I mMouseDownPoint;
424
425      StringTableEntry mBitmapBase;
426      GFXTexHandle mTexRollover;
427      GFXTexHandle mTexSelected;
428
429      ColorI mAltFontColor;
430      ColorI mAltFontColorHL;
431      ColorI mAltFontColorSE;
432
433      SimObjectPtr<SimObject> mRootObject;
434
435      void _destroyChildren( Item* item, Item* parent, bool deleteObjects=true);
436      void _destroyItem( Item* item, bool deleteObject=true);
437      void _destroyTree();
438
439      void _deleteItem(Item* item);
440
441      void _buildItem(Item* item, U32 tabLevel, bool bForceFullUpdate = false, bool skipFlter = false);
442
443      Item* _findItemByAmbiguousId( S32 itemOrObjectId, bool buildVirtual = true );
444
445      void _expandObjectHierarchy( SimGroup* group );
446
447      bool _hitTest(const Point2I & pnt, Item* & item, BitSet32 & flags);
448
449      S32 getInspectorItemIconsWidth(Item* & item);
450
451      virtual bool onVirtualParentBuild(Item *item, bool bForceFullUpdate = false);
452      virtual bool onVirtualParentExpand(Item *item);
453      virtual bool onVirtualParentCollapse(Item *item);
454      virtual void onItemSelected( Item *item );
455      virtual void onRemoveSelection( Item *item );
456      virtual void onClearSelection() {};
457
458      Item* addInspectorDataItem(Item *parent, SimObject *obj);
459      
460      virtual bool isValidDragTarget( Item* item );
461      
462      bool _isRootLevelItem( Item* item ) const
463      {
464         return ( item == mRoot && mShowRoot ) || ( item->mParent == mRoot && !mShowRoot );
465      }
466
467      /// For inspector tree views, this is hooked to the SetModificationSignal of sets
468      /// so that the tree view knows when it needs to refresh.
469      void _onInspectorSetObjectModified( SetModification modification, SimSet* set, SimObject* object );
470
471   public:
472      GuiTreeViewCtrl();
473      virtual ~GuiTreeViewCtrl();
474
475      //WLE Vince, Moving this into a function so I don't have to bounce off the console.  12/05/2013
476      const char* getSelectedObjectList();
477
478      /// Used for syncing the mSelected and mSelectedItems lists.
479      void syncSelection();
480
481      void lockSelection(bool lock);
482      void hideSelection(bool hide);
483      void toggleLockSelection();
484      void toggleHideSelection();
485      virtual bool canAddSelection( Item *item ) { return true; };
486      void addSelection(S32 itemId, bool update = true, bool isLastSelection = true);
487      const Vector< Item*>& getSelectedItems() const { return mSelectedItems; }
488      const Vector< S32>& getSelected() const { return mSelected; }
489
490      const Vector< Item*>& getItems() const { return mItems; }
491
492      bool isSelected(S32 itemId)
493      {
494         return isSelected( getItem( itemId ) );
495      }
496      bool isSelected(Item *item)
497      {
498         if ( !item )
499            return false;
500         return mSelectedItems.contains( item );   
501      }
502
503      void setDebug( bool value ) { mDebug = value; }
504
505      /// Should use addSelection and removeSelection when calling from script
506      /// instead of setItemSelected. Use setItemSelected when you want to select
507      /// something in the treeview as it has script call backs.
508      void removeSelection(S32 itemId);
509
510      /// Sets the flag of the item with the matching itemId.
511      bool setItemSelected(S32 itemId, bool select);
512      bool setItemExpanded(S32 itemId, bool expand);
513      bool setItemValue(S32 itemId, StringTableEntry Value);
514
515      const char * getItemText(S32 itemId);
516      const char * getItemValue(S32 itemId);
517      StringTableEntry getTextToRoot(S32 itemId, const char *delimiter = "");
518
519      Item* getRootItem() const { return mRoot; }
520      Item * getItem(S32 itemId) const;
521      Item * createItem(S32 icon);
522      bool editItem( S32 itemId, const char* newText, const char* newValue );
523
524      bool markItem( S32 itemId, bool mark );
525
526      S32 getItemAtPosition(Point2I position);
527      
528      bool isItemSelected( S32 itemId );
529
530      // insertion/removal
531      void unlinkItem(Item * item);
532      S32 insertItem(S32 parentId, const char * text, const char * value = "", const char * iconString = "", S16 normalImage = 0, S16 expandedImage = 1);
533      bool removeItem(S32 itemId, bool deleteObjects=true);
534      void removeAllChildren(S32 itemId); // Remove all children of the given item
535
536      bool buildIconTable(const char * icons);
537
538      bool setAddGroup(SimObject * obj);
539
540      S32 getIcon(const char * iconString);
541
542      // tree items
543      const S32 getFirstRootItem() const;
544      S32 getChildItem(S32 itemId);
545      S32 getParentItem(S32 itemId);
546      S32 getNextSiblingItem(S32 itemId);
547      S32 getPrevSiblingItem(S32 itemId);
548      S32 getItemCount();
549      S32 getSelectedItem();
550      S32 getSelectedItem(S32 index); // Given an item's index in the selection list, return its itemId
551      S32 getSelectedItemsCount() {return mSelectedItems.size();} // Returns the number of selected items
552      void moveItemUp( S32 itemId );
553      void moveItemDown( S32 itemId );
554
555      // misc.
556      bool scrollVisible( Item *item );
557      bool scrollVisible( S32 itemId );
558      bool scrollVisibleByObjectId( S32 objID );
559      
560      void deleteSelection();
561      void clearSelection();
562
563      S32 findItemByName(const char *name);
564      S32 findItemByValue(const char *name);
565      S32 findItemByObjectId(S32 iObjId);
566      S32 getItemObject(S32 itemId);
567
568      void sortTree( bool caseSensitive, bool traverseHierarchy, bool parentsFirst );
569
570      /// @name Filtering
571      /// @{
572
573      /// Get the current filter expression.  Only tree items whose text matches this expression
574      /// are displayed.  By default, the expression is empty and all items are shown.
575      const String& getFilterText() const { return mFilterText; }
576
577      /// Set the pattern by which to filter items in the tree.  Only items in the tree whose text
578      /// matches this pattern are displayed.
579      void setFilterText( const String& text );
580
581      void setFilterChildren(bool doFilter) { mDoFilterChildren = doFilter; }
582      void setItemFilterException(U32 item, bool isExempt);
583      void setItemHidden(U32 item, bool isHidden);
584      void clearHiddenItems() { mHiddenItemsList.clear(); }
585
586      /// Clear the current item filtering pattern.
587      void clearFilterText() { setFilterText( String::EmptyString ); }
588
589      void reparentItems(Vector<Item*> selectedItems, Item* newParent);
590
591      S32 getTabLevel(S32 itemId);
592
593      /// @}
594
595      // GuiControl
596      bool onAdd();
597      bool onWake();
598      void onSleep();
599      void onPreRender();
600      bool onKeyDown( const GuiEvent &event );
601      void onMouseDown(const GuiEvent &event);
602      void onMiddleMouseDown(const GuiEvent &event);
603      void onMouseMove(const GuiEvent &event);
604      void onMouseEnter(const GuiEvent &event);
605      void onMouseLeave(const GuiEvent &event);
606      void onRightMouseDown(const GuiEvent &event);
607      void onRightMouseUp(const GuiEvent &event);
608      void onMouseDragged(const GuiEvent &event);
609      virtual void onMouseUp(const GuiEvent &event);
610
611      /// Returns false if the object is a child of one of the inner items.
612      bool childSearch(Item * item, SimObject *obj, bool yourBaby);
613
614      /// Find immediately available inspector items (eg ones that aren't children of other inspector items)
615      /// and then update their sets
616      void inspectorSearch(Item * item, Item * parent, SimSet * parentSet, SimSet * newParentSet);
617
618      /// Find the Item associated with a sceneObject, returns true if it found one
619      bool objectSearch( const SimObject *object, Item **item );
620
621      // GuiArrayCtrl
622      void onRenderCell(Point2I offset, Point2I cell, bool, bool);
623      void onRender(Point2I offset, const RectI &updateRect);
624      
625      bool renderTooltip( const Point2I &hoverPos, const Point2I& cursorPos, const char* tipText );
626
627      static void initPersistFields();
628
629      void inspectObject(SimObject * obj, bool okToEdit);
630     S32 insertObject(S32 parentId, SimObject * obj, bool okToEdit);
631      void buildVisibleTree(bool bForceFullUpdate = false);
632
633      void cancelRename();
634      void onRenameValidate();
635      void showItemRenameCtrl( Item* item );
636
637      DECLARE_CONOBJECT(GuiTreeViewCtrl);
638      DECLARE_CATEGORY( "Gui Lists" );
639      DECLARE_DESCRIPTION( "Hierarchical list of text items with optional icons.\nCan also be used to inspect SimObject hierarchies." );
640};
641
642#endif
643