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.

1223 lines
35 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Act busy tool; main UI smarts class
  4. //
  5. //=============================================================================
  6. #include "toolutils/basetoolsystem.h"
  7. #include "toolutils/recentfilelist.h"
  8. #include "toolutils/toolmenubar.h"
  9. #include "toolutils/toolswitchmenubutton.h"
  10. #include "toolutils/toolfilemenubutton.h"
  11. #include "toolutils/tooleditmenubutton.h"
  12. #include "toolutils/toolmenubutton.h"
  13. #include "vgui_controls/Menu.h"
  14. #include "tier1/KeyValues.h"
  15. #include "toolutils/enginetools_int.h"
  16. #include "toolframework/ienginetool.h"
  17. #include "vgui/IInput.h"
  18. #include "vgui/KeyCode.h"
  19. #include "vgui_controls/FileOpenDialog.h"
  20. #include "filesystem.h"
  21. #include "actbusydoc.h"
  22. #include "vgui/ilocalize.h"
  23. #include "dme_controls/elementpropertiestree.h"
  24. #include "actbusytool.h"
  25. #include "movieobjects/dmeeditortypedictionary.h"
  26. #include "dme_controls/attributestringchoicepanel.h"
  27. #include "matsys_controls/mdlsequencepicker.h"
  28. #include "istudiorender.h"
  29. #include "materialsystem/imaterialsystem.h"
  30. #include "VGuiMatSurface/IMatSystemSurface.h"
  31. #include "toolutils/toolwindowfactory.h"
  32. #include "toolutils/basepropertiescontainer.h"
  33. #include "toolutils/savewindowpositions.h"
  34. #include "tier2/fileutils.h"
  35. #include "tier3/tier3.h"
  36. #include "vgui/ivgui.h"
  37. using namespace vgui;
  38. //-----------------------------------------------------------------------------
  39. // Singleton interfaces
  40. //-----------------------------------------------------------------------------
  41. CDmeEditorTypeDictionary *g_pEditorTypeDict;
  42. //-----------------------------------------------------------------------------
  43. // Methods needed by scenedatabase. They have to live here instead of toolutils
  44. // because this is a DLL but toolutils is only a static library
  45. //-----------------------------------------------------------------------------
  46. const char *GetVGuiControlsModuleName()
  47. {
  48. return "ActBusyTool";
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Connect, disconnect
  52. //-----------------------------------------------------------------------------
  53. bool ConnectTools( CreateInterfaceFn factory )
  54. {
  55. return (g_pMDLCache != NULL) && (studiorender != NULL) && (materials != NULL) && (g_pMatSystemSurface != NULL);
  56. }
  57. void DisconnectTools( )
  58. {
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Implementation of the act busy tool
  62. //-----------------------------------------------------------------------------
  63. class CActBusyTool : public CBaseToolSystem, public IFileMenuCallbacks, public IActBusyDocCallback
  64. {
  65. DECLARE_CLASS_SIMPLE( CActBusyTool, CBaseToolSystem );
  66. public:
  67. CActBusyTool();
  68. // Inherited from IToolSystem
  69. virtual const char *GetToolName() { return "ActBusy Script Editor"; }
  70. virtual const char *GetBindingsContextFile() { return "cfg/ActBusy.kb"; }
  71. virtual bool Init();
  72. virtual void Shutdown();
  73. virtual bool CanQuit();
  74. // Inherited from IFileMenuCallbacks
  75. virtual int GetFileMenuItemsEnabled( );
  76. virtual void AddRecentFilesToMenu( vgui::Menu *menu );
  77. virtual bool GetPerforceFileName( char *pFileName, int nMaxLen );
  78. virtual vgui::Panel* GetRootPanel() { return this; }
  79. // Inherited from IActBusyDocCallback
  80. virtual void OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags );
  81. // Inherited from CBaseToolSystem
  82. virtual vgui::HScheme GetToolScheme();
  83. virtual vgui::Menu *CreateActionMenu( vgui::Panel *pParent );
  84. virtual void OnCommand( const char *cmd );
  85. virtual const char *GetRegistryName() { return "ActBusy"; }
  86. virtual vgui::MenuBar *CreateMenuBar( CBaseToolSystem *pParent );
  87. virtual void OnToolActivate();
  88. virtual void OnToolDeactivate();
  89. virtual CActBusyDoc *GetDocument();
  90. virtual CBasePropertiesContainer *GetProperties();
  91. virtual CMDLSequencePicker *GetSequencePicker();
  92. virtual void SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues );
  93. virtual bool OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
  94. virtual bool OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
  95. virtual void OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues );
  96. public:
  97. // Commands related to the file menu
  98. MESSAGE_FUNC( OnNew, "OnNew" );
  99. MESSAGE_FUNC( OnOpen, "OnOpen" );
  100. MESSAGE_FUNC( OnSave, "OnSave" );
  101. MESSAGE_FUNC( OnSaveAs, "OnSaveAs" );
  102. MESSAGE_FUNC( OnClose, "OnClose" );
  103. MESSAGE_FUNC( OnCloseNoSave, "OnCloseNoSave" );
  104. MESSAGE_FUNC( OnMarkNotDirty, "OnMarkNotDirty" );
  105. MESSAGE_FUNC( OnExit, "OnExit" );
  106. void PerformNew();
  107. void OpenFileFromHistory( int slot, const char *pCommand );
  108. void OpenSpecificFile( const char *pFileName );
  109. // Commands related to the edit menu
  110. KEYBINDING_FUNC( undo, KEY_Z, vgui::MODIFIER_CONTROL, OnUndo, "#undo_help", 0 );
  111. KEYBINDING_FUNC( redo, KEY_Z, vgui::MODIFIER_CONTROL | vgui::MODIFIER_SHIFT, OnRedo, "#redo_help", 0 );
  112. void OnDescribeUndo();
  113. // Commands related to the actbusy menu
  114. void OnNewActBusy();
  115. void OnDeleteActBusy();
  116. private:
  117. // Flags for HideStandardFields
  118. enum EditorTypeStandardFields_t
  119. {
  120. EDITOR_FIELD_NAME = 0x1,
  121. EDITOR_FIELD_TYPE = 0x2,
  122. EDITOR_FIELD_ID = 0x4,
  123. EDITOR_FIELD_EDITORTYPE = 0x8,
  124. };
  125. void HideStandardFields( CDmeEditorType *pEditorType, int nFieldFlags );
  126. // Creates a new document
  127. void NewDocument( );
  128. // Loads up a new document
  129. bool LoadDocument( const char *pDocName );
  130. // Updates the menu bar based on the current file
  131. void UpdateMenuBar( );
  132. // Shows element properties
  133. void ShowElementProperties( );
  134. // Create custom editors
  135. void InitEditorDict();
  136. void CreateTools( CActBusyDoc *doc );
  137. void InitTools();
  138. void DestroyTools();
  139. void ToggleToolWindow( Panel *tool, const char *toolName );
  140. void ShowToolWindow( Panel *tool, const char *toolName, bool visible );
  141. void OnToggleProperties();
  142. void OnToggleSequencePicker();
  143. void OnDefaultLayout();
  144. void DestroyToolContainers();
  145. virtual const char *GetLogoTextureName();
  146. private:
  147. // All editable data
  148. CActBusyDoc *m_pDoc;
  149. // The menu bar
  150. CToolFileMenuBar *m_pMenuBar;
  151. // Element properties for editing actbusy
  152. vgui::DHANDLE< CBasePropertiesContainer > m_hProperties;
  153. // The sequence picker!
  154. vgui::DHANDLE< CMDLSequencePicker > m_hMDLSequencePicker;
  155. CToolWindowFactory< ToolWindow > m_ToolWindowFactory;
  156. CUtlVector< DmElementHandle_t > m_toolElements;
  157. };
  158. //-----------------------------------------------------------------------------
  159. // Singleton
  160. //-----------------------------------------------------------------------------
  161. CActBusyTool *g_pActBusyTool = NULL;
  162. void CreateTools()
  163. {
  164. g_pActBusyTool = new CActBusyTool();
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Constructor
  168. //-----------------------------------------------------------------------------
  169. CActBusyTool::CActBusyTool()
  170. {
  171. m_pMenuBar = NULL;
  172. m_pDoc = NULL;
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Init, shutdown
  176. //-----------------------------------------------------------------------------
  177. bool CActBusyTool::Init( )
  178. {
  179. m_pDoc = NULL;
  180. m_RecentFiles.LoadFromRegistry( GetRegistryName() );
  181. // NOTE: This has to happen before BaseClass::Init
  182. g_pVGuiLocalize->AddFile( "resource/toolactbusy_%language%.txt" );
  183. if ( !BaseClass::Init( ) )
  184. return false;
  185. g_pDataModel->SetUndoDepth( 256 );
  186. InitEditorDict();
  187. return true;
  188. }
  189. void CActBusyTool::Shutdown()
  190. {
  191. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  192. {
  193. CDisableUndoScopeGuard guard;
  194. int nElements = m_toolElements.Count();
  195. for ( int i = 0; i < nElements; ++i )
  196. {
  197. g_pDataModel->DestroyElement( m_toolElements[ i ] );
  198. }
  199. }
  200. BaseClass::Shutdown();
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Tool activation/deactivation
  204. //-----------------------------------------------------------------------------
  205. void CActBusyTool::OnToolActivate()
  206. {
  207. BaseClass::OnToolActivate();
  208. }
  209. void CActBusyTool::OnToolDeactivate()
  210. {
  211. BaseClass::OnToolDeactivate();
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Hides standard fields
  215. //-----------------------------------------------------------------------------
  216. void CActBusyTool::HideStandardFields( CDmeEditorType *pEditorType, int nFieldFlags )
  217. {
  218. CDmeEditorAttributeInfo *pInfo;
  219. if ( nFieldFlags & EDITOR_FIELD_NAME )
  220. {
  221. pInfo = CreateElement< CDmeEditorAttributeInfo >( "name info", DMFILEID_INVALID );
  222. pInfo->m_bIsVisible = false;
  223. pEditorType->AddAttributeInfo( "name", pInfo );
  224. m_toolElements.AddToTail( pInfo->GetHandle() );
  225. }
  226. if ( nFieldFlags & EDITOR_FIELD_TYPE )
  227. {
  228. pInfo = CreateElement< CDmeEditorAttributeInfo >( "type info", DMFILEID_INVALID );
  229. pInfo->m_bIsVisible = false;
  230. pEditorType->AddAttributeInfo( "type", pInfo );
  231. m_toolElements.AddToTail( pInfo->GetHandle() );
  232. }
  233. if ( nFieldFlags & EDITOR_FIELD_ID )
  234. {
  235. pInfo = CreateElement< CDmeEditorAttributeInfo >( "id info", DMFILEID_INVALID );
  236. pInfo->m_bIsVisible = false;
  237. pEditorType->AddAttributeInfo( "id", pInfo );
  238. m_toolElements.AddToTail( pInfo->GetHandle() );
  239. }
  240. if ( nFieldFlags & EDITOR_FIELD_EDITORTYPE )
  241. {
  242. pInfo = CreateElement< CDmeEditorAttributeInfo >( "editor type info", DMFILEID_INVALID );
  243. pInfo->m_bIsVisible = false;
  244. pEditorType->AddAttributeInfo( "editorType", pInfo );
  245. m_toolElements.AddToTail( pInfo->GetHandle() );
  246. }
  247. }
  248. //-----------------------------------------------------------------------------
  249. // Create custom editors
  250. //-----------------------------------------------------------------------------
  251. void CActBusyTool::InitEditorDict()
  252. {
  253. CDmeEditorAttributeInfo *pInfo, *pArrayInfo;
  254. // FIXME: This eventually will move to an .fgd-like file.
  255. g_pEditorTypeDict = CreateElement< CDmeEditorTypeDictionary >( "DmeEditorTypeDictionary", DMFILEID_INVALID );
  256. m_toolElements.AddToTail( g_pEditorTypeDict->GetHandle() );
  257. CDmeEditorType *pActBusyList = CreateElement< CDmeEditorType >( "actBusyList", DMFILEID_INVALID );
  258. HideStandardFields( pActBusyList, EDITOR_FIELD_NAME | EDITOR_FIELD_TYPE | EDITOR_FIELD_ID | EDITOR_FIELD_EDITORTYPE );
  259. g_pEditorTypeDict->AddEditorType( pActBusyList );
  260. m_toolElements.AddToTail( pActBusyList->GetHandle() );
  261. pInfo = CreateElement< CDmeEditorAttributeInfo >( "children info", DMFILEID_INVALID );
  262. pActBusyList->AddAttributeInfo( "children", pInfo );
  263. m_toolElements.AddToTail( pInfo->GetHandle() );
  264. pArrayInfo = CreateElement< CDmeEditorAttributeInfo >( "hide text info", DMFILEID_INVALID );
  265. pInfo->SetArrayInfo( pArrayInfo );
  266. pArrayInfo->SetValue( "hideText", true );
  267. m_toolElements.AddToTail( pArrayInfo->GetHandle() );
  268. CDmeEditorType *pActBusyType = CreateElement< CDmeEditorType >( "actBusy", DMFILEID_INVALID );
  269. HideStandardFields( pActBusyType, EDITOR_FIELD_TYPE | EDITOR_FIELD_ID | EDITOR_FIELD_EDITORTYPE );
  270. m_toolElements.AddToTail( pActBusyType->GetHandle() );
  271. // anims only accept activity names
  272. pInfo = CreateElement< CDmeEditorAttributeInfo >( "busy anim info", DMFILEID_INVALID );
  273. pActBusyType->AddAttributeInfo( "busy_anim", pInfo );
  274. pInfo->m_Widget = "sequencepicker";
  275. pInfo->SetValue( "texttype", "activityName" );
  276. m_toolElements.AddToTail( pInfo->GetHandle() );
  277. pInfo = CreateElement< CDmeEditorAttributeInfo >( "entry anim info", DMFILEID_INVALID );
  278. pActBusyType->AddAttributeInfo( "entry_anim", pInfo );
  279. pInfo->m_Widget = "sequencepicker";
  280. pInfo->SetValue( "texttype", "activityName" );
  281. m_toolElements.AddToTail( pInfo->GetHandle() );
  282. pInfo = CreateElement< CDmeEditorAttributeInfo >( "exit anim info", DMFILEID_INVALID );
  283. pActBusyType->AddAttributeInfo( "exit_anim", pInfo );
  284. pInfo->m_Widget = "sequencepicker";
  285. pInfo->SetValue( "texttype", "activityName" );
  286. m_toolElements.AddToTail( pInfo->GetHandle() );
  287. // sequences only accept sequence names
  288. pInfo = CreateElement< CDmeEditorAttributeInfo >( "busy sequence info", DMFILEID_INVALID );
  289. pActBusyType->AddAttributeInfo( "busy_sequence", pInfo );
  290. pInfo->m_Widget = "sequencepicker";
  291. pInfo->SetValue( "texttype", "sequenceName" );
  292. m_toolElements.AddToTail( pInfo->GetHandle() );
  293. pInfo = CreateElement< CDmeEditorAttributeInfo >( "entry sequence info", DMFILEID_INVALID );
  294. pActBusyType->AddAttributeInfo( "entry_sequence", pInfo );
  295. pInfo->m_Widget = "sequencepicker";
  296. pInfo->SetValue( "texttype", "sequenceName" );
  297. m_toolElements.AddToTail( pInfo->GetHandle() );
  298. pInfo = CreateElement< CDmeEditorAttributeInfo >( "exit sequence info", DMFILEID_INVALID );
  299. pActBusyType->AddAttributeInfo( "exit_sequence", pInfo );
  300. pInfo->m_Widget = "sequencepicker";
  301. pInfo->SetValue( "texttype", "sequenceName" );
  302. m_toolElements.AddToTail( pInfo->GetHandle() );
  303. CDmeEditorStringChoicesInfo *pChoicesInfo = CreateElement< CDmeEditorStringChoicesInfo >( "interrupts info", DMFILEID_INVALID );
  304. pActBusyType->AddAttributeInfo( "interrupts", pChoicesInfo );
  305. pChoicesInfo->m_Widget = "stringchoice";
  306. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_NONE", "No Interrupts" )->GetHandle() );
  307. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_DANGER", "Danger" )->GetHandle() );
  308. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_PLAYER", "Player" )->GetHandle() );
  309. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_AMBUSH", "Ambush" )->GetHandle() );
  310. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_COMBAT", "Combat" )->GetHandle() );
  311. m_toolElements.AddToTail( pChoicesInfo->AddChoice( "BA_INT_ZOMBIESLUMP", "Zombie Slump" )->GetHandle() );
  312. m_toolElements.AddToTail( pChoicesInfo->GetHandle() );
  313. g_pEditorTypeDict->AddEditorType( pActBusyType );
  314. }
  315. //-----------------------------------------------------------------------------
  316. //
  317. // The View menu
  318. //
  319. //-----------------------------------------------------------------------------
  320. class CActBusyViewMenuButton : public CToolMenuButton
  321. {
  322. DECLARE_CLASS_SIMPLE( CActBusyViewMenuButton, CToolMenuButton );
  323. public:
  324. CActBusyViewMenuButton( CActBusyTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget );
  325. virtual void OnShowMenu(vgui::Menu *menu);
  326. private:
  327. CActBusyTool *m_pTool;
  328. };
  329. CActBusyViewMenuButton::CActBusyViewMenuButton( CActBusyTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget )
  330. : BaseClass( parent, panelName, text, pActionSignalTarget )
  331. {
  332. m_pTool = parent;
  333. AddCheckableMenuItem( "properties", "#ActBusyProperties", new KeyValues( "Command", "command", "OnToggleProperties" ), pActionSignalTarget );
  334. AddCheckableMenuItem( "picker", "#ActBusyViewSequencePicker", new KeyValues( "Command", "command", "OnToggleSequencePicker" ), pActionSignalTarget );
  335. AddSeparator();
  336. AddMenuItem( "defaultlayout", "#ActBusyViewDefault", new KeyValues ( "Command", "command", "OnDefaultLayout"), pActionSignalTarget );
  337. SetMenu(m_pMenu);
  338. }
  339. void CActBusyViewMenuButton::OnShowMenu(vgui::Menu *menu)
  340. {
  341. BaseClass::OnShowMenu( menu );
  342. // Update the menu
  343. int id;
  344. CActBusyDoc *pDoc = m_pTool->GetDocument();
  345. if ( pDoc )
  346. {
  347. id = m_Items.Find( "properties" );
  348. m_pMenu->SetItemEnabled( id, true );
  349. Panel *p;
  350. p = m_pTool->GetProperties();
  351. Assert( p );
  352. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  353. id = m_Items.Find( "picker" );
  354. m_pMenu->SetItemEnabled( id, true );
  355. p = m_pTool->GetSequencePicker();
  356. Assert( p );
  357. m_pMenu->SetMenuItemChecked( id, ( p && p->GetParent() ) ? true : false );
  358. }
  359. else
  360. {
  361. id = m_Items.Find( "properties" );
  362. m_pMenu->SetItemEnabled( id, false );
  363. id = m_Items.Find( "picker" );
  364. m_pMenu->SetItemEnabled( id, false );
  365. }
  366. }
  367. //-----------------------------------------------------------------------------
  368. //
  369. // The ActBusy menu
  370. //
  371. //-----------------------------------------------------------------------------
  372. class CActBusyMenuButton : public CToolMenuButton
  373. {
  374. DECLARE_CLASS_SIMPLE( CActBusyMenuButton, CToolMenuButton );
  375. public:
  376. CActBusyMenuButton( CActBusyTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget );
  377. virtual void OnShowMenu(vgui::Menu *menu);
  378. private:
  379. CActBusyTool *m_pTool;
  380. };
  381. CActBusyMenuButton::CActBusyMenuButton( CActBusyTool *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget )
  382. : BaseClass( parent, panelName, text, pActionSignalTarget )
  383. {
  384. m_pTool = parent;
  385. AddMenuItem( "NewActBusy", "#ActBusyNewActBusy", new KeyValues( "Command", "command", "OnNewActBusy" ), pActionSignalTarget );
  386. AddMenuItem( "DeleteActBusy", "#ActBusyDeleteActBusy", new KeyValues( "Command", "command", "OnDeleteActBusy" ), pActionSignalTarget );
  387. SetMenu(m_pMenu);
  388. }
  389. void CActBusyMenuButton::OnShowMenu(vgui::Menu *menu)
  390. {
  391. BaseClass::OnShowMenu( menu );
  392. // Update the menu
  393. int id;
  394. CActBusyDoc *pDoc = m_pTool->GetDocument();
  395. if ( pDoc )
  396. {
  397. id = m_Items.Find( "NewActBusy" );
  398. m_pMenu->SetItemEnabled( id, true );
  399. id = m_Items.Find( "DeleteActBusy" );
  400. m_pMenu->SetItemEnabled( id, true );
  401. }
  402. else
  403. {
  404. id = m_Items.Find( "NewActBusy" );
  405. m_pMenu->SetItemEnabled( id, false );
  406. id = m_Items.Find( "DeleteActBusy" );
  407. m_pMenu->SetItemEnabled( id, false );
  408. }
  409. }
  410. //-----------------------------------------------------------------------------
  411. // Initializes the menu bar
  412. //-----------------------------------------------------------------------------
  413. vgui::MenuBar *CActBusyTool::CreateMenuBar( CBaseToolSystem *pParent )
  414. {
  415. m_pMenuBar = new CToolFileMenuBar( pParent, "ActBusyMenuBar" );
  416. // Sets info in the menu bar
  417. char title[ 64 ];
  418. ComputeMenuBarTitle( title, sizeof( title ) );
  419. m_pMenuBar->SetInfo( title );
  420. m_pMenuBar->SetToolName( GetToolName() );
  421. UpdateMenuBar();
  422. // Add menu buttons
  423. CToolMenuButton *pFileButton = CreateToolFileMenuButton( m_pMenuBar, "File", "&File", GetActionTarget(), this );
  424. CToolMenuButton *pEditButton = CreateToolEditMenuButton( this, "Edit", "&Edit", GetActionTarget() );
  425. CActBusyMenuButton *pActBusyButton = new CActBusyMenuButton( this, "ActBusy", "&ActBusy", GetActionTarget() );
  426. CToolMenuButton *pSwitchButton = CreateToolSwitchMenuButton( m_pMenuBar, "Switcher", "&Tools", GetActionTarget() );
  427. CActBusyViewMenuButton *pViewButton = new CActBusyViewMenuButton( this, "View", "&View", GetActionTarget() );
  428. m_pMenuBar->AddButton( pFileButton );
  429. m_pMenuBar->AddButton( pEditButton );
  430. m_pMenuBar->AddButton( pActBusyButton );
  431. m_pMenuBar->AddButton( pViewButton );
  432. m_pMenuBar->AddButton( pSwitchButton );
  433. return m_pMenuBar;
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Updates the menu bar based on the current file
  437. //-----------------------------------------------------------------------------
  438. void CActBusyTool::UpdateMenuBar( )
  439. {
  440. if ( !m_pDoc )
  441. {
  442. m_pMenuBar->SetFileName( "#ActBusyNoFile" );
  443. return;
  444. }
  445. if ( m_pDoc->IsDirty() )
  446. {
  447. char sz[ 512 ];
  448. Q_snprintf( sz, sizeof( sz ), "* %s", m_pDoc->GetFileName() );
  449. m_pMenuBar->SetFileName( sz );
  450. }
  451. else
  452. {
  453. m_pMenuBar->SetFileName( m_pDoc->GetFileName() );
  454. }
  455. }
  456. //-----------------------------------------------------------------------------
  457. // Inherited from IFileMenuCallbacks
  458. //-----------------------------------------------------------------------------
  459. int CActBusyTool::GetFileMenuItemsEnabled( )
  460. {
  461. int nFlags;
  462. if ( !m_pDoc )
  463. {
  464. nFlags = FILE_NEW | FILE_OPEN | FILE_RECENT | FILE_CLEAR_RECENT | FILE_EXIT;
  465. }
  466. else
  467. {
  468. nFlags = FILE_ALL;
  469. }
  470. if ( m_RecentFiles.IsEmpty() )
  471. {
  472. nFlags &= ~(FILE_RECENT | FILE_CLEAR_RECENT);
  473. }
  474. return nFlags;
  475. }
  476. void CActBusyTool::AddRecentFilesToMenu( vgui::Menu *pMenu )
  477. {
  478. m_RecentFiles.AddToMenu( pMenu, GetActionTarget(), "OnRecent" );
  479. }
  480. //-----------------------------------------------------------------------------
  481. // Returns the file name for perforce
  482. //-----------------------------------------------------------------------------
  483. bool CActBusyTool::GetPerforceFileName( char *pFileName, int nMaxLen )
  484. {
  485. if ( !m_pDoc )
  486. return false;
  487. Q_strncpy( pFileName, m_pDoc->GetFileName(), nMaxLen );
  488. return true;
  489. }
  490. //-----------------------------------------------------------------------------
  491. // Derived classes can implement this to get a new scheme to be applied to this tool
  492. //-----------------------------------------------------------------------------
  493. vgui::HScheme CActBusyTool::GetToolScheme()
  494. {
  495. return vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "BoxRocket" );
  496. }
  497. //-----------------------------------------------------------------------------
  498. // Creates the action menu
  499. //-----------------------------------------------------------------------------
  500. vgui::Menu *CActBusyTool::CreateActionMenu( vgui::Panel *pParent )
  501. {
  502. vgui::Menu *pActionMenu = new Menu( pParent, "ActionMenu" );
  503. pActionMenu->AddMenuItem( "#ToolHide", new KeyValues( "Command", "command", "HideActionMenu" ), GetActionTarget() );
  504. return pActionMenu;
  505. }
  506. //-----------------------------------------------------------------------------
  507. // Purpose:
  508. // Input : -
  509. //-----------------------------------------------------------------------------
  510. void CActBusyTool::OnExit()
  511. {
  512. windowposmgr->SavePositions( "cfg/actbusy.txt", "ActBusy" );
  513. // Throw up a "save" dialog?
  514. enginetools->Command( "quit\n" );
  515. }
  516. //-----------------------------------------------------------------------------
  517. // Handle commands from the action menu and other menus
  518. //-----------------------------------------------------------------------------
  519. void CActBusyTool::OnCommand( const char *cmd )
  520. {
  521. if ( !V_stricmp( cmd, "HideActionMenu" ) )
  522. {
  523. if ( GetActionMenu() )
  524. {
  525. GetActionMenu()->SetVisible( false );
  526. }
  527. }
  528. else if ( !V_stricmp( cmd, "OnNewActBusy" ) )
  529. {
  530. OnNewActBusy();
  531. }
  532. else if ( !V_stricmp( cmd, "OnDeleteActBusy" ) )
  533. {
  534. OnDeleteActBusy();
  535. }
  536. else if ( !V_stricmp( cmd, "OnToggleProperties" ) )
  537. {
  538. OnToggleProperties();
  539. }
  540. else if ( !V_stricmp( cmd, "OnToggleSequencePicker" ) )
  541. {
  542. OnToggleSequencePicker();
  543. }
  544. else if ( !V_stricmp( cmd, "OnDefaultLayout" ) )
  545. {
  546. OnDefaultLayout();
  547. }
  548. else if ( !V_stricmp( cmd, "OnUndo" ) )
  549. {
  550. OnUndo();
  551. }
  552. else if ( !V_stricmp( cmd, "OnRedo" ) )
  553. {
  554. OnRedo();
  555. }
  556. else if ( !V_stricmp( cmd, "OnDescribeUndo" ) )
  557. {
  558. OnDescribeUndo();
  559. }
  560. else if ( const char *pSuffix = StringAfterPrefix( cmd, "OnRecent" ) )
  561. {
  562. int idx = Q_atoi( pSuffix );
  563. g_pActBusyTool->OpenFileFromHistory( idx, cmd );
  564. }
  565. else if( const char *pSuffixTool = StringAfterPrefix( cmd, "OnTool" ) )
  566. {
  567. int idx = Q_atoi( pSuffixTool );
  568. enginetools->SwitchToTool( idx );
  569. }
  570. else
  571. {
  572. BaseClass::OnCommand( cmd );
  573. }
  574. }
  575. //-----------------------------------------------------------------------------
  576. // Derived classes can implement this to get notified when files are saved/loaded
  577. //-----------------------------------------------------------------------------
  578. void CActBusyTool::OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues )
  579. {
  580. if ( bWroteFile )
  581. {
  582. OnMarkNotDirty();
  583. }
  584. if ( !pContextKeyValues )
  585. return;
  586. if ( state != FileOpenStateMachine::SUCCESSFUL )
  587. return;
  588. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnNew" ) )
  589. {
  590. PerformNew();
  591. return;
  592. }
  593. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnClose" ) )
  594. {
  595. OnCloseNoSave();
  596. return;
  597. }
  598. if ( !Q_stricmp( pContextKeyValues->GetName(), "OnQuit" ) )
  599. {
  600. OnCloseNoSave();
  601. vgui::ivgui()->PostMessage( GetVPanel(), new KeyValues( "OnExit" ), 0 );
  602. return;
  603. }
  604. }
  605. //-----------------------------------------------------------------------------
  606. // Called by SaveFile to allow clients to set up the save dialog
  607. //-----------------------------------------------------------------------------
  608. void CActBusyTool::SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues )
  609. {
  610. // Compute starting directory
  611. char pStartingDir[ MAX_PATH ];
  612. GetModSubdirectory( "scripts", pStartingDir, sizeof(pStartingDir) );
  613. if ( bOpenFile )
  614. {
  615. pDialog->SetTitle( "Open ActBusy .TXT File", true );
  616. }
  617. else
  618. {
  619. pDialog->SetTitle( "Save ActBusy .TXT File As", true );
  620. }
  621. pDialog->SetStartDirectoryContext( "actbusy_session", pStartingDir );
  622. pDialog->AddFilter( "*.txt", "ActBusy .TXT (*.txt)", true );
  623. }
  624. //-----------------------------------------------------------------------------
  625. // Called by SaveFile to allow clients to actually write the file out
  626. //-----------------------------------------------------------------------------
  627. bool CActBusyTool::OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  628. {
  629. OnCloseNoSave();
  630. return LoadDocument( pFileName );
  631. }
  632. //-----------------------------------------------------------------------------
  633. // Called by SaveFile to allow clients to actually write the file out
  634. //-----------------------------------------------------------------------------
  635. bool CActBusyTool::OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  636. {
  637. if ( !m_pDoc )
  638. return true;
  639. m_pDoc->SetFileName( pFileName );
  640. m_pDoc->SaveToFile( );
  641. UpdateMenuBar();
  642. return true;
  643. }
  644. //-----------------------------------------------------------------------------
  645. // Command handlers
  646. //-----------------------------------------------------------------------------
  647. void CActBusyTool::PerformNew()
  648. {
  649. OnCloseNoSave();
  650. NewDocument();
  651. }
  652. void CActBusyTool::OnNew()
  653. {
  654. if ( m_pDoc )
  655. {
  656. if ( m_pDoc->IsDirty() )
  657. {
  658. SaveFile( m_pDoc->GetFileName(), "actbusy", FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  659. new KeyValues( "OnNew" ) );
  660. return;
  661. }
  662. }
  663. PerformNew();
  664. }
  665. void CActBusyTool::OnOpen()
  666. {
  667. int nFlags = 0;
  668. const char *pSaveFileName = NULL;
  669. if ( m_pDoc && m_pDoc->IsDirty() )
  670. {
  671. nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY;
  672. pSaveFileName = m_pDoc->GetFileName();
  673. }
  674. OpenFile( "actbusy", pSaveFileName, "actbusy", nFlags );
  675. }
  676. void CActBusyTool::OnSave()
  677. {
  678. if ( m_pDoc )
  679. {
  680. SaveFile( m_pDoc->GetFileName(), "actbusy", FOSM_SHOW_PERFORCE_DIALOGS );
  681. }
  682. }
  683. void CActBusyTool::OnSaveAs()
  684. {
  685. if ( m_pDoc )
  686. {
  687. SaveFile( NULL, "actbusy", FOSM_SHOW_PERFORCE_DIALOGS );
  688. }
  689. }
  690. void CActBusyTool::OnClose()
  691. {
  692. if ( m_pDoc && m_pDoc->IsDirty() )
  693. {
  694. SaveFile( m_pDoc->GetFileName(), "actbusy", FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  695. new KeyValues( "OnClose" ) );
  696. return;
  697. }
  698. OnCloseNoSave();
  699. }
  700. void CActBusyTool::OnCloseNoSave()
  701. {
  702. DestroyTools();
  703. if ( m_pDoc )
  704. {
  705. CAppNotifyScopeGuard( "CActBusyTool::OnCloseNoSave", 0 );
  706. delete m_pDoc;
  707. m_pDoc = NULL;
  708. if ( m_hProperties )
  709. {
  710. m_hProperties->SetObject( NULL );
  711. }
  712. }
  713. UpdateMenuBar( );
  714. }
  715. void CActBusyTool::OnMarkNotDirty()
  716. {
  717. if ( m_pDoc )
  718. {
  719. m_pDoc->SetDirty( false );
  720. }
  721. }
  722. //-----------------------------------------------------------------------------
  723. // Open a specific file
  724. //-----------------------------------------------------------------------------
  725. void CActBusyTool::OpenSpecificFile( const char *pFileName )
  726. {
  727. int nFlags = 0;
  728. const char *pSaveFileName = NULL;
  729. if ( m_pDoc )
  730. {
  731. // File is already open
  732. if ( !Q_stricmp( m_pDoc->GetFileName(), pFileName ) )
  733. return;
  734. if ( m_pDoc->IsDirty() )
  735. {
  736. nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY;
  737. pSaveFileName = m_pDoc->GetFileName();
  738. }
  739. else
  740. {
  741. OnCloseNoSave();
  742. }
  743. }
  744. OpenFile( pFileName, "actbusy", pSaveFileName, "actbusy", nFlags );
  745. }
  746. //-----------------------------------------------------------------------------
  747. // Show the save document query dialog
  748. //-----------------------------------------------------------------------------
  749. void CActBusyTool::OpenFileFromHistory( int slot, const char *pCommand )
  750. {
  751. const char *pFileName = m_RecentFiles.GetFile( slot );
  752. if ( pFileName )
  753. {
  754. OpenSpecificFile( pFileName );
  755. }
  756. }
  757. bool CActBusyTool::CanQuit()
  758. {
  759. if ( m_pDoc && m_pDoc->IsDirty() )
  760. {
  761. // Show Save changes Yes/No/Cancel and re-quit if hit yes/no
  762. SaveFile( m_pDoc->GetFileName(), "actbusy", FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  763. new KeyValues( "OnQuit" ) );
  764. return false;
  765. }
  766. return true;
  767. }
  768. //-----------------------------------------------------------------------------
  769. // Various command handlers related to the Edit menu
  770. //-----------------------------------------------------------------------------
  771. void CActBusyTool::OnUndo()
  772. {
  773. CDisableUndoScopeGuard guard;
  774. g_pDataModel->Undo();
  775. }
  776. void CActBusyTool::OnRedo()
  777. {
  778. CDisableUndoScopeGuard guard;
  779. g_pDataModel->Redo();
  780. }
  781. void CActBusyTool::OnDescribeUndo()
  782. {
  783. CUtlVector< UndoInfo_t > list;
  784. g_pDataModel->GetUndoInfo( list );
  785. Msg( "%i operations in stack\n", list.Count() );
  786. for ( int i = list.Count() - 1; i >= 0; --i )
  787. {
  788. UndoInfo_t& entry = list[ i ];
  789. if ( entry.terminator )
  790. {
  791. Msg( "[ '%s' ] - %i operations\n", entry.undo, entry.numoperations );
  792. }
  793. Msg( " +%s\n", entry.desc );
  794. }
  795. }
  796. //-----------------------------------------------------------------------------
  797. // Commands related to the actbusy menu
  798. //-----------------------------------------------------------------------------
  799. void CActBusyTool::OnNewActBusy()
  800. {
  801. if ( m_pDoc )
  802. {
  803. m_pDoc->CreateActBusy();
  804. }
  805. }
  806. void CActBusyTool::OnDeleteActBusy()
  807. {
  808. }
  809. //-----------------------------------------------------------------------------
  810. // Inherited from IActBusyDocCallback
  811. //-----------------------------------------------------------------------------
  812. void CActBusyTool::OnDocChanged( const char *pReason, int nNotifySource, int nNotifyFlags )
  813. {
  814. UpdateMenuBar();
  815. if ( ( nNotifySource != NOTIFY_SOURCE_PROPERTIES_TREE ) && m_hProperties.Get() )
  816. {
  817. m_hProperties->Refresh();
  818. }
  819. }
  820. //-----------------------------------------------------------------------------
  821. // Purpose:
  822. // Input : -
  823. // Output : CActBusyDoc
  824. //-----------------------------------------------------------------------------
  825. CActBusyDoc *CActBusyTool::GetDocument()
  826. {
  827. return m_pDoc;
  828. }
  829. //-----------------------------------------------------------------------------
  830. // Purpose:
  831. // Input : -
  832. // Output : virtual CBasePropertiesContainer
  833. //-----------------------------------------------------------------------------
  834. CBasePropertiesContainer *CActBusyTool::GetProperties()
  835. {
  836. return m_hProperties.Get();
  837. }
  838. CMDLSequencePicker *CActBusyTool::GetSequencePicker()
  839. {
  840. return m_hMDLSequencePicker.Get();
  841. }
  842. //-----------------------------------------------------------------------------
  843. // Initializes the tools
  844. //-----------------------------------------------------------------------------
  845. void CActBusyTool::InitTools()
  846. {
  847. ShowElementProperties();
  848. // FIXME: There are no tool windows here; how should this work?
  849. // These panels are saved
  850. windowposmgr->RegisterPanel( "picker", m_hMDLSequencePicker, false );
  851. windowposmgr->RegisterPanel( "properties", m_hProperties, false );
  852. if ( !windowposmgr->LoadPositions( "cfg/actbusy.txt", this, &m_ToolWindowFactory, "ActBusy" ) )
  853. {
  854. OnDefaultLayout();
  855. }
  856. }
  857. //-----------------------------------------------------------------------------
  858. // Loads up a new document
  859. //-----------------------------------------------------------------------------
  860. bool CActBusyTool::LoadDocument( const char *pDocName )
  861. {
  862. Assert( !m_pDoc );
  863. DestroyTools();
  864. m_pDoc = new CActBusyDoc( this );
  865. if ( !m_pDoc->LoadFromFile( pDocName ) )
  866. {
  867. delete m_pDoc;
  868. m_pDoc = NULL;
  869. Warning( "Fatal error loading '%s'\n", pDocName );
  870. return false;
  871. }
  872. // ShowMiniViewport( false );
  873. CreateTools( m_pDoc );
  874. m_RecentFiles.Add( pDocName, "actbusy" );
  875. UpdateMenuBar( );
  876. InitTools();
  877. return true;
  878. }
  879. //-----------------------------------------------------------------------------
  880. // Loads up a new document
  881. //-----------------------------------------------------------------------------
  882. void CActBusyTool::NewDocument( )
  883. {
  884. Assert( !m_pDoc );
  885. m_pDoc = new CActBusyDoc( this );
  886. m_pDoc->CreateNew( );
  887. // ShowMiniViewport( false );
  888. CreateTools( m_pDoc );
  889. UpdateMenuBar( );
  890. InitTools();
  891. }
  892. //-----------------------------------------------------------------------------
  893. // Shows element properties
  894. //-----------------------------------------------------------------------------
  895. void CActBusyTool::ShowElementProperties( )
  896. {
  897. if ( !m_pDoc )
  898. return;
  899. if ( !m_pDoc->GetRootObject() )
  900. return;
  901. // It should already exist
  902. Assert( m_hProperties.Get() );
  903. if ( m_hProperties.Get() )
  904. {
  905. m_hProperties->SetObject( m_pDoc->GetRootObject() );
  906. }
  907. }
  908. void CActBusyTool::DestroyTools()
  909. {
  910. int c = ToolWindow::GetToolWindowCount();
  911. for ( int i = c - 1; i >= 0 ; --i )
  912. {
  913. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  914. delete kill;
  915. }
  916. UnregisterAllToolWindows();
  917. if ( m_hProperties.Get() )
  918. {
  919. windowposmgr->UnregisterPanel( m_hProperties.Get() );
  920. delete m_hProperties.Get();
  921. m_hProperties = NULL;
  922. }
  923. if ( m_hMDLSequencePicker.Get() )
  924. {
  925. windowposmgr->UnregisterPanel( m_hMDLSequencePicker.Get() );
  926. delete m_hMDLSequencePicker.Get();
  927. m_hMDLSequencePicker = NULL;
  928. }
  929. }
  930. void CActBusyTool::CreateTools( CActBusyDoc *doc )
  931. {
  932. if ( !m_hProperties.Get() )
  933. {
  934. m_hProperties = new CBasePropertiesContainer( NULL, m_pDoc, g_pEditorTypeDict );
  935. }
  936. if ( !m_hMDLSequencePicker.Get() )
  937. {
  938. m_hMDLSequencePicker = new CMDLSequencePicker( NULL );
  939. SETUP_PANEL( m_hMDLSequencePicker.Get() );
  940. m_hMDLSequencePicker->Activate();
  941. }
  942. RegisterToolWindow( m_hProperties );
  943. RegisterToolWindow( m_hMDLSequencePicker );
  944. }
  945. void CActBusyTool::ShowToolWindow( Panel *tool, const char *toolName, bool visible )
  946. {
  947. Assert( tool );
  948. if ( tool->GetParent() == NULL && visible )
  949. {
  950. m_ToolWindowFactory.InstanceToolWindow( this, false, tool, toolName, false );
  951. }
  952. else if ( !visible )
  953. {
  954. ToolWindow *tw = dynamic_cast< ToolWindow * >( tool->GetParent()->GetParent() );
  955. Assert( tw );
  956. tw->RemovePage( tool );
  957. }
  958. }
  959. void CActBusyTool::ToggleToolWindow( Panel *tool, const char *toolName )
  960. {
  961. Assert( tool );
  962. if ( tool->GetParent() == NULL )
  963. {
  964. ShowToolWindow( tool, toolName, true );
  965. }
  966. else
  967. {
  968. ShowToolWindow( tool, toolName, false );
  969. }
  970. }
  971. void CActBusyTool::DestroyToolContainers()
  972. {
  973. int c = ToolWindow::GetToolWindowCount();
  974. for ( int i = c - 1; i >= 0 ; --i )
  975. {
  976. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  977. delete kill;
  978. }
  979. }
  980. void CActBusyTool::OnDefaultLayout()
  981. {
  982. int y = m_pMenuBar->GetTall();
  983. int usew, useh;
  984. GetSize( usew, useh );
  985. DestroyToolContainers();
  986. Assert( ToolWindow::GetToolWindowCount() == 0 );
  987. CBasePropertiesContainer *properties = GetProperties();
  988. CMDLSequencePicker *picker = GetSequencePicker();
  989. // Need three containers
  990. ToolWindow *propertyWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, properties, "#ActBusyProperties", false );
  991. ToolWindow *pickerWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, picker, "#ActBusyViewSequencePicker", false );
  992. int halfScreen = usew / 2;
  993. int bottom = useh - y;
  994. propertyWindow->SetBounds( 0, y, halfScreen, bottom );
  995. pickerWindow->SetBounds( halfScreen, y, halfScreen, bottom );
  996. }
  997. void CActBusyTool::OnToggleProperties()
  998. {
  999. ToggleToolWindow( m_hProperties.Get(), "#ActBusyProperties" );
  1000. }
  1001. void CActBusyTool::OnToggleSequencePicker()
  1002. {
  1003. ToggleToolWindow( m_hMDLSequencePicker.Get(), "#ActBusyViewSequencePicker" );
  1004. }
  1005. const char *CActBusyTool::GetLogoTextureName()
  1006. {
  1007. return "vgui/tools/actbusy/actbusy_logo";
  1008. }