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.

1172 lines
33 KiB

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