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.

625 lines
17 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  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/toolmenubutton.h"
  12. #include "vgui_controls/Menu.h"
  13. #include "tier1/KeyValues.h"
  14. #include "toolutils/enginetools_int.h"
  15. #include "toolframework/ienginetool.h"
  16. #include "vgui/IInput.h"
  17. #include "vgui/KeyCode.h"
  18. #include "vgui_controls/FileOpenDialog.h"
  19. #include "filesystem.h"
  20. #include "vgui/ilocalize.h"
  21. #include "dme_controls/elementpropertiestree.h"
  22. #include "tier0/icommandline.h"
  23. #include "materialsystem/imaterialsystem.h"
  24. #include "VGuiMatSurface/IMatSystemSurface.h"
  25. #include "tier3/tier3.h"
  26. #include "tier2/fileutils.h"
  27. #include "gameeventeditdoc.h"
  28. #include "gameeventeditpanel.h"
  29. #include "toolutils/toolwindowfactory.h"
  30. #include "toolutils/savewindowpositions.h" // for windowposmgr
  31. #include "toolutils/ConsolePage.h"
  32. #include "igameevents.h"
  33. IGameEventManager2 *gameeventmanager = NULL;
  34. using namespace vgui;
  35. const char *GetVGuiControlsModuleName()
  36. {
  37. return "GameEvents";
  38. }
  39. //-----------------------------------------------------------------------------
  40. // Connect, disconnect
  41. //-----------------------------------------------------------------------------
  42. bool ConnectTools( CreateInterfaceFn factory )
  43. {
  44. gameeventmanager = ( IGameEventManager2 * )factory( INTERFACEVERSION_GAMEEVENTSMANAGER2, NULL );
  45. if ( !gameeventmanager )
  46. {
  47. Warning( "Game Event Tool missing required interface\n" );
  48. return false;
  49. }
  50. return (materials != NULL) && (g_pMatSystemSurface != NULL);
  51. }
  52. void DisconnectTools( )
  53. {
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Implementation of the game events tool
  57. //-----------------------------------------------------------------------------
  58. class CGameEventTool : public CBaseToolSystem, public IFileMenuCallbacks
  59. {
  60. DECLARE_CLASS_SIMPLE( CGameEventTool, CBaseToolSystem );
  61. public:
  62. CGameEventTool();
  63. // Inherited from IToolSystem
  64. virtual const char *GetToolName() { return "Game Events"; }
  65. virtual const char *GetBindingsContextFile() { return "cfg/GameEvents.kb"; }
  66. virtual bool Init( );
  67. virtual void Shutdown();
  68. // Inherited from IFileMenuCallbacks
  69. virtual int GetFileMenuItemsEnabled( );
  70. virtual void AddRecentFilesToMenu( vgui::Menu *menu );
  71. virtual bool GetPerforceFileName( char *pFileName, int nMaxLen ) { return false; }
  72. virtual vgui::Panel* GetRootPanel() { return this; }
  73. // Inherited from CBaseToolSystem
  74. virtual vgui::HScheme GetToolScheme();
  75. virtual vgui::Menu *CreateActionMenu( vgui::Panel *pParent );
  76. virtual void OnCommand( const char *cmd );
  77. virtual const char *GetRegistryName() { return "SampleTool"; }
  78. virtual vgui::MenuBar *CreateMenuBar( CBaseToolSystem *pParent );
  79. public:
  80. MESSAGE_FUNC( OnNew, "OnNew" );
  81. MESSAGE_FUNC( OnOpen, "OnOpen" );
  82. MESSAGE_FUNC( OnSave, "OnSave" );
  83. MESSAGE_FUNC( OnSaveAs, "OnSaveAs" );
  84. MESSAGE_FUNC( OnClose, "OnClose" );
  85. MESSAGE_FUNC( OnCloseNoSave, "OnCloseNoSave" );
  86. MESSAGE_FUNC( OnMarkNotDirty, "OnMarkNotDirty" );
  87. MESSAGE_FUNC( OnExit, "OnExit" );
  88. void NewDocument();
  89. void OpenFileFromHistory( int slot );
  90. virtual void SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues );
  91. virtual bool OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
  92. virtual bool OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues );
  93. virtual void OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues );
  94. // Get at the edit panel
  95. CGameEventEditPanel *GetGameEventEditPanel();
  96. private:
  97. // Loads up a new document
  98. bool LoadDocument( const char *pDocName );
  99. // Creates, destroys tools
  100. void CreateTools( CGameEventEditDoc *doc );
  101. void InitTools();
  102. void DestroyTools();
  103. void OnDefaultLayout();
  104. // Updates the menu bar based on the current file
  105. void UpdateMenuBar( );
  106. // Shows element properties
  107. void ShowElementProperties( );
  108. virtual const char *GetLogoTextureName();
  109. CConsolePage *GetConsole();
  110. void OnToggleConsole();
  111. void ShowToolWindow( Panel *tool, char const *toolName, bool visible );
  112. void ToggleToolWindow( Panel *tool, char const *toolName );
  113. CToolWindowFactory< ToolWindow > m_ToolWindowFactory;
  114. // The entity report
  115. vgui::DHANDLE< CGameEventEditPanel > m_hGameEventEditPanel;
  116. // Document
  117. CGameEventEditDoc *m_pDoc;
  118. // The menu bar
  119. CToolFileMenuBar *m_pMenuBar;
  120. // console tab in viewport
  121. vgui::DHANDLE< CConsolePage > m_hConsole;
  122. };
  123. //-----------------------------------------------------------------------------
  124. // Singleton
  125. //-----------------------------------------------------------------------------
  126. CGameEventTool *g_pSampleTool = NULL;
  127. void CreateTools()
  128. {
  129. g_pSampleTool = new CGameEventTool();
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Constructor
  133. //-----------------------------------------------------------------------------
  134. CGameEventTool::CGameEventTool()
  135. {
  136. m_pMenuBar = NULL;
  137. m_pDoc = NULL;
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Init, shutdown
  141. //-----------------------------------------------------------------------------
  142. bool CGameEventTool::Init( )
  143. {
  144. m_RecentFiles.LoadFromRegistry( GetRegistryName() );
  145. // NOTE: This has to happen before BaseClass::Init
  146. g_pVGuiLocalize->AddFile( "resource/toolgameevents_%language%.txt" );
  147. if ( !BaseClass::Init( ) )
  148. return false;
  149. return true;
  150. }
  151. void CGameEventTool::Shutdown()
  152. {
  153. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  154. BaseClass::Shutdown();
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Derived classes can implement this to get a new scheme to be applied to this tool
  158. //-----------------------------------------------------------------------------
  159. vgui::HScheme CGameEventTool::GetToolScheme()
  160. {
  161. return vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", "SampleTool" );
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Initializes the menu bar
  165. //-----------------------------------------------------------------------------
  166. vgui::MenuBar *CGameEventTool::CreateMenuBar( CBaseToolSystem *pParent )
  167. {
  168. m_pMenuBar = new CToolFileMenuBar( pParent, "Main Menu Bar" );
  169. // Sets info in the menu bar
  170. char title[ 64 ];
  171. ComputeMenuBarTitle( title, sizeof( title ) );
  172. m_pMenuBar->SetInfo( title );
  173. m_pMenuBar->SetToolName( GetToolName() );
  174. // Add menu buttons
  175. CToolMenuButton *pFileButton = CreateToolFileMenuButton( m_pMenuBar, "File", "&File", GetActionTarget(), this );
  176. CToolMenuButton *pSwitchButton = CreateToolSwitchMenuButton( m_pMenuBar, "Switcher", "&Tools", GetActionTarget() );
  177. m_pMenuBar->AddButton( pFileButton );
  178. m_pMenuBar->AddButton( pSwitchButton );
  179. return m_pMenuBar;
  180. }
  181. //-----------------------------------------------------------------------------
  182. // Creates the action menu
  183. //-----------------------------------------------------------------------------
  184. vgui::Menu *CGameEventTool::CreateActionMenu( vgui::Panel *pParent )
  185. {
  186. vgui::Menu *pActionMenu = new Menu( pParent, "ActionMenu" );
  187. pActionMenu->AddMenuItem( "#ToolHide", new KeyValues( "Command", "command", "HideActionMenu" ), GetActionTarget() );
  188. return pActionMenu;
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Inherited from IFileMenuCallbacks
  192. //-----------------------------------------------------------------------------
  193. int CGameEventTool::GetFileMenuItemsEnabled( )
  194. {
  195. int nFlags = FILE_ALL;
  196. if ( m_RecentFiles.IsEmpty() )
  197. {
  198. nFlags &= ~(FILE_RECENT | FILE_CLEAR_RECENT);
  199. }
  200. return nFlags;
  201. }
  202. void CGameEventTool::AddRecentFilesToMenu( vgui::Menu *pMenu )
  203. {
  204. m_RecentFiles.AddToMenu( pMenu, GetActionTarget(), "OnRecent" );
  205. }
  206. //-----------------------------------------------------------------------------
  207. // Purpose:
  208. // Input : -
  209. //-----------------------------------------------------------------------------
  210. void CGameEventTool::OnExit()
  211. {
  212. enginetools->Command( "quit\n" );
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Handle commands from the action menu and other menus
  216. //-----------------------------------------------------------------------------
  217. void CGameEventTool::OnCommand( const char *cmd )
  218. {
  219. if ( !V_stricmp( cmd, "HideActionMenu" ) )
  220. {
  221. if ( GetActionMenu() )
  222. {
  223. GetActionMenu()->SetVisible( false );
  224. }
  225. }
  226. else if ( const char *pOnRecentSuffix = StringAfterPrefix( cmd, "OnRecent" ) )
  227. {
  228. int idx = Q_atoi( pOnRecentSuffix );
  229. OpenFileFromHistory( idx );
  230. }
  231. else if( const char *pOnToolSuffix = StringAfterPrefix( cmd, "OnTool" ) )
  232. {
  233. int idx = Q_atoi( pOnToolSuffix );
  234. enginetools->SwitchToTool( idx );
  235. }
  236. else
  237. {
  238. BaseClass::OnCommand( cmd );
  239. }
  240. }
  241. //-----------------------------------------------------------------------------
  242. // Command handlers
  243. //-----------------------------------------------------------------------------
  244. void CGameEventTool::OnNew()
  245. {
  246. if ( m_pDoc )
  247. {
  248. if ( m_pDoc->IsDirty() )
  249. {
  250. SaveFile( m_pDoc->GetTXTFileName(), "xt", FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY,
  251. new KeyValues( "OnNew" ) );
  252. return;
  253. }
  254. }
  255. NewDocument();
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Loads up a new document
  259. //-----------------------------------------------------------------------------
  260. void CGameEventTool::NewDocument( )
  261. {
  262. Assert( !m_pDoc );
  263. m_pDoc = new CGameEventEditDoc(/* this */);
  264. CreateTools( m_pDoc );
  265. UpdateMenuBar();
  266. InitTools();
  267. }
  268. //-----------------------------------------------------------------------------
  269. // Called when the File->Open menu is selected
  270. //-----------------------------------------------------------------------------
  271. void CGameEventTool::OnOpen( )
  272. {
  273. int nFlags = 0;
  274. const char *pSaveFileName = NULL;
  275. if ( m_pDoc && m_pDoc->IsDirty() )
  276. {
  277. nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY;
  278. pSaveFileName = m_pDoc->GetTXTFileName();
  279. }
  280. OpenFile( "txt", pSaveFileName, "txt", nFlags );
  281. }
  282. bool CGameEventTool::OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  283. {
  284. OnCloseNoSave();
  285. if ( !LoadDocument( pFileName ) )
  286. return false;
  287. m_RecentFiles.Add( pFileName, pFileFormat );
  288. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  289. UpdateMenuBar();
  290. return true;
  291. }
  292. //-----------------------------------------------------------------------------
  293. // Updates the menu bar based on the current file
  294. //-----------------------------------------------------------------------------
  295. void CGameEventTool::UpdateMenuBar( )
  296. {
  297. if ( !m_pDoc )
  298. {
  299. m_pMenuBar->SetFileName( "#CommEditNoFile" );
  300. return;
  301. }
  302. const char *pTXTFile = m_pDoc->GetTXTFileName();
  303. if ( !pTXTFile[0] )
  304. {
  305. m_pMenuBar->SetFileName( "#CommEditNoFile" );
  306. return;
  307. }
  308. if ( m_pDoc->IsDirty() )
  309. {
  310. char sz[ 512 ];
  311. Q_snprintf( sz, sizeof( sz ), "* %s", pTXTFile );
  312. m_pMenuBar->SetFileName( sz );
  313. }
  314. else
  315. {
  316. m_pMenuBar->SetFileName( pTXTFile );
  317. }
  318. }
  319. void CGameEventTool::OnSave()
  320. {
  321. // FIXME: Implement
  322. }
  323. void CGameEventTool::OnSaveAs()
  324. {
  325. SaveFile( NULL, NULL, 0 );
  326. }
  327. bool CGameEventTool::OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues )
  328. {
  329. // FIXME: Implement
  330. m_RecentFiles.Add( pFileName, pFileFormat );
  331. return true;
  332. }
  333. void CGameEventTool::OnClose()
  334. {
  335. // FIXME: Implement
  336. }
  337. void CGameEventTool::OnCloseNoSave()
  338. {
  339. // FIXME: Implement
  340. }
  341. void CGameEventTool::OnMarkNotDirty()
  342. {
  343. // FIXME: Implement
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Show the save document query dialog
  347. //-----------------------------------------------------------------------------
  348. void CGameEventTool::OpenFileFromHistory( int slot )
  349. {
  350. const char *pFileName = m_RecentFiles.GetFile( slot );
  351. OnReadFileFromDisk( pFileName, NULL, 0 );
  352. }
  353. //-----------------------------------------------------------------------------
  354. // Called when file operations complete
  355. //-----------------------------------------------------------------------------
  356. void CGameEventTool::OnFileOperationCompleted( const char *pFileType, bool bWroteFile, vgui::FileOpenStateMachine::CompletionState_t state, KeyValues *pContextKeyValues )
  357. {
  358. // FIXME: Implement
  359. }
  360. //-----------------------------------------------------------------------------
  361. // Show the File browser dialog
  362. //-----------------------------------------------------------------------------
  363. void CGameEventTool::SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues )
  364. {
  365. char pStartingDir[ MAX_PATH ];
  366. GetModSubdirectory( NULL, pStartingDir, sizeof(pStartingDir) );
  367. pDialog->SetTitle( "Choose SampleTool .txt file", true );
  368. pDialog->SetStartDirectoryContext( "sample_session", pStartingDir );
  369. pDialog->AddFilter( "*.txt", "SampleTool (*.txt)", true );
  370. }
  371. const char *CGameEventTool::GetLogoTextureName()
  372. {
  373. return "vgui/tools/sampletool/sampletool_logo";
  374. }
  375. CGameEventEditPanel *CGameEventTool::GetGameEventEditPanel()
  376. {
  377. return m_hGameEventEditPanel.Get();
  378. }
  379. //-----------------------------------------------------------------------------
  380. // Creates
  381. //-----------------------------------------------------------------------------
  382. void CGameEventTool::CreateTools( CGameEventEditDoc *doc )
  383. {
  384. if ( !m_hGameEventEditPanel.Get() )
  385. {
  386. m_hGameEventEditPanel = new CGameEventEditPanel( m_pDoc, this );
  387. }
  388. if ( !m_hConsole.Get() )
  389. {
  390. m_hConsole = new CConsolePage( NULL, false );
  391. }
  392. RegisterToolWindow( m_hGameEventEditPanel );
  393. RegisterToolWindow( m_hConsole );
  394. }
  395. //-----------------------------------------------------------------------------
  396. // Initializes the tools
  397. //-----------------------------------------------------------------------------
  398. void CGameEventTool::InitTools()
  399. {
  400. //ShowElementProperties();
  401. windowposmgr->RegisterPanel( "gameeventedit", m_hGameEventEditPanel, false );
  402. windowposmgr->RegisterPanel( "Console", m_hConsole, false ); // No context menu
  403. if ( !windowposmgr->LoadPositions( "cfg/commedit.txt", this, &m_ToolWindowFactory, "CommEdit" ) )
  404. {
  405. OnDefaultLayout();
  406. }
  407. }
  408. void CGameEventTool::DestroyTools()
  409. {
  410. UnregisterAllToolWindows();
  411. if ( m_hGameEventEditPanel.Get() )
  412. {
  413. windowposmgr->UnregisterPanel( m_hGameEventEditPanel.Get() );
  414. delete m_hGameEventEditPanel.Get();
  415. m_hGameEventEditPanel = NULL;
  416. }
  417. if ( m_hConsole.Get() )
  418. {
  419. windowposmgr->UnregisterPanel( m_hConsole.Get() );
  420. delete m_hConsole.Get();
  421. m_hConsole = NULL;
  422. }
  423. }
  424. //-----------------------------------------------------------------------------
  425. // Loads up a new document
  426. //-----------------------------------------------------------------------------
  427. bool CGameEventTool::LoadDocument( const char *pDocName )
  428. {
  429. Assert( !m_pDoc );
  430. DestroyTools();
  431. m_pDoc = new CGameEventEditDoc(/* this */);
  432. if ( !m_pDoc->LoadFromFile( pDocName ) )
  433. {
  434. delete m_pDoc;
  435. m_pDoc = NULL;
  436. Warning( "Fatal error loading '%s'\n", pDocName );
  437. return false;
  438. }
  439. ShowMiniViewport( true );
  440. CreateTools( m_pDoc );
  441. InitTools();
  442. return true;
  443. }
  444. CConsolePage *CGameEventTool::GetConsole()
  445. {
  446. return m_hConsole;
  447. }
  448. void CGameEventTool::ShowToolWindow( Panel *tool, char const *toolName, bool visible )
  449. {
  450. Assert( tool );
  451. if ( tool->GetParent() == NULL && visible )
  452. {
  453. m_ToolWindowFactory.InstanceToolWindow( this, false, tool, toolName, false );
  454. }
  455. else if ( !visible )
  456. {
  457. ToolWindow *tw = dynamic_cast< ToolWindow * >( tool->GetParent()->GetParent() );
  458. Assert( tw );
  459. tw->RemovePage( tool );
  460. }
  461. }
  462. void CGameEventTool::ToggleToolWindow( Panel *tool, char const *toolName )
  463. {
  464. Assert( tool );
  465. if ( tool->GetParent() == NULL )
  466. {
  467. ShowToolWindow( tool, toolName, true );
  468. }
  469. else
  470. {
  471. ShowToolWindow( tool, toolName, false );
  472. }
  473. }
  474. void CGameEventTool::OnToggleConsole()
  475. {
  476. if ( m_hConsole.Get() )
  477. {
  478. ToggleToolWindow( m_hConsole.Get(), "#BxConsole" );
  479. }
  480. }
  481. //-----------------------------------------------------------------------------
  482. // Sets up the default layout
  483. //-----------------------------------------------------------------------------
  484. void CGameEventTool::OnDefaultLayout()
  485. {
  486. int y = m_pMenuBar->GetTall();
  487. int usew, useh;
  488. GetSize( usew, useh );
  489. int c = ToolWindow::GetToolWindowCount();
  490. for ( int i = c - 1; i >= 0 ; --i )
  491. {
  492. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  493. delete kill;
  494. }
  495. Assert( ToolWindow::GetToolWindowCount() == 0 );
  496. CGameEventEditPanel *pEditPanel = GetGameEventEditPanel();
  497. CConsolePage *pConsole = GetConsole();
  498. // Need three containers
  499. ToolWindow *pEditPanelWindow = m_ToolWindowFactory.InstanceToolWindow( GetClientArea(), false, pEditPanel, "#CommEditProperties", false );
  500. ToolWindow *pMiniViewport = dynamic_cast< ToolWindow* >( GetMiniViewport() );
  501. pMiniViewport->AddPage( pConsole, "#BxConsole", false );
  502. int quarterScreen = usew / 4;
  503. SetMiniViewportBounds( quarterScreen, y, 3*quarterScreen, useh - y );
  504. pEditPanelWindow->SetBounds( 0, y, quarterScreen, useh - y );
  505. }