diff options
Diffstat (limited to 'public/dme_controls/ElementPropertiesTree.h')
| -rw-r--r-- | public/dme_controls/ElementPropertiesTree.h | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/public/dme_controls/ElementPropertiesTree.h b/public/dme_controls/ElementPropertiesTree.h new file mode 100644 index 0000000..aa4e57a --- /dev/null +++ b/public/dme_controls/ElementPropertiesTree.h @@ -0,0 +1,471 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef ELEMENTPROPERTIESTREE_H +#define ELEMENTPROPERTIESTREE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "vgui_controls/Frame.h" +#include "dme_controls/AttributeWidgetFactory.h" +#include "vgui_controls/TreeView.h" +#include "vgui_controls/TreeViewListControl.h" +#include "datamodel/dmelement.h" +#include "datamodel/dmattribute.h" +#include "datamodel/dmattributevar.h" +#include "datamodel/dmehandle.h" +#include "tier1/utlntree.h" +#include "tier1/utlstring.h" +#include "tier1/utlvector.h" +#include "vgui_controls/InputDialog.h" +#include "vgui/KeyCode.h" +#include "dme_controls/inotifyui.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CDmElement; +class IDmNotify; +class CDocAllElements; +class IAttributeWidgetFactory; +class CDmeEditorTypeDictionary; +class CPropertiesTreeToolbar; + +namespace vgui +{ + class TextEntry; + class ComboBox; + class Button; + class PanelListPanel; + class Menu; +} + +//----------------------------------------------------------------------------- +// CElementTreeViewListControl +//----------------------------------------------------------------------------- +class CElementTreeViewListControl : public vgui::CTreeViewListControl +{ + DECLARE_CLASS_SIMPLE( CElementTreeViewListControl, CTreeViewListControl ); + +public: + CElementTreeViewListControl( Panel *pParent, const char *pName ); + + virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); + virtual int AddItem( KeyValues *data, bool allowLabelEditing, int parentItemIndex, CUtlVector< vgui::Panel * >& columnPanels ); + virtual void RemoveItem( int nItemIndex ); + virtual void PerformLayout(); + virtual void RemoveAll(); + virtual vgui::HFont GetFont( int size ); + virtual void SetFont( vgui::HFont font ); + virtual int GetFontSize(); + virtual void SetFontSize( int size ); + virtual void PostChildPaint(); + virtual void ExpandItem( int itemIndex, bool bExpand ); + virtual bool IsItemExpanded( int itemIndex ); + virtual bool IsItemSelected( int itemIndex ); + virtual KeyValues *GetItemData( int itemIndex ); + virtual int GetTreeColumnWidth(); + virtual void SetTreeColumnWidth( int w ); + virtual void OnCursorMoved( int x, int y ); + virtual void OnMousePressed( vgui::MouseCode code ); + virtual void OnMouseReleased( vgui::MouseCode code ); + virtual void OnMouseDoublePressed( vgui::MouseCode code ); + virtual void OnMouseWheeled( int delta ); + virtual int GetScrollBarSize(); + virtual void ToggleDrawGrid(); + virtual bool IsDrawingGrid(); + + void ResizeTreeToExpandedWidth(); + +private: + struct ColumnPanels_t + { + ColumnPanels_t() : + treeViewItem( -1 ) + { + } + + ColumnPanels_t( const ColumnPanels_t& src ) + { + treeViewItem = src.treeViewItem; + int i, c; + c = src.m_Columns.Count(); + for ( i = 0; i < c; ++i ) + { + m_Columns.AddToTail( src.m_Columns[ i ] ); + } + } + + void SetList( CUtlVector< vgui::Panel * >& list ) + { + m_Columns.RemoveAll(); + int c = list.Count(); + for ( int i = 0; i < c; ++i ) + { + m_Columns.AddToTail( list[ i ] ); + } + } + + int treeViewItem; + CUtlVector< vgui::Panel * > m_Columns; + }; + + // Removes an item from the tree recursively + void RemoveItem_R( int nItemIndex ); + + void HideAll(); + + static bool PanelsLessFunc( const ColumnPanels_t& lhs, const ColumnPanels_t& rhs ) + { + return lhs.treeViewItem < rhs.treeViewItem; + } + + int m_iTreeColumnWidth; + int m_iFontSize; // 1 = verySmall, small, normal, large, verylarge + bool m_bMouseLeftIsDown; + bool m_bMouseIsDragging; + bool m_bDrawGrid; + CUtlRBTree< ColumnPanels_t, int > m_Panels; +}; + +//----------------------------------------------------------------------------- +// CElementPropertiesTreeInternal +//----------------------------------------------------------------------------- +class CElementPropertiesTreeInternal : public vgui::EditablePanel +{ + DECLARE_CLASS_SIMPLE( CElementPropertiesTreeInternal, vgui::EditablePanel ); + +public: + enum RefreshType_t + { + REFRESH_REBUILD = 0, // Close the entire tree + REFRESH_VALUES_ONLY, // Tree topology hasn't changed; only update values + REFRESH_TREE_VIEW, // Tree topology changed; some attributes may be added or removed + }; + + CElementPropertiesTreeInternal( vgui::Panel *parent, IDmNotify *pNotify, + CDmElement *pObject, bool autoApply = true, CDmeEditorTypeDictionary *pDict = NULL ); + ~CElementPropertiesTreeInternal(); + + virtual void Init( ); + virtual void Refresh( RefreshType_t rebuild = REFRESH_TREE_VIEW, bool preservePrevSelectedItem = false ); + virtual void ApplyChanges(); + virtual void GenerateChildrenOfNode( int itemIndex ); + virtual void GenerateContextMenu( int itemIndex, int x, int y ); + virtual void GenerateDragDataForItem( int itemIndex, KeyValues *msg ); + virtual void OnLabelChanged( int itemIndex, char const *oldString, char const *newString ); + virtual bool IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist ); + virtual void OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist ); + virtual bool GetItemDropContextMenu( int itemIndex, vgui::Menu *menu, CUtlVector< KeyValues * >& msglist ); + virtual vgui::HCursor GetItemDropCursor( int itemIndex, CUtlVector< KeyValues * >& msglist ); + virtual void SetObject( CDmElement *object ); + virtual void OnCommand( const char *cmd ); + + MESSAGE_FUNC( OnShowMemoryUsage, "OnShowMemoryUsage" ); + + CDmElement *GetObject(); + bool IsLabelBeingEdited() const; + bool HasItemsSelected() const; + + enum + { + DME_PROPERTIESTREE_MENU_BACKWARD = 0, + DME_PROPERTIESTREE_MENU_FORWARD, + DME_PROPERTIESTREE_MENU_SEARCHHSITORY, + }; + + virtual void PopulateHistoryMenu( int whichMenu, vgui::Menu *menu ); + virtual int GetHistoryMenuItemCount( int whichMenu ); + void AddToSearchHistory( char const *str ); + void SetTypeDictionary( CDmeEditorTypeDictionary *pDict ); + + MESSAGE_FUNC_CHARPTR( OnNavSearch, "OnNavigateSearch", text ); + +protected: + KeyValues *GetTreeItemData( int itemIndex ); + +protected: + + struct AttributeWidgets_t + { + vgui::Panel *m_pValueWidget; + + bool operator==( const AttributeWidgets_t &src ) const + { + return m_pValueWidget == src.m_pValueWidget; + } + }; + + enum + { + EP_EXPANDED = (1<<0), + EP_SELECTED = (1<<1), + }; + + struct TreeItem_t + { + TreeItem_t() : + m_pElement( 0 ), + m_pAttributeName(), + m_pArrayElement( 0 ) + { + } + CDmElement *m_pElement; + CUtlString m_pAttributeName; + CDmElement *m_pArrayElement; // points to the element referenced in an element array + }; + + // Used to build a list of open element for refresh + struct TreeInfo_t + { + TreeInfo_t() : + m_nFlags( 0 ) + { + } + + TreeItem_t m_Item; // points to the element referenced in an element array + + int m_nFlags; + TreeItem_t m_Preserved; + }; + + typedef CUtlNTree< TreeInfo_t, int > OpenItemTree_t; + + struct SearchResult_t + { + CDmeHandle< CDmElement > handle; + CUtlString attributeName; + + bool operator == ( const SearchResult_t &other ) const + { + if ( &other == this ) + return true; + + if ( other.handle != handle ) + return false; + if ( other.attributeName != attributeName ) + return false; + + return true; + } + }; + + bool BuildExpansionListToFindElement_R( CUtlRBTree< CDmElement *, int >& visited, int depth, SearchResult_t& sr, CDmElement *owner, CDmElement *element, char const *attributeName, int arrayIndex, CUtlVector< int >& expandIndices ); + void FindMatchingElements_R( CUtlRBTree< CDmElement *, int >& visited, char const *searchstr, CDmElement *root, CUtlVector< SearchResult_t >& list ); + void NavigateToSearchResult(); + + void SpewOpenItems( int depth, OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex ); + + // Finds the tree index of a child matching the particular element + attribute + int FindTreeItem( int nParentIndex, const TreeItem_t &info ); + + // Expands all items in the open item tree if they exist + void ExpandOpenItems( OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex, bool makeVisible ); + + // Builds a list of open items + void BuildOpenItemList( OpenItemTree_t &tree, int nParent, int nItemIndex, bool preservePrevSelectedItem ); + + void FillInDataForItem( TreeItem_t &item, int nItemIndex ); + + // Removes an item from the tree + void RemoveItem( int nItemIndex ); + + // Removes an item recursively + void RemoveItem_R( int nItemIndex ); + + // Adds a single entry into the tree + void CreateTreeEntry( int parentNodeIndex, CDmElement* obj, CDmAttribute *pAttribute, int nArrayIndex, AttributeWidgets_t &entry ); + + // Sets up the attribute widget init info for a particular attribute + void SetupWidgetInfo( AttributeWidgetInfo_t *pInfo, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 ); + + // Creates an attribute data widget using a specifically requested widget + vgui::Panel *CreateAttributeDataWidget( CDmElement *pElement, const char *pWidgetName, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 ); + + void UpdateTree(); + void InsertAttributes( int parentNodeIndex, CDmElement *obj ); + void InsertAttributeArrayMembers( int parentNodeIndex, CDmElement *obj, CDmAttribute *array ); + + // Adds a single editable attribute of the element to the tree + void InsertSingleAttribute( int parentNodeIndex, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 ); + + // Refreshes the tree view + void RefreshTreeView( bool preservePrevSelectedItem = false ); + + // Gets tree view text + void GetTreeViewText( CDmElement* obj, CDmAttribute *pAttribute, int nArrayIndex, char *pBuffer, int nMaxLen, bool& editableText ); + + void RemoveSelected( bool selectLeft ); + + void AddToHistory( CDmElement *element ); + + void ValidateHistory(); + void SpewHistory(); + void JumpToHistoryItem(); + + void UpdateButtonState(); + + KEYBINDING_FUNC( ondelete, KEY_DELETE, 0, OnKeyDelete, "#elementpropertiestree_ondelete_help", 0 ); + KEYBINDING_FUNC( onbackspace, KEY_BACKSPACE, 0, OnKeyBackspace, "#elementpropertiestree_ondelete_help", 0 ); + KEYBINDING_FUNC( onrefresh, KEY_F5, 0, OnRefresh, "#elementpropertiestree_onrefresh_help", 0 ); + + MESSAGE_FUNC( OnRename, "OnRename" ); + MESSAGE_FUNC( OnRemove, "OnRemove" ); + MESSAGE_FUNC( OnClear, "OnClear" ); + MESSAGE_FUNC( OnSortByName, "OnSortByName" ); + + MESSAGE_FUNC( OnCut, "OnCut" ); + MESSAGE_FUNC( OnCopy, "OnCopy" ); + MESSAGE_FUNC( OnPaste, "OnPaste" ); + MESSAGE_FUNC( OnPasteReference, "OnPasteReference" ); + MESSAGE_FUNC( OnPasteInsert, "OnPasteInsert" ); + MESSAGE_FUNC( OnDeleteSelected, "OnDelete" ); + + MESSAGE_FUNC_INT( OnElementChangedExternally, "ElementChangedExternally", valuesOnly ); + MESSAGE_FUNC_INT( OnNavBack, "OnNavigateBack", item ); + MESSAGE_FUNC_INT( OnNavForward, "OnNavigateForward", item ); + MESSAGE_FUNC_INT( OnNavigateSearchAgain, "OnNavigateSearchAgain", direction ); + MESSAGE_FUNC( OnShowSearchResults, "OnShowSearchResults" ); + +protected: + + MESSAGE_FUNC_PARAMS( OnInputCompleted, "InputCompleted", params ); + MESSAGE_FUNC( OnAddItem, "OnAddItem" ); + + MESSAGE_FUNC_PARAMS( OnSetShared, "OnSetShared", pParams ); + + MESSAGE_FUNC_PARAMS( OnChangeFile, "OnChangeFile", pParams ); + + MESSAGE_FUNC_PARAMS( OnShowFileDialog, "OnShowFileDialog", pParams ); + MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", params ); + + enum DropOperation_t + { + DO_MOVE, + DO_LINK, + DO_COPY, + DO_UNKNOWN, + }; + + DropOperation_t GetDropOperation( int itemIndex, CUtlVector< KeyValues * >& msglist ); + + void DropItemsIntoArray( CDmrElementArray<> &array, + CUtlVector< KeyValues* > &msglist, + CUtlVector< CDmElement* > &list, + int nArrayIndex, DropOperation_t op ); + + bool OnRemoveFromData( CUtlVector< KeyValues * >& list ); + bool OnRemoveFromData( KeyValues *item ); + void OnPaste_( bool reference ); + bool ShowAddAttributeDialog( CDmElement *pElement, const char *pAttributeType ); + void AddAttribute( const char *pAttributeName, KeyValues *pContext ); + bool ShowSetElementAttributeDialog( CDmElement *pOwner, const char *pAttributeName, int nArrayItem, const char *pElementType ); + void SetElementAttribute( const char *pElementName, KeyValues *pContext ); + void OnImportElement( const char *pFullPath, KeyValues *pContext ); + void OnExportElement( const char *pFullPath, KeyValues *pContext ); + + void GetPathToItem( CUtlVector< TreeItem_t > &path, int itemIndex ); + int OpenPath( const CUtlVector< TreeItem_t > &path ); + + // Refreshes the color state of the tree + void RefreshTreeItemState( int nItemID ); + + // Refreshes the color state of the tree + void SetTreeItemColor( int nItemID, CDmElement *pEntryElement, bool bIsElementArrayItem, bool bEditableLabel ); + + CDmeHandle< CDmeEditorTypeDictionary > m_hTypeDictionary; + CUtlVector< AttributeWidgets_t > m_AttributeWidgets; + IDmNotify *m_pNotify; + CDmeHandle< CDmElement > m_hObject; + CElementTreeViewListControl *m_pTree; + bool m_bAutoApply; + bool m_bShowMemoryUsage; + vgui::DHANDLE< vgui::Menu > m_hContextMenu; + + CPropertiesTreeToolbar *m_pToolBar; // Forward/backward navigation and search fields + + enum + { + DME_PROPERTIESTREE_MAXHISTORYITEMS = 32, + DME_PROPERTIESTREE_MAXSEARCHHISTORYITEMS = 32, + }; + + // Most recent are at the head + CUtlVector< CDmeHandle< CDmElement > > m_hHistory; + int m_nCurrentHistoryPosition; + bool m_bSuppressHistoryUpdates; + char m_szSearchStr[ 128 ]; + + CUtlVector< SearchResult_t > m_SearchResults; + int m_nCurrentSearchResult; + + CUtlVector< CUtlString > m_SearchHistory; + + CDmeHandle< CDmElement > m_SearchResultsRoot; + + vgui::HCursor m_hDragCopyCursor; + vgui::HCursor m_hDragLinkCursor; + vgui::HCursor m_hDragMoveCursor; +}; + + +//----------------------------------------------------------------------------- +// CElementPropertiesTree +//----------------------------------------------------------------------------- +class CElementPropertiesTree : public vgui::Frame +{ + DECLARE_CLASS_SIMPLE( CElementPropertiesTree, vgui::Frame ); +public: + + CElementPropertiesTree( vgui::Panel *parent, IDmNotify *pNotify, CDmElement *pObject, CDmeEditorTypeDictionary *pDict = NULL ); + + virtual void Init( ); + virtual void Refresh( CElementPropertiesTreeInternal::RefreshType_t rebuild = CElementPropertiesTreeInternal::REFRESH_REBUILD, bool preservePrevSelectedItem = false ); + virtual void GenerateChildrenOfNode( int itemIndex ); + virtual void SetObject( CDmElement *object ); + virtual void OnCommand( const char *cmd ); + virtual void ActivateBuildMode(); + + CElementPropertiesTreeInternal *GetInternal(); + +protected: + CElementPropertiesTreeInternal *m_pProperties; + vgui::Button *m_pOK; + vgui::Button *m_pApply; + vgui::Button *m_pCancel; +}; + + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline CElementPropertiesTreeInternal *CElementPropertiesTree::GetInternal() +{ + return m_pProperties; +} + + +//----------------------------------------------------------------------------- +// Wrapper panel to hook into DmePanels +//----------------------------------------------------------------------------- +class CDmeElementPanel : public CElementPropertiesTreeInternal, public IDmNotify +{ + DECLARE_CLASS_SIMPLE( CDmeElementPanel, CElementPropertiesTreeInternal ); + +public: + CDmeElementPanel( vgui::Panel *pParent, const char *pPanelName ); + + void SetDmeElement( CDmElement *pElement ); + + // Inherited from IDmNotify + virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ); +}; + +#endif // ELEMENTPROPERTIESTREE_H |