123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _GUI_TREEVIEWCTRL_H
- #define _GUI_TREEVIEWCTRL_H
- #include "core/bitSet.h"
- #include "math/mRect.h"
- #include "gfx/gFont.h"
- #include "gui/core/guiControl.h"
- #include "gui/core/guiArrayCtrl.h"
- class GuiTextEditCtrl;
- //------------------------------------------------------------------------------
- class GuiTreeViewCtrl : public GuiArrayCtrl
- {
- private:
- typedef GuiArrayCtrl Parent;
- public:
- /// @section GuiControl_Intro Introduction
- /// @nosubgrouping
- ///
- class Item
- {
- public:
- enum ItemState
- {
- Selected = BIT( 0 ),
- Expanded = BIT( 1 ),
- Marked = BIT( 2 ), ///< Marked items are drawn with a border around them. This is
- /// different than "Selected" because it can only be set by script.
- Filtered = BIT( 3 ), ///< Whether the item is currently filtered out.
- MouseOverBmp = BIT( 4 ),
- MouseOverText = BIT( 5 ),
- MouseOverIcon = BIT( 6 ),
- InspectorData = BIT( 7 ), ///< Set if we're representing some inspector
- /// info (ie, use mInspectorInfo, not mScriptInfo)
- VirtualParent = BIT( 8 ), ///< This indicates that we should be rendered as
- /// a parent even though we don't have any children.
- /// This is useful for preventing scenarios where
- /// we might want to create thousands of
- /// Items that might never be shown (for instance
- /// if we're browsing the object hierarchy in
- /// Torque, which might have thousands of objects).
- RebuildVisited = BIT( 9 ), ///< Rebuild traversal for virtual parents has visited and validated this item.
-
- ShowObjectId = BIT( 10 ),
- ShowClassName = BIT( 11 ),
- ShowObjectName = BIT( 12 ),
- ShowInternalName = BIT( 13 ),
- ShowClassNameForUnnamed = BIT( 14 ),
- ForceItemName = BIT(15),
- ForceDragTarget = BIT(16),
- DenyDrag = BIT(17),
- };
- GuiTreeViewCtrl* mParentControl;
- BitSet32 mState;
- SimObjectPtr< GuiControlProfile > mProfile;
- S16 mId;
- U16 mTabLevel;
- Item* mParent;
- Item* mChild;
- Item* mNext;
- Item* mPrevious;
- String mTooltip;
- S32 mIcon; //stores the icon that will represent the item in the tree
- S32 mDataRenderWidth; /// this stores the pixel width needed
- /// to render the item's data in the
- /// onRenderCell function to optimize
- /// for speed.
- Item( GuiTreeViewCtrl* parent, GuiControlProfile *pProfile );
- ~Item();
- struct ScriptTag
- {
- S8 mNormalImage;
- S8 mExpandedImage;
- StringTableEntry mText;
- StringTableEntry mValue;
- } mScriptInfo;
- struct InspectorTag
- {
- SimObjectPtr<SimObject> mObject;
- } mInspectorInfo;
- /// @name Get Methods
- /// @{
- ///
- S8 getNormalImage() const;
- S8 getExpandedImage() const;
- StringTableEntry getText();
- StringTableEntry getValue();
- inline const S16 getID() const { return mId; };
- SimObject *getObject();
- U32 getDisplayTextLength();
- S32 getDisplayTextWidth(GFont *font);
- void getDisplayText(U32 bufLen, char *buf);
- bool hasObjectBasedTooltip();
- void getTooltipText(U32 bufLen, char *buf);
- /// @}
- /// @name Set Methods
- /// @{
- /// Set whether an item is expanded or not (showing children or having them hidden)
- void setExpanded( const bool f = true );
- /// Set the image to display when an item IS expanded
- void setExpandedImage(const S8 id);
- /// Set the image to display when an item is NOT expanded
- void setNormalImage(const S8 id);
- /// Assign a SimObject pointer to an inspector data item
- void setObject(SimObject *obj);
- /// Set the items displayable text (caption)
- void setText(StringTableEntry txt);
- /// Set the items script value (data)
- void setValue(StringTableEntry val);
- /// Set the items virtual parent flag
- void setVirtualParent( bool value );
- /// Set whether the item is filtered out or not.
- void setFiltered( bool value ) { mState.set( Filtered ); }
- /// @}
- /// @name State Retrieval
- /// @{
- /// Returns true if this item is expanded. For
- /// inspector objects, the expansion is stored
- /// on the SimObject, for other things we use our
- /// bit vector.
- bool isExpanded() const;
- /// Return whether the item is current filtered out or not.
- /// @note Parent items may be filtered and yet still be visible if they have
- /// children that are not filtered.
- bool isFiltered() const { return mState.test( Filtered ); }
- /// Returns true if an item is inspector data
- /// or false if it's just an item.
- bool isInspectorData() const { return mState.test(InspectorData); };
- /// Returns true if we've been manually set to allow dragging overrides.
- /// As it's a manually set flag, by default it is false.
- bool isDragTargetAllowed() const { return mState.test(ForceDragTarget); };
- /// Returns true if we've been manually set to allow dragging overrides.
- /// As it's a manually set flag, by default it is false.
- bool isDragAllowed() const { return !mState.test(DenyDrag); };
- /// Returns true if we should show the expand art
- /// and make the item interact with the mouse as if
- /// it were a parent.
- bool isParent() const;
-
- /// Return true if text label for inspector item should include internal name only.
- bool showInternalNameOnly() const { return mState.test( ShowInternalName ) && !mState.test( ShowObjectName | ShowClassName | ShowObjectId ); }
- /// Return true if text label for inspector item should include object name only.
- bool showObjectNameOnly() const { return mState.test( ShowObjectName ) && !mState.test( ShowInternalName | ShowClassName | ShowObjectId ); }
- /// @}
- /// @name Searching Methods
- /// @{
-
- /// Find a regular data item by it's script name.
- Item* findChildByName( const char* name );
- /// Find an inspector data item by it's SimObject pointer
- Item* findChildByValue(const SimObject *obj);
- /// Find a regular data item by it's script value
- Item* findChildByValue(StringTableEntry Value);
- /// @}
-
- /// Sort the childs of the item by their text.
- ///
- /// @param caseSensitive If true, sorting is case-sensitive.
- /// @param traverseHierarchy If true, also triggers a sort() on all child items.
- /// @param parentsFirst If true, parents are grouped before children in the resulting sort.
- void sort( bool caseSensitive = true, bool traverseHierarchy = false, bool parentsFirst = false );
- private:
- void _connectMonitors();
- void _disconnectMonitors();
- };
- friend class Item; // _onInspectorSetObjectModified
- /// @name Enums
- /// @{
- ///
- enum TreeState
- {
- RebuildVisible = BIT(0), ///< Temporary flag, we have to rebuild the tree.
- IsInspector = BIT(1), ///< We are mapping a SimObject hierarchy.
- IsEditable = BIT(2), ///< We allow items to be moved around.
- ShowTreeLines = BIT(3), ///< Should we render tree lines or just icons?
- BuildingVisTree = BIT(4), ///< We are currently building the visible tree (prevent recursion)
- };
- protected:
- enum
- {
- MaxIcons = 32,
- };
- enum Icons
- {
- Default1 = 0,
- SimGroup1,
- SimGroup2,
- SimGroup3,
- SimGroup4,
- Hidden,
- Lock1,
- Lock2,
- Default,
- Icon31,
- Icon32
- };
- enum mDragMidPointFlags
- {
- NomDragMidPoint,
- AbovemDragMidPoint,
- BelowmDragMidPoint
- };
- ///
- enum HitFlags
- {
- OnIndent = BIT(0),
- OnImage = BIT(1),
- OnIcon = BIT(2),
- OnText = BIT(3),
- OnRow = BIT(4),
- };
- ///
- enum BmpIndices
- {
- BmpFirstChild,
- BmpLastChild,
- BmpChild,
- BmpExp,
- BmpExpN,
- BmpExpP,
- BmpExpPN,
- BmpCon,
- BmpConN,
- BmpConP,
- BmpConPN,
- BmpLine,
- BmpGlow,
- };
- /// @}
- /// @name Callbacks
- /// @{
- DECLARE_CALLBACK( bool, onDeleteObject, ( SimObject* object ) );
- DECLARE_CALLBACK( bool, isValidDragTarget, ( S32 id, const char* value ) );
- DECLARE_CALLBACK( void, onDefineIcons, () );
- DECLARE_CALLBACK( void, onAddGroupSelected, ( SimGroup* group ) );
- DECLARE_CALLBACK( void, onAddSelection, ( S32 itemOrObjectId, bool isLastSelection ) );
- DECLARE_CALLBACK( void, onSelect, ( S32 itemOrObjectId ) );
- DECLARE_CALLBACK( void, onInspect, ( S32 itemOrObjectId ) );
- DECLARE_CALLBACK( void, onRemoveSelection, ( S32 itemOrObjectId ) );
- DECLARE_CALLBACK( void, onUnselect, ( S32 itemOrObjectId ) );
- DECLARE_CALLBACK( void, onDeleteSelection, () );
- DECLARE_CALLBACK( void, onObjectDeleteCompleted, () );
- DECLARE_CALLBACK( void, onKeyDown, ( S32 modifier, S32 keyCode ) );
- DECLARE_CALLBACK( void, onMouseUp, ( S32 hitItemId, S32 mouseClickCount ) );
- DECLARE_CALLBACK( void, onMouseDragged, () );
- DECLARE_CALLBACK( void, onRightMouseDown, ( S32 itemId, const Point2I& mousePos, SimObject* object = NULL ) );
- DECLARE_CALLBACK( void, onRightMouseUp, ( S32 itemId, const Point2I& mousePos, SimObject* object = NULL ) );
- DECLARE_CALLBACK( void, onBeginReparenting, () );
- DECLARE_CALLBACK( void, onEndReparenting, () );
- DECLARE_CALLBACK( void, onReparent, ( S32 itemOrObjectId, S32 oldParentItemOrObjectId, S32 newParentItemOrObjectId ) );
- DECLARE_CALLBACK( void, onDragDropped, () );
- DECLARE_CALLBACK( void, onAddMultipleSelectionBegin, () );
- DECLARE_CALLBACK( void, onAddMultipleSelectionEnd, () );
- DECLARE_CALLBACK( bool, canRenameObject, ( SimObject* object ) );
- DECLARE_CALLBACK( bool, handleRenameObject, ( const char* newName, SimObject* object ) );
- DECLARE_CALLBACK( void, onClearSelection, () );
- /// @}
- ///
- Vector<Item*> mItems;
- Vector<Item*> mVisibleItems;
- Vector<Item*> mSelectedItems;
- /// Used for tracking stuff that was selected, but may not have been
- /// created at time of selection.
- Vector<S32> mSelected;
- S32 mItemCount;
- /// We do our own free list, as we we want to be able to recycle
- /// item ids and do some other clever things.
- Item* mItemFreeList;
- Item* mRoot;
- S32 mMaxWidth;
- S32 mSelectedItem;
- S32 mDraggedToItem;
- S32 mStart;
- /// A combination of TreeState flags.
- BitSet32 mFlags;
- Item* mPossibleRenameItem;
- Item* mRenamingItem;
- Item* mTempItem;
- GuiTextEditCtrl* mRenameCtrl;
- /// Current filter that determines which items in the tree are displayed and which are hidden.
- String mFilterText;
- /// If true, all items are filtered. If false, then children of items that successfully pass filter are not filtered
- bool mDoFilterChildren;
- Vector<U32> mItemFilterExceptionList;
- Vector<U32> mHiddenItemsList;
- /// If true, a trace of actions taken by the control is logged to the console. Can
- /// be turned on with the setDebug() script method.
- bool mDebug;
- GFXTexHandle mIconTable[MaxIcons];
- S32 mTabSize;
- S32 mTextOffset;
- bool mFullRowSelect;
- S32 mItemHeight;
- bool mDestroyOnSleep;
- bool mSupportMouseDragging;
- bool mMultipleSelections;
- bool mDeleteObjectAllowed;
- bool mDragToItemAllowed;
- bool mClearAllOnSingleSelection; ///< When clicking on an already selected item, clear all other selections
- bool mCompareToObjectID;
-
- /// Used to hide the root tree element, defaults to true.
- bool mShowRoot;
-
- /// If true, object IDs will be included in inspector tree item labels.
- bool mShowObjectIds;
-
- /// If true, class names will be included in inspector tree item labels.
- bool mShowClassNames;
-
- /// If true, object names will be included in inspector tree item labels.
- bool mShowObjectNames;
-
- /// If true, internal names will be included in inspector tree item labels.
- bool mShowInternalNames;
- /// If true, class names will be used as object names for unnamed objects.
- bool mShowClassNameForUnnamedObjects;
- /// If true then tooltips will be automatically
- /// generated for all Inspector items
- bool mUseInspectorTooltips;
- /// If true then only render item tooltips if the item
- /// extends past the displayable width
- bool mTooltipOnWidthOnly;
- /// If true clicking on a selected item ( that is an object )
- /// will allow you to rename it.
- bool mCanRenameObjects;
-
- /// If true then object renaming operates on the internalName rather than
- /// the object name.
- bool mRenameInternal;
-
- S32 mCurrentDragCell;
- S32 mPreviousDragCell;
- S32 mDragMidPoint;
- bool mMouseDragged;
- bool mDragStartInSelection;
- Point2I mMouseDownPoint;
- StringTableEntry mBitmapBase;
- GFXTexHandle mTexRollover;
- GFXTexHandle mTexSelected;
- ColorI mAltFontColor;
- ColorI mAltFontColorHL;
- ColorI mAltFontColorSE;
- SimObjectPtr<SimObject> mRootObject;
- void _destroyChildren( Item* item, Item* parent, bool deleteObjects=true);
- void _destroyItem( Item* item, bool deleteObject=true);
- void _destroyTree();
- void _deleteItem(Item* item);
- void _buildItem(Item* item, U32 tabLevel, bool bForceFullUpdate = false, bool skipFlter = false);
- Item* _findItemByAmbiguousId( S32 itemOrObjectId, bool buildVirtual = true );
- void _expandObjectHierarchy( SimGroup* group );
- bool _hitTest(const Point2I & pnt, Item* & item, BitSet32 & flags);
- S32 getInspectorItemIconsWidth(Item* & item);
- virtual bool onVirtualParentBuild(Item *item, bool bForceFullUpdate = false);
- virtual bool onVirtualParentExpand(Item *item);
- virtual bool onVirtualParentCollapse(Item *item);
- virtual void onItemSelected( Item *item );
- virtual void onRemoveSelection( Item *item );
- virtual void onClearSelection() {};
- Item* addInspectorDataItem(Item *parent, SimObject *obj);
-
- virtual bool isValidDragTarget( Item* item );
-
- bool _isRootLevelItem( Item* item ) const
- {
- return ( item == mRoot && mShowRoot ) || ( item->mParent == mRoot && !mShowRoot );
- }
- /// For inspector tree views, this is hooked to the SetModificationSignal of sets
- /// so that the tree view knows when it needs to refresh.
- void _onInspectorSetObjectModified( SetModification modification, SimSet* set, SimObject* object );
- public:
- GuiTreeViewCtrl();
- virtual ~GuiTreeViewCtrl();
- //WLE Vince, Moving this into a function so I don't have to bounce off the console. 12/05/2013
- const char* getSelectedObjectList();
- /// Used for syncing the mSelected and mSelectedItems lists.
- void syncSelection();
- void lockSelection(bool lock);
- void hideSelection(bool hide);
- void toggleLockSelection();
- void toggleHideSelection();
- virtual bool canAddSelection( Item *item ) { return true; };
- void addSelection(S32 itemId, bool update = true, bool isLastSelection = true);
- const Vector< Item* >& getSelectedItems() const { return mSelectedItems; }
- const Vector< S32 >& getSelected() const { return mSelected; }
- const Vector< Item* >& getItems() const { return mItems; }
- bool isSelected(S32 itemId)
- {
- return isSelected( getItem( itemId ) );
- }
- bool isSelected(Item *item)
- {
- if ( !item )
- return false;
- return mSelectedItems.contains( item );
- }
- void setDebug( bool value ) { mDebug = value; }
- /// Should use addSelection and removeSelection when calling from script
- /// instead of setItemSelected. Use setItemSelected when you want to select
- /// something in the treeview as it has script call backs.
- void removeSelection(S32 itemId);
- /// Sets the flag of the item with the matching itemId.
- bool setItemSelected(S32 itemId, bool select);
- bool setItemExpanded(S32 itemId, bool expand);
- bool setItemValue(S32 itemId, StringTableEntry Value);
- const char * getItemText(S32 itemId);
- const char * getItemValue(S32 itemId);
- StringTableEntry getTextToRoot(S32 itemId, const char *delimiter = "");
- Item* getRootItem() const { return mRoot; }
- Item * getItem(S32 itemId) const;
- Item * createItem(S32 icon);
- bool editItem( S32 itemId, const char* newText, const char* newValue );
- bool markItem( S32 itemId, bool mark );
- S32 getItemAtPosition(Point2I position);
-
- bool isItemSelected( S32 itemId );
- // insertion/removal
- void unlinkItem(Item * item);
- S32 insertItem(S32 parentId, const char * text, const char * value = "", const char * iconString = "", S16 normalImage = 0, S16 expandedImage = 1);
- bool removeItem(S32 itemId, bool deleteObjects=true);
- void removeAllChildren(S32 itemId); // Remove all children of the given item
- bool buildIconTable(const char * icons);
- bool setAddGroup(SimObject * obj);
- S32 getIcon(const char * iconString);
- // tree items
- const S32 getFirstRootItem() const;
- S32 getChildItem(S32 itemId);
- S32 getParentItem(S32 itemId);
- S32 getNextSiblingItem(S32 itemId);
- S32 getPrevSiblingItem(S32 itemId);
- S32 getItemCount();
- S32 getSelectedItem();
- S32 getSelectedItem(S32 index); // Given an item's index in the selection list, return its itemId
- S32 getSelectedItemsCount() {return mSelectedItems.size();} // Returns the number of selected items
- void moveItemUp( S32 itemId );
- void moveItemDown( S32 itemId );
- // misc.
- bool scrollVisible( Item *item );
- bool scrollVisible( S32 itemId );
- bool scrollVisibleByObjectId( S32 objID );
-
- void deleteSelection();
- void clearSelection();
- S32 findItemByName(const char *name);
- S32 findItemByValue(const char *name);
- S32 findItemByObjectId(S32 iObjId);
- S32 getItemObject(S32 itemId);
- void sortTree( bool caseSensitive, bool traverseHierarchy, bool parentsFirst );
- /// @name Filtering
- /// @{
- /// Get the current filter expression. Only tree items whose text matches this expression
- /// are displayed. By default, the expression is empty and all items are shown.
- const String& getFilterText() const { return mFilterText; }
- /// Set the pattern by which to filter items in the tree. Only items in the tree whose text
- /// matches this pattern are displayed.
- void setFilterText( const String& text );
- void setFilterChildren(bool doFilter) { mDoFilterChildren = doFilter; }
- void setItemFilterException(U32 item, bool isExempt);
- void setItemHidden(U32 item, bool isHidden);
- void clearHiddenItems() { mHiddenItemsList.clear(); }
- /// Clear the current item filtering pattern.
- void clearFilterText() { setFilterText( String::EmptyString ); }
- void reparentItems(Vector<Item*> selectedItems, Item* newParent);
- S32 getTabLevel(S32 itemId);
- /// @}
- // GuiControl
- bool onAdd();
- bool onWake();
- void onSleep();
- void onPreRender();
- bool onKeyDown( const GuiEvent &event );
- void onMouseDown(const GuiEvent &event);
- void onMiddleMouseDown(const GuiEvent &event);
- void onMouseMove(const GuiEvent &event);
- void onMouseEnter(const GuiEvent &event);
- void onMouseLeave(const GuiEvent &event);
- void onRightMouseDown(const GuiEvent &event);
- void onRightMouseUp(const GuiEvent &event);
- void onMouseDragged(const GuiEvent &event);
- virtual void onMouseUp(const GuiEvent &event);
- /// Returns false if the object is a child of one of the inner items.
- bool childSearch(Item * item, SimObject *obj, bool yourBaby);
- /// Find immediately available inspector items (eg ones that aren't children of other inspector items)
- /// and then update their sets
- void inspectorSearch(Item * item, Item * parent, SimSet * parentSet, SimSet * newParentSet);
- /// Find the Item associated with a sceneObject, returns true if it found one
- bool objectSearch( const SimObject *object, Item **item );
- // GuiArrayCtrl
- void onRenderCell(Point2I offset, Point2I cell, bool, bool);
- void onRender(Point2I offset, const RectI &updateRect);
-
- bool renderTooltip( const Point2I &hoverPos, const Point2I& cursorPos, const char* tipText );
- static void initPersistFields();
- void inspectObject(SimObject * obj, bool okToEdit);
- S32 insertObject(S32 parentId, SimObject * obj, bool okToEdit);
- void buildVisibleTree(bool bForceFullUpdate = false);
- void cancelRename();
- void onRenameValidate();
- void showItemRenameCtrl( Item* item );
- DECLARE_CONOBJECT(GuiTreeViewCtrl);
- DECLARE_CATEGORY( "Gui Lists" );
- DECLARE_DESCRIPTION( "Hierarchical list of text items with optional icons.\nCan also be used to inspect SimObject hierarchies." );
- };
- #endif
|