Counter Strike : Global Offensive Source Code
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.

1243 lines
33 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Core Movie Maker UI API
  4. //
  5. //=============================================================================
  6. #include "toolutils/basetoolsystem.h"
  7. #include "toolframework/ienginetool.h"
  8. #include "vgui/IPanel.h"
  9. #include "vgui_controls/Controls.h"
  10. #include "vgui_controls/Menu.h"
  11. #include "vgui/ISurface.h"
  12. #include "vgui_controls/Panel.h"
  13. #include "vgui_controls/FileOpenDialog.h"
  14. #include "vgui_controls/MessageBox.h"
  15. #include "vgui/Cursor.h"
  16. #include "vgui/iinput.h"
  17. #include "vgui/ivgui.h"
  18. #include "vgui_controls/AnimationController.h"
  19. #include "ienginevgui.h"
  20. #include "toolui.h"
  21. #include "toolutils/toolmenubar.h"
  22. #include "vgui/ilocalize.h"
  23. #include "toolutils/enginetools_int.h"
  24. #include "toolutils/vgui_tools.h"
  25. #include "icvar.h"
  26. #include "tier1/convar.h"
  27. #include "datamodel/dmelementfactoryhelper.h"
  28. #include "filesystem.h"
  29. #include "vgui_controls/savedocumentquery.h"
  30. #include "vgui_controls/perforcefilelistframe.h"
  31. #include "toolutils/miniviewport.h"
  32. #include "materialsystem/imaterialsystem.h"
  33. #include "materialsystem/imaterial.h"
  34. #include "materialsystem/IMesh.h"
  35. #include "toolutils/BaseStatusBar.h"
  36. #include "movieobjects/movieobjects.h"
  37. #include "vgui_controls/KeyBoardEditorDialog.h"
  38. #include "vgui_controls/KeyBindingHelpDialog.h"
  39. #include "dmserializers/idmserializers.h"
  40. #include "tier2/renderutils.h"
  41. // memdbgon must be the last include file in a .cpp file!!!
  42. #include "tier0/memdbgon.h"
  43. using namespace vgui;
  44. extern IMaterialSystem *MaterialSystem();
  45. class CGlobalFlexController : public IGlobalFlexController
  46. {
  47. public:
  48. virtual int FindGlobalFlexController( const char *name )
  49. {
  50. return clienttools->FindGlobalFlexcontroller( name );
  51. }
  52. virtual const char *GetGlobalFlexControllerName( int idx )
  53. {
  54. return clienttools->GetGlobalFlexControllerName( idx );
  55. }
  56. };
  57. static CGlobalFlexController g_GlobalFlexController;
  58. extern IGlobalFlexController *g_pGlobalFlexController;
  59. //-----------------------------------------------------------------------------
  60. // Singleton interfaces
  61. //-----------------------------------------------------------------------------
  62. IServerTools *servertools = NULL;
  63. IClientTools *clienttools = NULL;
  64. //-----------------------------------------------------------------------------
  65. // External functions
  66. //-----------------------------------------------------------------------------
  67. void RegisterTool( IToolSystem *tool );
  68. //-----------------------------------------------------------------------------
  69. // Base tool system constructor
  70. //-----------------------------------------------------------------------------
  71. CBaseToolSystem::CBaseToolSystem( const char *pToolName /*="CBaseToolSystem"*/ ) :
  72. BaseClass( NULL, pToolName ),
  73. m_pBackground( 0 ),
  74. m_pLogo( 0 )
  75. {
  76. RegisterTool( this );
  77. SetAutoDelete( false );
  78. m_bGameInputEnabled = false;
  79. m_bFullscreenMode = false;
  80. m_bIsActive = false;
  81. m_bFullscreenToolModeEnabled = false;
  82. m_MostRecentlyFocused = NULL;
  83. SetKeyBoardInputEnabled( true );
  84. input()->RegisterKeyCodeUnhandledListener( GetVPanel() );
  85. m_pFileOpenStateMachine = new vgui::FileOpenStateMachine( this, this );
  86. m_pFileOpenStateMachine->AddActionSignalTarget( this );
  87. }
  88. void CBaseToolSystem::ApplySchemeSettings(IScheme *pScheme)
  89. {
  90. BaseClass::ApplySchemeSettings(pScheme);
  91. SetKeyBoardInputEnabled( true );
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Derived classes can implement this to get a new scheme to be applied to this tool
  95. //-----------------------------------------------------------------------------
  96. vgui::HScheme CBaseToolSystem::GetToolScheme()
  97. {
  98. return vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", GetToolName() );
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Called at the end of engine startup (after client .dll and server .dll have been loaded)
  102. //-----------------------------------------------------------------------------
  103. bool CBaseToolSystem::Init( )
  104. {
  105. // Read shared localization info
  106. g_pVGuiLocalize->AddFile( "resource/dmecontrols_%language%.txt" );
  107. g_pVGuiLocalize->AddFile( "resource/toolshared_%language%.txt" );
  108. g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt" );
  109. g_pVGuiLocalize->AddFile( "Resource/platform_%language%.txt" );
  110. g_pVGuiLocalize->AddFile( "resource/boxrocket_%language%.txt" );
  111. // Create the tool workspace
  112. SetParent( VGui_GetToolRootPanel() );
  113. // Deal with scheme
  114. vgui::HScheme hToolScheme = GetToolScheme();
  115. if ( hToolScheme != 0 )
  116. {
  117. SetScheme( hToolScheme );
  118. }
  119. m_KeyBindingsHandle = Panel::CreateKeyBindingsContext( GetBindingsContextFile(), "GAME" );
  120. SetKeyBindingsContext( m_KeyBindingsHandle );
  121. LoadKeyBindings();
  122. const char *pszBackground = GetBackgroundTextureName();
  123. if ( pszBackground )
  124. {
  125. m_pBackground = materials->FindMaterial( GetBackgroundTextureName() , TEXTURE_GROUP_VGUI );
  126. m_pBackground->IncrementReferenceCount();
  127. }
  128. const char *pszLogo = GetLogoTextureName();
  129. if ( pszLogo )
  130. {
  131. m_pLogo = materials->FindMaterial( GetLogoTextureName(), TEXTURE_GROUP_VGUI );
  132. m_pLogo->IncrementReferenceCount();
  133. }
  134. // Make the tool workspace the size of the screen
  135. int w, h;
  136. surface()->GetScreenSize( w, h );
  137. SetBounds( 0, 0, w, h );
  138. SetPaintBackgroundEnabled( true );
  139. SetPaintBorderEnabled( false );
  140. SetPaintEnabled( false );
  141. SetCursor( vgui::dc_none );
  142. SetVisible( false );
  143. // Create the tool UI
  144. m_pToolUI = new CToolUI( this, "ToolUI", this );
  145. // Create the mini viewport
  146. m_hMiniViewport = CreateMiniViewport( GetClientArea() );
  147. Assert( m_hMiniViewport.Get() );
  148. return true;
  149. }
  150. void CBaseToolSystem::ShowMiniViewport( bool state )
  151. {
  152. if ( !m_hMiniViewport.Get() )
  153. return;
  154. m_hMiniViewport->SetVisible( state );
  155. }
  156. void CBaseToolSystem::SetMiniViewportBounds( int x, int y, int width, int height )
  157. {
  158. if ( m_hMiniViewport )
  159. {
  160. m_hMiniViewport->SetBounds( x, y, width, height );
  161. }
  162. }
  163. void CBaseToolSystem::SetMiniViewportText( const char *pText )
  164. {
  165. if ( m_hMiniViewport )
  166. {
  167. m_hMiniViewport->SetOverlayText( pText );
  168. }
  169. }
  170. void CBaseToolSystem::GetMiniViewportEngineBounds( int &x, int &y, int &width, int &height )
  171. {
  172. if ( m_hMiniViewport )
  173. {
  174. m_hMiniViewport->GetEngineBounds( x, y, width, height );
  175. }
  176. }
  177. vgui::Panel *CBaseToolSystem::GetMiniViewport( void )
  178. {
  179. return m_hMiniViewport;
  180. }
  181. //-----------------------------------------------------------------------------
  182. // Shut down
  183. //-----------------------------------------------------------------------------
  184. void CBaseToolSystem::Shutdown()
  185. {
  186. if ( m_pBackground )
  187. {
  188. m_pBackground->DecrementReferenceCount();
  189. }
  190. if ( m_pLogo )
  191. {
  192. m_pLogo->DecrementReferenceCount();
  193. }
  194. if ( m_hMiniViewport.Get() )
  195. {
  196. delete m_hMiniViewport.Get();
  197. }
  198. // Delete ourselves
  199. MarkForDeletion();
  200. // Make sure anything "marked for deletion"
  201. // actually gets deleted before this dll goes away
  202. vgui::ivgui()->RunFrame();
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Can the tool quit?
  206. //-----------------------------------------------------------------------------
  207. bool CBaseToolSystem::CanQuit( const char* /*pExitMsg*/ )
  208. {
  209. return true;
  210. }
  211. //-----------------------------------------------------------------------------
  212. // Client, server init + shutdown
  213. //-----------------------------------------------------------------------------
  214. bool CBaseToolSystem::ServerInit( CreateInterfaceFn serverFactory )
  215. {
  216. servertools = ( IServerTools * )serverFactory( VSERVERTOOLS_INTERFACE_VERSION, NULL );
  217. if ( !servertools )
  218. {
  219. Error( "CBaseToolSystem::PostInit: Unable to get '%s' interface from game .dll\n", VSERVERTOOLS_INTERFACE_VERSION );
  220. }
  221. return true;
  222. }
  223. bool CBaseToolSystem::ClientInit( CreateInterfaceFn clientFactory )
  224. {
  225. clienttools = ( IClientTools * )clientFactory( VCLIENTTOOLS_INTERFACE_VERSION, NULL );
  226. if ( !clienttools )
  227. {
  228. Error( "CBaseToolSystem::PostInit: Unable to get '%s' interface from client .dll\n", VCLIENTTOOLS_INTERFACE_VERSION );
  229. }
  230. else
  231. {
  232. g_pGlobalFlexController = &g_GlobalFlexController; // don't set this until clienttools is connected
  233. }
  234. return true;
  235. }
  236. void CBaseToolSystem::ServerShutdown()
  237. {
  238. servertools = NULL;
  239. }
  240. void CBaseToolSystem::ClientShutdown()
  241. {
  242. clienttools = NULL;
  243. }
  244. //-----------------------------------------------------------------------------
  245. // Level init, shutdown for server
  246. //-----------------------------------------------------------------------------
  247. void CBaseToolSystem::ServerLevelInitPreEntity()
  248. {
  249. }
  250. void CBaseToolSystem::ServerLevelInitPostEntity()
  251. {
  252. }
  253. void CBaseToolSystem::ServerLevelShutdownPreEntity()
  254. {
  255. }
  256. void CBaseToolSystem::ServerLevelShutdownPostEntity()
  257. {
  258. }
  259. //-----------------------------------------------------------------------------
  260. // Think methods
  261. //-----------------------------------------------------------------------------
  262. void CBaseToolSystem::ServerFrameUpdatePreEntityThink()
  263. {
  264. }
  265. void CBaseToolSystem::Think( bool finalTick )
  266. {
  267. // run vgui animations
  268. vgui::GetAnimationController()->UpdateAnimations( enginetools->Time() );
  269. }
  270. void CBaseToolSystem::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *message )
  271. {
  272. return;
  273. }
  274. void CBaseToolSystem::ServerFrameUpdatePostEntityThink()
  275. {
  276. }
  277. void CBaseToolSystem::ServerPreClientUpdate()
  278. {
  279. }
  280. void CBaseToolSystem::ServerPreSetupVisibility()
  281. {
  282. }
  283. const char* CBaseToolSystem::GetEntityData( const char *pActualEntityData )
  284. {
  285. return pActualEntityData;
  286. }
  287. void* CBaseToolSystem::QueryInterface( const char *pInterfaceName )
  288. {
  289. return NULL;
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Level init, shutdown for client
  293. //-----------------------------------------------------------------------------
  294. void CBaseToolSystem::ClientLevelInitPreEntity()
  295. {
  296. }
  297. void CBaseToolSystem::ClientLevelInitPostEntity()
  298. {
  299. }
  300. void CBaseToolSystem::ClientLevelShutdownPreEntity()
  301. {
  302. }
  303. void CBaseToolSystem::ClientLevelShutdownPostEntity()
  304. {
  305. }
  306. void CBaseToolSystem::ClientPreRender()
  307. {
  308. }
  309. void CBaseToolSystem::ClientPostRender()
  310. {
  311. }
  312. //-----------------------------------------------------------------------------
  313. // Tool activation/deactivation
  314. //-----------------------------------------------------------------------------
  315. void CBaseToolSystem::OnToolActivate()
  316. {
  317. m_bIsActive = true;
  318. UpdateUIVisibility( );
  319. // FIXME: Note that this is necessary because IsGameInputEnabled depends on m_bIsActive at the moment
  320. OnModeChanged();
  321. input()->SetModalSubTree( VGui_GetToolRootPanel(), GetVPanel(), IsGameInputEnabled() );
  322. input()->SetModalSubTreeReceiveMessages( !IsGameInputEnabled() );
  323. m_pToolUI->UpdateMenuBarTitle();
  324. }
  325. void CBaseToolSystem::OnToolDeactivate()
  326. {
  327. m_bIsActive = false;
  328. UpdateUIVisibility( );
  329. // FIXME: Note that this is necessary because IsGameInputEnabled depends on m_bIsActive at the moment
  330. OnModeChanged();
  331. input()->ReleaseModalSubTree();
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Let tool override key events (ie ESC and ~)
  335. //-----------------------------------------------------------------------------
  336. bool CBaseToolSystem::TrapKey( ButtonCode_t key, bool down )
  337. {
  338. // Don't hook keyboard if not topmost
  339. if ( !m_bIsActive )
  340. return false; // didn't trap, continue processing
  341. // This is a bit of a hack to work around the mouse capture bugs we seem to keep getting...
  342. if ( !IsGameInputEnabled() && key == KEY_ESCAPE )
  343. {
  344. vgui::input()->SetMouseCapture( NULL );
  345. }
  346. // If in fullscreen toolMode, don't let ECSAPE bring up the game menu
  347. if ( !m_bGameInputEnabled && m_bFullscreenMode && ( key == KEY_ESCAPE ) )
  348. return true; // trapping this key, stop processing
  349. if ( down )
  350. {
  351. if ( key == TOGGLE_WINDOWED_KEY_CODE )
  352. {
  353. SetMode( m_bGameInputEnabled, !m_bFullscreenMode );
  354. return true; // trapping this key, stop processing
  355. }
  356. if ( key == TOGGLE_INPUT_KEY_CODE )
  357. {
  358. if ( input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_RCONTROL ) )
  359. {
  360. ToggleForceToolCamera();
  361. }
  362. else
  363. {
  364. SetMode( !m_bGameInputEnabled, m_bFullscreenMode );
  365. }
  366. return true; // trapping this key, stop processing
  367. }
  368. // If in IFM mode, let ~ switch to gameMode and toggle console
  369. if ( !IsGameInputEnabled() && ( key == '~' || key == '`' ) )
  370. {
  371. SetMode( true, m_bFullscreenMode );
  372. return false; // didn't trap, continue processing
  373. }
  374. }
  375. return false; // didn't trap, continue processing
  376. }
  377. //-----------------------------------------------------------------------------
  378. // Shows, hides the tool ui (menu, client area, status bar)
  379. //-----------------------------------------------------------------------------
  380. void CBaseToolSystem::SetToolUIVisible( bool bVisible )
  381. {
  382. if ( bVisible != m_pToolUI->IsVisible() )
  383. {
  384. m_pToolUI->SetVisible( bVisible );
  385. m_pToolUI->InvalidateLayout();
  386. }
  387. }
  388. //-----------------------------------------------------------------------------
  389. // Computes whether vgui is visible or not
  390. //-----------------------------------------------------------------------------
  391. void CBaseToolSystem::UpdateUIVisibility()
  392. {
  393. bool bIsVisible = m_bIsActive && ( !IsGameInputEnabled() || !m_bFullscreenMode );
  394. ShowUI( bIsVisible );
  395. }
  396. //-----------------------------------------------------------------------------
  397. // Changes game input + fullscreen modes
  398. //-----------------------------------------------------------------------------
  399. void CBaseToolSystem::EnableFullscreenToolMode( bool bEnable )
  400. {
  401. m_bFullscreenToolModeEnabled = bEnable;
  402. }
  403. //-----------------------------------------------------------------------------
  404. // Changed whether camera is forced to be tool camera
  405. //-----------------------------------------------------------------------------
  406. void CBaseToolSystem::ToggleForceToolCamera()
  407. {
  408. }
  409. //-----------------------------------------------------------------------------
  410. // Changes game input + fullscreen modes
  411. //-----------------------------------------------------------------------------
  412. void CBaseToolSystem::SetMode( bool bGameInputEnabled, bool bFullscreen )
  413. {
  414. Assert( m_bIsActive );
  415. if ( !m_bFullscreenToolModeEnabled )
  416. {
  417. if ( !bGameInputEnabled )
  418. {
  419. bFullscreen = false;
  420. }
  421. }
  422. if ( ( m_bFullscreenMode == bFullscreen ) && ( m_bGameInputEnabled == bGameInputEnabled ) )
  423. return;
  424. bool bOldGameInputEnabled = m_bGameInputEnabled;
  425. m_bFullscreenMode = bFullscreen;
  426. m_bGameInputEnabled = bGameInputEnabled;
  427. UpdateUIVisibility();
  428. if ( bOldGameInputEnabled != m_bGameInputEnabled )
  429. {
  430. Warning( "Input is now being sent to the %s\n", m_bGameInputEnabled ? "Game" : "Tools" );
  431. // If switching from tool to game mode, release the mouse capture so that the
  432. // tool knows that it is going to miss mouse events that are handed to the game.
  433. if ( bGameInputEnabled == true )
  434. {
  435. input()->SetMouseCapture( NULL );
  436. }
  437. // The subtree starts at the tool system root panel. If game input is enabled then
  438. // the subtree should not receive or process input messages, otherwise it should
  439. Assert( input()->GetModalSubTree() );
  440. if ( input()->GetModalSubTree() )
  441. {
  442. input()->SetModalSubTreeReceiveMessages( !m_bGameInputEnabled );
  443. }
  444. enginetools->OnModeChanged( m_bGameInputEnabled );
  445. }
  446. if ( m_pToolUI )
  447. {
  448. m_pToolUI->UpdateMenuBarTitle();
  449. }
  450. OnModeChanged( );
  451. }
  452. //-----------------------------------------------------------------------------
  453. // Keybinding
  454. //-----------------------------------------------------------------------------
  455. void CBaseToolSystem::LoadKeyBindings()
  456. {
  457. ReloadKeyBindings( m_KeyBindingsHandle );
  458. }
  459. void CBaseToolSystem::ShowKeyBindingsEditor( Panel *panel, KeyBindingContextHandle_t handle )
  460. {
  461. if ( !m_hKeyBindingsEditor.Get() )
  462. {
  463. // Show the editor
  464. m_hKeyBindingsEditor = new CKeyBoardEditorDialog( GetClientArea(), panel, handle );
  465. m_hKeyBindingsEditor->DoModal();
  466. }
  467. }
  468. void CBaseToolSystem::ShowKeyBindingsHelp( Panel *panel, KeyBindingContextHandle_t handle, vgui::KeyCode boundKey, int modifiers )
  469. {
  470. if ( m_hKeyBindingsHelp.Get() )
  471. {
  472. m_hKeyBindingsHelp->HelpKeyPressed();
  473. return;
  474. }
  475. m_hKeyBindingsHelp = new CKeyBindingHelpDialog( GetClientArea(), panel, handle, boundKey, modifiers );
  476. }
  477. vgui::KeyBindingContextHandle_t CBaseToolSystem::GetKeyBindingsHandle()
  478. {
  479. return m_KeyBindingsHandle;
  480. }
  481. void CBaseToolSystem::OnEditKeyBindings()
  482. {
  483. Panel *tool = GetMostRecentlyFocusedTool();
  484. if ( tool )
  485. {
  486. ShowKeyBindingsEditor( tool, tool->GetKeyBindingsContext() );
  487. }
  488. }
  489. void CBaseToolSystem::OnKeyBindingHelp()
  490. {
  491. Panel *tool = GetMostRecentlyFocusedTool();
  492. if ( tool )
  493. {
  494. CUtlVector< BoundKey_t * > list;
  495. LookupBoundKeys( "keybindinghelp", list );
  496. if ( list.Count() > 0 )
  497. {
  498. ShowKeyBindingsHelp( tool, tool->GetKeyBindingsContext(), (KeyCode)list[ 0 ]->keycode, list[ 0 ]->modifiers );
  499. }
  500. }
  501. }
  502. //-----------------------------------------------------------------------------
  503. // Registers tool window
  504. //-----------------------------------------------------------------------------
  505. void CBaseToolSystem::RegisterToolWindow( vgui::PHandle hPanel )
  506. {
  507. int i = m_Tools.AddToTail( hPanel );
  508. m_Tools[i]->SetKeyBindingsContext( m_KeyBindingsHandle );
  509. }
  510. void CBaseToolSystem::UnregisterAllToolWindows()
  511. {
  512. m_Tools.RemoveAll();
  513. m_MostRecentlyFocused = NULL;
  514. }
  515. //-----------------------------------------------------------------------------
  516. // Destroys all tool windows containers
  517. //-----------------------------------------------------------------------------
  518. void CBaseToolSystem::DestroyToolContainers()
  519. {
  520. int c = ToolWindow::GetToolWindowCount();
  521. for ( int i = c - 1; i >= 0 ; --i )
  522. {
  523. ToolWindow *kill = ToolWindow::GetToolWindow( i );
  524. delete kill;
  525. }
  526. }
  527. Panel *CBaseToolSystem::GetMostRecentlyFocusedTool()
  528. {
  529. VPANEL focus = input()->GetFocus();
  530. int c = m_Tools.Count();
  531. for ( int i = 0; i < c; ++i )
  532. {
  533. Panel *p = m_Tools[ i ].Get();
  534. if ( !p )
  535. continue;
  536. // Not a visible tool
  537. if ( !p->GetParent() )
  538. continue;
  539. bool hasFocus = p->HasFocus();
  540. bool focusOnChild = focus && ipanel()->HasParent(focus, p->GetVPanel());
  541. if ( !hasFocus && !focusOnChild )
  542. {
  543. continue;
  544. }
  545. return p;
  546. }
  547. return m_MostRecentlyFocused.Get();
  548. }
  549. void CBaseToolSystem::PostMessageToActiveTool( KeyValues *pKeyValues, float flDelay )
  550. {
  551. Panel *pMostRecent = GetMostRecentlyFocusedTool();
  552. if ( pMostRecent )
  553. {
  554. Panel::PostMessage( pMostRecent->GetVPanel(), pKeyValues, flDelay );
  555. }
  556. }
  557. void CBaseToolSystem::PostMessageToActiveTool( const char *msg, float flDelay )
  558. {
  559. Panel *pMostRecent = GetMostRecentlyFocusedTool();
  560. if ( pMostRecent )
  561. {
  562. Panel::PostMessage( pMostRecent->GetVPanel(), new KeyValues( msg ), flDelay );
  563. }
  564. }
  565. void CBaseToolSystem::PostMessageToAllTools( KeyValues *message )
  566. {
  567. int nCount = enginetools->GetToolCount();
  568. for ( int i = 0; i < nCount; ++i )
  569. {
  570. IToolSystem *pToolSystem = const_cast<IToolSystem*>( enginetools->GetToolSystem( i ) );
  571. pToolSystem->PostToolMessage( HTOOLHANDLE_INVALID, message );
  572. }
  573. }
  574. void CBaseToolSystem::OnThink()
  575. {
  576. BaseClass::OnThink();
  577. VPANEL focus = input()->GetFocus();
  578. int c = m_Tools.Count();
  579. for ( int i = 0; i < c; ++i )
  580. {
  581. Panel *p = m_Tools[ i ].Get();
  582. if ( !p )
  583. continue;
  584. // Not a visible tool
  585. Panel *pPage = p->GetParent();
  586. if ( !pPage )
  587. continue;
  588. bool hasFocus = p->HasFocus();
  589. bool bFocusOnTab = false;
  590. bool focusOnChild = false;
  591. if ( !hasFocus )
  592. {
  593. PropertySheet *pSheet = dynamic_cast< PropertySheet * >( pPage );
  594. if ( pSheet )
  595. {
  596. Panel *pActiveTab = pSheet->GetActiveTab();
  597. if ( pActiveTab )
  598. {
  599. bFocusOnTab = ( ( focus == pActiveTab->GetVPanel() ) || // Tab itself has focus
  600. ipanel()->HasParent( focus, pActiveTab->GetVPanel() ) ); // Tab is parent of panel that has focus (in case we add subpanels to tabs)
  601. }
  602. }
  603. focusOnChild = focus && ipanel()->HasParent(focus, p->GetVPanel());
  604. }
  605. if ( !hasFocus && !focusOnChild && !bFocusOnTab )
  606. continue;
  607. if ( m_MostRecentlyFocused != p )
  608. {
  609. m_MostRecentlyFocused = p;
  610. }
  611. break;
  612. }
  613. }
  614. //-----------------------------------------------------------------------------
  615. // Let tool override viewport for engine
  616. //-----------------------------------------------------------------------------
  617. void CBaseToolSystem::AdjustEngineViewport( int& x, int& y, int& width, int& height )
  618. {
  619. if ( !m_hMiniViewport.Get() )
  620. return;
  621. bool enabled;
  622. int vpx, vpy, vpw, vph;
  623. m_hMiniViewport->GetViewport( enabled, vpx, vpy, vpw, vph );
  624. if ( !enabled )
  625. return;
  626. x = vpx;
  627. y = vpy;
  628. width = vpw;
  629. height = vph;
  630. }
  631. //-----------------------------------------------------------------------------
  632. // Let tool override view/camera
  633. //-----------------------------------------------------------------------------
  634. bool CBaseToolSystem::SetupEngineView( Vector &origin, QAngle &angles, float &fov )
  635. {
  636. return false;
  637. }
  638. //-----------------------------------------------------------------------------
  639. // Let tool override microphone
  640. //-----------------------------------------------------------------------------
  641. bool CBaseToolSystem::SetupAudioState( AudioState_t &audioState )
  642. {
  643. return false;
  644. }
  645. //-----------------------------------------------------------------------------
  646. // Should the game be allowed to render the view?
  647. //-----------------------------------------------------------------------------
  648. bool CBaseToolSystem::ShouldGameRenderView()
  649. {
  650. // Render through mini viewport unless in fullscreen mode
  651. if ( !IsVisible() )
  652. {
  653. return true;
  654. }
  655. if ( !m_hMiniViewport.Get() )
  656. return true;
  657. if ( !m_hMiniViewport->IsVisible() )
  658. {
  659. return true;
  660. }
  661. // Route through mini viewport
  662. return false;
  663. }
  664. bool CBaseToolSystem::ShouldGamePlaySounds()
  665. {
  666. return true;
  667. }
  668. bool CBaseToolSystem::IsThirdPersonCamera()
  669. {
  670. return false;
  671. }
  672. bool CBaseToolSystem::IsToolRecording()
  673. {
  674. return false;
  675. }
  676. IMaterialProxy *CBaseToolSystem::LookupProxy( const char *proxyName )
  677. {
  678. return NULL;
  679. }
  680. bool CBaseToolSystem::GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info )
  681. {
  682. // Always hearable (no changes)
  683. return true;
  684. }
  685. void CBaseToolSystem::HostRunFrameBegin()
  686. {
  687. }
  688. void CBaseToolSystem::HostRunFrameEnd()
  689. {
  690. }
  691. void CBaseToolSystem::RenderFrameBegin()
  692. {
  693. // If we can't see the engine window, do nothing
  694. if ( !IsVisible() || !IsActiveTool() )
  695. return;
  696. if ( !m_hMiniViewport.Get() || !m_hMiniViewport->IsVisible() )
  697. return;
  698. m_hMiniViewport->RenderFrameBegin();
  699. }
  700. void CBaseToolSystem::RenderFrameEnd()
  701. {
  702. }
  703. void CBaseToolSystem::VGui_PreRender( int paintMode )
  704. {
  705. }
  706. void CBaseToolSystem::VGui_PostRender( int paintMode )
  707. {
  708. }
  709. void CBaseToolSystem::VGui_PreSimulate()
  710. {
  711. if ( !m_bIsActive )
  712. return;
  713. // only show the gameUI when in gameMode
  714. vgui::VPANEL gameui = enginevgui->GetPanel( PANEL_GAMEUIDLL );
  715. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  716. vgui::VPANEL gameuiBackground = enginevgui->GetPanel( PANEL_GAMEUIBACKGROUND );
  717. #endif
  718. if ( gameui != 0 )
  719. {
  720. bool wantsToBeSeen = IsGameInputEnabled() && (enginetools->IsGamePaused() || !enginetools->IsInGame() || enginetools->IsConsoleVisible());
  721. vgui::ipanel()->SetVisible(gameui, wantsToBeSeen);
  722. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  723. vgui::ipanel()->SetVisible(gameuiBackground, wantsToBeSeen);
  724. #endif
  725. }
  726. // if there's no map loaded and we're in fullscreen toolMode, switch to gameMode
  727. // otherwise there's nothing to see or do...
  728. if ( !IsGameInputEnabled() && !IsVisible() && !enginetools->IsInGame() )
  729. {
  730. SetMode( true, m_bFullscreenMode );
  731. }
  732. }
  733. void CBaseToolSystem::VGui_PostSimulate()
  734. {
  735. }
  736. const char *CBaseToolSystem::MapName() const
  737. {
  738. return enginetools->GetCurrentMap();
  739. }
  740. //-----------------------------------------------------------------------------
  741. // Shows or hides the UI
  742. //-----------------------------------------------------------------------------
  743. bool CBaseToolSystem::ShowUI( bool bVisible )
  744. {
  745. bool bPrevVisible = IsVisible();
  746. if ( bPrevVisible == bVisible )
  747. return bPrevVisible;
  748. SetMouseInputEnabled( bVisible );
  749. SetVisible( bVisible );
  750. // Hide loading image if using bx movie UI
  751. // A bit of a hack because it more or less tunnels through to the client .dll, but the moviemaker assumes
  752. // single player anyway...
  753. if ( bVisible )
  754. {
  755. ConVar *pCv = ( ConVar * )cvar->FindVar( "cl_showpausedimage" );
  756. if ( pCv )
  757. {
  758. pCv->SetValue( 0 );
  759. }
  760. }
  761. return bPrevVisible;
  762. }
  763. //-----------------------------------------------------------------------------
  764. // Gets the action target to sent to panels so that the tool system's OnCommand is called
  765. //-----------------------------------------------------------------------------
  766. vgui::Panel *CBaseToolSystem::GetActionTarget()
  767. {
  768. return this;
  769. }
  770. //-----------------------------------------------------------------------------
  771. // Derived classes implement this to create a custom menubar
  772. //-----------------------------------------------------------------------------
  773. vgui::MenuBar *CBaseToolSystem::CreateMenuBar(CBaseToolSystem *pParent )
  774. {
  775. return new vgui::MenuBar( pParent, "ToolMenuBar" );
  776. }
  777. //-----------------------------------------------------------------------------
  778. // Purpose: Derived classes implement this to create a custom status bar, or return NULL for no status bar
  779. //-----------------------------------------------------------------------------
  780. vgui::Panel *CBaseToolSystem::CreateStatusBar( vgui::Panel *pParent )
  781. {
  782. return new CBaseStatusBar( this, "Status Bar" );
  783. }
  784. //-----------------------------------------------------------------------------
  785. // Gets at the action menu
  786. //-----------------------------------------------------------------------------
  787. vgui::Menu *CBaseToolSystem::GetActionMenu()
  788. {
  789. return m_hActionMenu;
  790. }
  791. //-----------------------------------------------------------------------------
  792. // Returns the client area
  793. //-----------------------------------------------------------------------------
  794. vgui::Panel* CBaseToolSystem::GetClientArea()
  795. {
  796. return m_pToolUI->GetClientArea();
  797. }
  798. //-----------------------------------------------------------------------------
  799. // Returns the menu bar
  800. //-----------------------------------------------------------------------------
  801. vgui::MenuBar* CBaseToolSystem::GetMenuBar()
  802. {
  803. return m_pToolUI->GetMenuBar();
  804. }
  805. //-----------------------------------------------------------------------------
  806. // Returns the status bar
  807. //-----------------------------------------------------------------------------
  808. vgui::Panel* CBaseToolSystem::GetStatusBar()
  809. {
  810. return m_pToolUI->GetStatusBar();
  811. }
  812. //-----------------------------------------------------------------------------
  813. // Pops up the action menu
  814. //-----------------------------------------------------------------------------
  815. void CBaseToolSystem::OnMousePressed( vgui::MouseCode code )
  816. {
  817. if ( code == MOUSE_RIGHT )
  818. {
  819. InitActionMenu();
  820. }
  821. else
  822. {
  823. BaseClass::OnMousePressed( code );
  824. }
  825. }
  826. //-----------------------------------------------------------------------------
  827. // Creates the action menu
  828. //-----------------------------------------------------------------------------
  829. void CBaseToolSystem::InitActionMenu()
  830. {
  831. ShutdownActionMenu();
  832. // Let the tool system create the action menu
  833. m_hActionMenu = CreateActionMenu( this );
  834. if ( m_hActionMenu.Get() )
  835. {
  836. m_hActionMenu->SetVisible(true);
  837. PositionActionMenu();
  838. m_hActionMenu->RequestFocus();
  839. }
  840. }
  841. //-----------------------------------------------------------------------------
  842. // Destroy action menu
  843. //-----------------------------------------------------------------------------
  844. void CBaseToolSystem::ShutdownActionMenu()
  845. {
  846. if ( m_hActionMenu.Get() )
  847. {
  848. m_hActionMenu->MarkForDeletion();
  849. m_hActionMenu = NULL;
  850. }
  851. }
  852. void CBaseToolSystem::UpdateMenu( vgui::Menu *menu )
  853. {
  854. // Nothing
  855. }
  856. //-----------------------------------------------------------------------------
  857. // Positions the action menu when it's time to pop it up
  858. //-----------------------------------------------------------------------------
  859. void CBaseToolSystem::PositionActionMenu()
  860. {
  861. // get cursor position, this is local to this text edit window
  862. int cursorX, cursorY;
  863. input()->GetCursorPos(cursorX, cursorY);
  864. // relayout the menu immediately so that we know it's size
  865. m_hActionMenu->InvalidateLayout(true);
  866. // Get the menu size
  867. int menuWide, menuTall;
  868. m_hActionMenu->GetSize( menuWide, menuTall );
  869. // work out where the cursor is and therefore the best place to put the menu
  870. int wide, tall;
  871. GetSize( wide, tall );
  872. if (wide - menuWide > cursorX)
  873. {
  874. // menu hanging right
  875. if (tall - menuTall > cursorY)
  876. {
  877. // menu hanging down
  878. m_hActionMenu->SetPos(cursorX, cursorY);
  879. }
  880. else
  881. {
  882. // menu hanging up
  883. m_hActionMenu->SetPos(cursorX, cursorY - menuTall);
  884. }
  885. }
  886. else
  887. {
  888. // menu hanging left
  889. if (tall - menuTall > cursorY)
  890. {
  891. // menu hanging down
  892. m_hActionMenu->SetPos(cursorX - menuWide, cursorY);
  893. }
  894. else
  895. {
  896. // menu hanging up
  897. m_hActionMenu->SetPos(cursorX - menuWide, cursorY - menuTall);
  898. }
  899. }
  900. }
  901. //-----------------------------------------------------------------------------
  902. // Handles the clear recent files message
  903. //-----------------------------------------------------------------------------
  904. void CBaseToolSystem::OnClearRecent()
  905. {
  906. m_RecentFiles.Clear();
  907. m_RecentFiles.SaveToRegistry( GetRegistryName() );
  908. }
  909. //-----------------------------------------------------------------------------
  910. // Called by the file open state machine
  911. //-----------------------------------------------------------------------------
  912. void CBaseToolSystem::OnFileStateMachineFinished( KeyValues *pKeyValues )
  913. {
  914. KeyValues *pContext = pKeyValues->GetFirstTrueSubKey();
  915. bool bWroteFile = pKeyValues->GetInt( "wroteFile", 0 ) != 0;
  916. vgui::FileOpenStateMachine::CompletionState_t state = (vgui::FileOpenStateMachine::CompletionState_t)pKeyValues->GetInt( "completionState", vgui::FileOpenStateMachine::IN_PROGRESS );
  917. const char *pFileType = pKeyValues->GetString( "fileType" );
  918. OnFileOperationCompleted( pFileType, bWroteFile, state, pContext );
  919. }
  920. //-----------------------------------------------------------------------------
  921. // Show the File browser dialog
  922. //-----------------------------------------------------------------------------
  923. void CBaseToolSystem::OpenFile( const char *pOpenFileType, const char *pSaveFileName, const char *pSaveFileType, int nFlags, KeyValues *pContextKeyValues )
  924. {
  925. m_pFileOpenStateMachine->OpenFile( pOpenFileType, pContextKeyValues, pSaveFileName, pSaveFileType, nFlags );
  926. }
  927. void CBaseToolSystem::OpenFile( const char *pOpenFileName, const char *pOpenFileType, const char *pSaveFileName, const char *pSaveFileType, int nFlags, KeyValues *pContextKeyValues )
  928. {
  929. m_pFileOpenStateMachine->OpenFile( pOpenFileName, pOpenFileType, pContextKeyValues, pSaveFileName, pSaveFileType, nFlags );
  930. }
  931. //-----------------------------------------------------------------------------
  932. // Used to save a specified file, and deal with all the lovely dialogs
  933. //-----------------------------------------------------------------------------
  934. void CBaseToolSystem::SaveFile( const char *pFileName, const char *pFileType, int nFlags, KeyValues *pContextKeyValues )
  935. {
  936. m_pFileOpenStateMachine->SaveFile( pContextKeyValues, pFileName, pFileType, nFlags );
  937. }
  938. //-----------------------------------------------------------------------------
  939. // Paints the background
  940. //-----------------------------------------------------------------------------
  941. void CBaseToolSystem::PaintBackground()
  942. {
  943. int w, h;
  944. GetSize( w, h );
  945. int x, y;
  946. GetPos( x, y );
  947. LocalToScreen( x, y );
  948. CMatRenderContextPtr pRenderContext( materials );
  949. if ( m_pBackground )
  950. {
  951. int texWide = m_pBackground->GetMappingWidth();
  952. int texTall = m_pBackground->GetMappingHeight();
  953. float maxu = (float)w / (float)texWide;
  954. float maxv = (float)h / (float)texTall;
  955. RenderQuad( m_pBackground, x, y, w, h, surface()->GetZPos(), 0.0f, 0.0f, maxu, maxv, Color( 255, 255, 255, 255 ) );
  956. }
  957. bool hasDoc = HasDocument();
  958. if ( m_pLogo )
  959. {
  960. int texWide = m_pLogo->GetMappingWidth();
  961. float logoAspectRatio = 0.442;
  962. if ( hasDoc )
  963. {
  964. int logoW = texWide / 2;
  965. int logoH = logoW * logoAspectRatio;
  966. x = w - logoW - 15;
  967. y = h - logoH - 30;
  968. w = logoW;
  969. h = logoH;
  970. }
  971. else
  972. {
  973. int logoW = texWide;
  974. int logoH = logoW * logoAspectRatio;
  975. x = ( w - logoW ) / 2;
  976. y = ( h - logoH ) / 2;
  977. w = logoW;
  978. h = logoH;
  979. }
  980. int alpha = hasDoc ? 0 : 255;
  981. RenderQuad( m_pLogo, x, y, w, h, surface()->GetZPos(), 0.0f, 0.0f, 1.0f, 1.0f, Color( 255, 255, 255, alpha ) );
  982. }
  983. }
  984. const char *CBaseToolSystem::GetBackgroundTextureName()
  985. {
  986. return "vgui/tools/ifm/ifm_background";
  987. }
  988. bool CBaseToolSystem::HasDocument()
  989. {
  990. return false;
  991. }
  992. CMiniViewport *CBaseToolSystem::CreateMiniViewport( vgui::Panel *parent )
  993. {
  994. int w, h;
  995. surface()->GetScreenSize( w, h );
  996. CMiniViewport *vp = new CMiniViewport( parent, "MiniViewport" );
  997. Assert( vp );
  998. vp->SetVisible( true );
  999. int menuBarHeight = 28;
  1000. int titleBarHeight = 22;
  1001. int offset = 4;
  1002. vp->SetBounds( ( 2 * w / 3 ) - offset, menuBarHeight + offset, w / 3, h / 3 + titleBarHeight);
  1003. return vp;
  1004. }
  1005. void CBaseToolSystem::ComputeMenuBarTitle( char *buf, size_t buflen )
  1006. {
  1007. Q_snprintf( buf, buflen, ": %s [ %s - Switch Mode ] [ %s - Full Screen ]", IsGameInputEnabled() ? "Game Mode" : "Tool Mode", TOGGLE_INPUT_KEY_NAME, TOGGLE_WINDOWED_KEY_NAME );
  1008. }
  1009. void CBaseToolSystem::OnUnhandledMouseClick( int code )
  1010. {
  1011. if ( (MouseCode)code == MOUSE_LEFT )
  1012. {
  1013. // If tool ui is visible and we're running game in a window
  1014. // and they click on the ifm it'll be unhandled, but in this case
  1015. // we'll switch back to the IFM mode
  1016. if ( !IsFullscreen() && IsGameInputEnabled() )
  1017. {
  1018. SetMode( false, m_bFullscreenMode );
  1019. }
  1020. }
  1021. }