Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
15 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #ifndef ELEMENTPROPERTIESTREE_H
  8. #define ELEMENTPROPERTIESTREE_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "vgui_controls/Frame.h"
  13. #include "dme_controls/AttributeWidgetFactory.h"
  14. #include "vgui_controls/TreeView.h"
  15. #include "vgui_controls/TreeViewListControl.h"
  16. #include "datamodel/dmelement.h"
  17. #include "datamodel/dmattribute.h"
  18. #include "datamodel/dmattributevar.h"
  19. #include "datamodel/dmehandle.h"
  20. #include "tier1/utlntree.h"
  21. #include "tier1/utlstring.h"
  22. #include "tier1/utlvector.h"
  23. #include "vgui_controls/InputDialog.h"
  24. #include "vgui/KeyCode.h"
  25. #include "dme_controls/inotifyui.h"
  26. //-----------------------------------------------------------------------------
  27. // Forward declarations
  28. //-----------------------------------------------------------------------------
  29. class CDmElement;
  30. class IDmNotify;
  31. class CDocAllElements;
  32. class IAttributeWidgetFactory;
  33. class CDmeEditorTypeDictionary;
  34. class CPropertiesTreeToolbar;
  35. namespace vgui
  36. {
  37. class TextEntry;
  38. class ComboBox;
  39. class Button;
  40. class PanelListPanel;
  41. class Menu;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // CElementTreeViewListControl
  45. //-----------------------------------------------------------------------------
  46. class CElementTreeViewListControl : public vgui::CTreeViewListControl
  47. {
  48. DECLARE_CLASS_SIMPLE( CElementTreeViewListControl, CTreeViewListControl );
  49. public:
  50. CElementTreeViewListControl( Panel *pParent, const char *pName );
  51. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  52. virtual int AddItem( KeyValues *data, bool allowLabelEditing, int parentItemIndex, CUtlVector< vgui::Panel * >& columnPanels );
  53. virtual void RemoveItem( int nItemIndex );
  54. virtual void PerformLayout();
  55. virtual void RemoveAll();
  56. virtual vgui::HFont GetFont( int size );
  57. virtual void SetFont( vgui::HFont font );
  58. virtual int GetFontSize();
  59. virtual void SetFontSize( int size );
  60. virtual void PostChildPaint();
  61. virtual void ExpandItem( int itemIndex, bool bExpand );
  62. virtual bool IsItemExpanded( int itemIndex );
  63. virtual bool IsItemSelected( int itemIndex );
  64. virtual KeyValues *GetItemData( int itemIndex );
  65. virtual int GetTreeColumnWidth();
  66. virtual void SetTreeColumnWidth( int w );
  67. virtual void OnCursorMoved( int x, int y );
  68. virtual void OnMousePressed( vgui::MouseCode code );
  69. virtual void OnMouseReleased( vgui::MouseCode code );
  70. virtual void OnMouseDoublePressed( vgui::MouseCode code );
  71. virtual void OnMouseWheeled( int delta );
  72. virtual int GetScrollBarSize();
  73. virtual void ToggleDrawGrid();
  74. virtual bool IsDrawingGrid();
  75. void ResizeTreeToExpandedWidth();
  76. private:
  77. struct ColumnPanels_t
  78. {
  79. ColumnPanels_t() :
  80. treeViewItem( -1 )
  81. {
  82. }
  83. ColumnPanels_t( const ColumnPanels_t& src )
  84. {
  85. treeViewItem = src.treeViewItem;
  86. int i, c;
  87. c = src.m_Columns.Count();
  88. for ( i = 0; i < c; ++i )
  89. {
  90. m_Columns.AddToTail( src.m_Columns[ i ] );
  91. }
  92. }
  93. void SetList( CUtlVector< vgui::Panel * >& list )
  94. {
  95. m_Columns.RemoveAll();
  96. int c = list.Count();
  97. for ( int i = 0; i < c; ++i )
  98. {
  99. m_Columns.AddToTail( list[ i ] );
  100. }
  101. }
  102. int treeViewItem;
  103. CUtlVector< vgui::Panel * > m_Columns;
  104. };
  105. // Removes an item from the tree recursively
  106. void RemoveItem_R( int nItemIndex );
  107. void HideAll();
  108. static bool PanelsLessFunc( const ColumnPanels_t& lhs, const ColumnPanels_t& rhs )
  109. {
  110. return lhs.treeViewItem < rhs.treeViewItem;
  111. }
  112. int m_iTreeColumnWidth;
  113. int m_iFontSize; // 1 = verySmall, small, normal, large, verylarge
  114. bool m_bMouseLeftIsDown;
  115. bool m_bMouseIsDragging;
  116. bool m_bDrawGrid;
  117. CUtlRBTree< ColumnPanels_t, int > m_Panels;
  118. };
  119. //-----------------------------------------------------------------------------
  120. // CElementPropertiesTreeInternal
  121. //-----------------------------------------------------------------------------
  122. class CElementPropertiesTreeInternal : public vgui::EditablePanel
  123. {
  124. DECLARE_CLASS_SIMPLE( CElementPropertiesTreeInternal, vgui::EditablePanel );
  125. public:
  126. enum RefreshType_t
  127. {
  128. REFRESH_REBUILD = 0, // Close the entire tree
  129. REFRESH_VALUES_ONLY, // Tree topology hasn't changed; only update values
  130. REFRESH_TREE_VIEW, // Tree topology changed; some attributes may be added or removed
  131. };
  132. CElementPropertiesTreeInternal( vgui::Panel *parent, IDmNotify *pNotify,
  133. CDmElement *pObject, bool autoApply = true, CDmeEditorTypeDictionary *pDict = NULL );
  134. ~CElementPropertiesTreeInternal();
  135. virtual void Init( );
  136. virtual void Refresh( RefreshType_t rebuild = REFRESH_TREE_VIEW, bool preservePrevSelectedItem = false );
  137. virtual void ApplyChanges();
  138. virtual void GenerateChildrenOfNode( int itemIndex );
  139. virtual void GenerateContextMenu( int itemIndex, int x, int y );
  140. virtual void GenerateDragDataForItem( int itemIndex, KeyValues *msg );
  141. virtual void OnLabelChanged( int itemIndex, char const *oldString, char const *newString );
  142. virtual bool IsItemDroppable( int itemIndex, CUtlVector< KeyValues * >& msglist );
  143. virtual void OnItemDropped( int itemIndex, CUtlVector< KeyValues * >& msglist );
  144. virtual bool GetItemDropContextMenu( int itemIndex, vgui::Menu *menu, CUtlVector< KeyValues * >& msglist );
  145. virtual vgui::HCursor GetItemDropCursor( int itemIndex, CUtlVector< KeyValues * >& msglist );
  146. virtual void SetObject( CDmElement *object );
  147. virtual void OnCommand( const char *cmd );
  148. MESSAGE_FUNC( OnShowMemoryUsage, "OnShowMemoryUsage" );
  149. CDmElement *GetObject();
  150. bool IsLabelBeingEdited() const;
  151. bool HasItemsSelected() const;
  152. enum
  153. {
  154. DME_PROPERTIESTREE_MENU_BACKWARD = 0,
  155. DME_PROPERTIESTREE_MENU_FORWARD,
  156. DME_PROPERTIESTREE_MENU_SEARCHHSITORY,
  157. };
  158. virtual void PopulateHistoryMenu( int whichMenu, vgui::Menu *menu );
  159. virtual int GetHistoryMenuItemCount( int whichMenu );
  160. void AddToSearchHistory( char const *str );
  161. void SetTypeDictionary( CDmeEditorTypeDictionary *pDict );
  162. MESSAGE_FUNC_CHARPTR( OnNavSearch, "OnNavigateSearch", text );
  163. protected:
  164. KeyValues *GetTreeItemData( int itemIndex );
  165. protected:
  166. struct AttributeWidgets_t
  167. {
  168. vgui::Panel *m_pValueWidget;
  169. bool operator==( const AttributeWidgets_t &src ) const
  170. {
  171. return m_pValueWidget == src.m_pValueWidget;
  172. }
  173. };
  174. enum
  175. {
  176. EP_EXPANDED = (1<<0),
  177. EP_SELECTED = (1<<1),
  178. };
  179. struct TreeItem_t
  180. {
  181. TreeItem_t() :
  182. m_pElement( 0 ),
  183. m_pAttributeName(),
  184. m_pArrayElement( 0 )
  185. {
  186. }
  187. CDmElement *m_pElement;
  188. CUtlString m_pAttributeName;
  189. CDmElement *m_pArrayElement; // points to the element referenced in an element array
  190. };
  191. // Used to build a list of open element for refresh
  192. struct TreeInfo_t
  193. {
  194. TreeInfo_t() :
  195. m_nFlags( 0 )
  196. {
  197. }
  198. TreeItem_t m_Item; // points to the element referenced in an element array
  199. int m_nFlags;
  200. TreeItem_t m_Preserved;
  201. };
  202. typedef CUtlNTree< TreeInfo_t, int > OpenItemTree_t;
  203. struct SearchResult_t
  204. {
  205. CDmeHandle< CDmElement > handle;
  206. CUtlString attributeName;
  207. bool operator == ( const SearchResult_t &other ) const
  208. {
  209. if ( &other == this )
  210. return true;
  211. if ( other.handle != handle )
  212. return false;
  213. if ( other.attributeName != attributeName )
  214. return false;
  215. return true;
  216. }
  217. };
  218. bool BuildExpansionListToFindElement_R( CUtlRBTree< CDmElement *, int >& visited, int depth, SearchResult_t& sr, CDmElement *owner, CDmElement *element, char const *attributeName, int arrayIndex, CUtlVector< int >& expandIndices );
  219. void FindMatchingElements_R( CUtlRBTree< CDmElement *, int >& visited, char const *searchstr, CDmElement *root, CUtlVector< SearchResult_t >& list );
  220. void NavigateToSearchResult();
  221. void SpewOpenItems( int depth, OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex );
  222. // Finds the tree index of a child matching the particular element + attribute
  223. int FindTreeItem( int nParentIndex, const TreeItem_t &info );
  224. // Expands all items in the open item tree if they exist
  225. void ExpandOpenItems( OpenItemTree_t &tree, int nOpenTreeIndex, int nItemIndex, bool makeVisible );
  226. // Builds a list of open items
  227. void BuildOpenItemList( OpenItemTree_t &tree, int nParent, int nItemIndex, bool preservePrevSelectedItem );
  228. void FillInDataForItem( TreeItem_t &item, int nItemIndex );
  229. // Removes an item from the tree
  230. void RemoveItem( int nItemIndex );
  231. // Removes an item recursively
  232. void RemoveItem_R( int nItemIndex );
  233. // Adds a single entry into the tree
  234. void CreateTreeEntry( int parentNodeIndex, CDmElement* obj, CDmAttribute *pAttribute, int nArrayIndex, AttributeWidgets_t &entry );
  235. // Sets up the attribute widget init info for a particular attribute
  236. void SetupWidgetInfo( AttributeWidgetInfo_t *pInfo, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 );
  237. // Creates an attribute data widget using a specifically requested widget
  238. vgui::Panel *CreateAttributeDataWidget( CDmElement *pElement, const char *pWidgetName, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 );
  239. void UpdateTree();
  240. void InsertAttributes( int parentNodeIndex, CDmElement *obj );
  241. void InsertAttributeArrayMembers( int parentNodeIndex, CDmElement *obj, CDmAttribute *array );
  242. // Adds a single editable attribute of the element to the tree
  243. void InsertSingleAttribute( int parentNodeIndex, CDmElement *obj, CDmAttribute *pAttribute, int nArrayIndex = -1 );
  244. // Refreshes the tree view
  245. void RefreshTreeView( bool preservePrevSelectedItem = false );
  246. // Gets tree view text
  247. void GetTreeViewText( CDmElement* obj, CDmAttribute *pAttribute, int nArrayIndex, char *pBuffer, int nMaxLen, bool& editableText );
  248. void RemoveSelected( bool selectLeft );
  249. void AddToHistory( CDmElement *element );
  250. void ValidateHistory();
  251. void SpewHistory();
  252. void JumpToHistoryItem();
  253. void UpdateButtonState();
  254. KEYBINDING_FUNC( ondelete, KEY_DELETE, 0, OnKeyDelete, "#elementpropertiestree_ondelete_help", 0 );
  255. KEYBINDING_FUNC( onbackspace, KEY_BACKSPACE, 0, OnKeyBackspace, "#elementpropertiestree_ondelete_help", 0 );
  256. KEYBINDING_FUNC( onrefresh, KEY_F5, 0, OnRefresh, "#elementpropertiestree_onrefresh_help", 0 );
  257. MESSAGE_FUNC( OnRename, "OnRename" );
  258. MESSAGE_FUNC( OnRemove, "OnRemove" );
  259. MESSAGE_FUNC( OnClear, "OnClear" );
  260. MESSAGE_FUNC( OnSortByName, "OnSortByName" );
  261. MESSAGE_FUNC( OnCut, "OnCut" );
  262. MESSAGE_FUNC( OnCopy, "OnCopy" );
  263. MESSAGE_FUNC( OnPaste, "OnPaste" );
  264. MESSAGE_FUNC( OnPasteReference, "OnPasteReference" );
  265. MESSAGE_FUNC( OnPasteInsert, "OnPasteInsert" );
  266. MESSAGE_FUNC( OnDeleteSelected, "OnDelete" );
  267. MESSAGE_FUNC_INT( OnElementChangedExternally, "ElementChangedExternally", valuesOnly );
  268. MESSAGE_FUNC_INT( OnNavBack, "OnNavigateBack", item );
  269. MESSAGE_FUNC_INT( OnNavForward, "OnNavigateForward", item );
  270. MESSAGE_FUNC_INT( OnNavigateSearchAgain, "OnNavigateSearchAgain", direction );
  271. MESSAGE_FUNC( OnShowSearchResults, "OnShowSearchResults" );
  272. protected:
  273. MESSAGE_FUNC_PARAMS( OnInputCompleted, "InputCompleted", params );
  274. MESSAGE_FUNC( OnAddItem, "OnAddItem" );
  275. MESSAGE_FUNC_PARAMS( OnSetShared, "OnSetShared", pParams );
  276. MESSAGE_FUNC_PARAMS( OnChangeFile, "OnChangeFile", pParams );
  277. MESSAGE_FUNC_PARAMS( OnShowFileDialog, "OnShowFileDialog", pParams );
  278. MESSAGE_FUNC_PARAMS( OnFileSelected, "FileSelected", params );
  279. enum DropOperation_t
  280. {
  281. DO_MOVE,
  282. DO_LINK,
  283. DO_COPY,
  284. DO_UNKNOWN,
  285. };
  286. DropOperation_t GetDropOperation( int itemIndex, CUtlVector< KeyValues * >& msglist );
  287. void DropItemsIntoArray( CDmrElementArray<> &array,
  288. CUtlVector< KeyValues* > &msglist,
  289. CUtlVector< CDmElement* > &list,
  290. int nArrayIndex, DropOperation_t op );
  291. bool OnRemoveFromData( CUtlVector< KeyValues * >& list );
  292. bool OnRemoveFromData( KeyValues *item );
  293. void OnPaste_( bool reference );
  294. bool ShowAddAttributeDialog( CDmElement *pElement, const char *pAttributeType );
  295. void AddAttribute( const char *pAttributeName, KeyValues *pContext );
  296. bool ShowSetElementAttributeDialog( CDmElement *pOwner, const char *pAttributeName, int nArrayItem, const char *pElementType );
  297. void SetElementAttribute( const char *pElementName, KeyValues *pContext );
  298. void OnImportElement( const char *pFullPath, KeyValues *pContext );
  299. void OnExportElement( const char *pFullPath, KeyValues *pContext );
  300. void GetPathToItem( CUtlVector< TreeItem_t > &path, int itemIndex );
  301. int OpenPath( const CUtlVector< TreeItem_t > &path );
  302. // Refreshes the color state of the tree
  303. void RefreshTreeItemState( int nItemID );
  304. // Refreshes the color state of the tree
  305. void SetTreeItemColor( int nItemID, CDmElement *pEntryElement, bool bIsElementArrayItem, bool bEditableLabel );
  306. CDmeHandle< CDmeEditorTypeDictionary > m_hTypeDictionary;
  307. CUtlVector< AttributeWidgets_t > m_AttributeWidgets;
  308. IDmNotify *m_pNotify;
  309. CDmeHandle< CDmElement > m_hObject;
  310. CElementTreeViewListControl *m_pTree;
  311. bool m_bAutoApply;
  312. bool m_bShowMemoryUsage;
  313. vgui::DHANDLE< vgui::Menu > m_hContextMenu;
  314. CPropertiesTreeToolbar *m_pToolBar; // Forward/backward navigation and search fields
  315. enum
  316. {
  317. DME_PROPERTIESTREE_MAXHISTORYITEMS = 32,
  318. DME_PROPERTIESTREE_MAXSEARCHHISTORYITEMS = 32,
  319. };
  320. // Most recent are at the head
  321. CUtlVector< CDmeHandle< CDmElement > > m_hHistory;
  322. int m_nCurrentHistoryPosition;
  323. bool m_bSuppressHistoryUpdates;
  324. char m_szSearchStr[ 128 ];
  325. CUtlVector< SearchResult_t > m_SearchResults;
  326. int m_nCurrentSearchResult;
  327. CUtlVector< CUtlString > m_SearchHistory;
  328. CDmeHandle< CDmElement > m_SearchResultsRoot;
  329. vgui::HCursor m_hDragCopyCursor;
  330. vgui::HCursor m_hDragLinkCursor;
  331. vgui::HCursor m_hDragMoveCursor;
  332. };
  333. //-----------------------------------------------------------------------------
  334. // CElementPropertiesTree
  335. //-----------------------------------------------------------------------------
  336. class CElementPropertiesTree : public vgui::Frame
  337. {
  338. DECLARE_CLASS_SIMPLE( CElementPropertiesTree, vgui::Frame );
  339. public:
  340. CElementPropertiesTree( vgui::Panel *parent, IDmNotify *pNotify, CDmElement *pObject, CDmeEditorTypeDictionary *pDict = NULL );
  341. virtual void Init( );
  342. virtual void Refresh( CElementPropertiesTreeInternal::RefreshType_t rebuild = CElementPropertiesTreeInternal::REFRESH_REBUILD, bool preservePrevSelectedItem = false );
  343. virtual void GenerateChildrenOfNode( int itemIndex );
  344. virtual void SetObject( CDmElement *object );
  345. virtual void OnCommand( const char *cmd );
  346. virtual void ActivateBuildMode();
  347. CElementPropertiesTreeInternal *GetInternal();
  348. protected:
  349. CElementPropertiesTreeInternal *m_pProperties;
  350. vgui::Button *m_pOK;
  351. vgui::Button *m_pApply;
  352. vgui::Button *m_pCancel;
  353. };
  354. //-----------------------------------------------------------------------------
  355. // Inline methods
  356. //-----------------------------------------------------------------------------
  357. inline CElementPropertiesTreeInternal *CElementPropertiesTree::GetInternal()
  358. {
  359. return m_pProperties;
  360. }
  361. //-----------------------------------------------------------------------------
  362. // Wrapper panel to hook into DmePanels
  363. //-----------------------------------------------------------------------------
  364. class CDmeElementPanel : public CElementPropertiesTreeInternal, public IDmNotify
  365. {
  366. DECLARE_CLASS_SIMPLE( CDmeElementPanel, CElementPropertiesTreeInternal );
  367. public:
  368. CDmeElementPanel( vgui::Panel *pParent, const char *pPanelName );
  369. void SetDmeElement( CDmElement *pElement );
  370. // Inherited from IDmNotify
  371. virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
  372. };
  373. #endif // ELEMENTPROPERTIESTREE_H