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.

980 lines
23 KiB

  1. //========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Client DLL VGUI2 Viewport
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #pragma warning( disable : 4800 ) // disable forcing int to bool performance warning
  14. #include "cbase.h"
  15. #include <cdll_client_int.h>
  16. #include <cdll_util.h>
  17. #include <globalvars_base.h>
  18. // VGUI panel includes
  19. #include <vgui_controls/Panel.h>
  20. #include <vgui_controls/AnimationController.h>
  21. #include <vgui/ISurface.h>
  22. #include <keyvalues.h>
  23. #include <vgui/IScheme.h>
  24. #include <vgui/IVGui.h>
  25. #include <vgui/ILocalize.h>
  26. #include <vgui/IPanel.h>
  27. #include <vgui_controls/Button.h>
  28. #include <igameresources.h>
  29. // sub dialogs
  30. #include "clientscoreboarddialog.h"
  31. #include "spectatorgui.h"
  32. #include "teammenu.h"
  33. #include "vguitextwindow.h"
  34. #include "IGameUIFuncs.h"
  35. #include "mapoverview.h"
  36. #include "hud.h"
  37. #include "NavProgress.h"
  38. #include "commentary_modelviewer.h"
  39. // our definition
  40. #include "baseviewport.h"
  41. #include <filesystem.h>
  42. #include <convar.h>
  43. #include "ienginevgui.h"
  44. #include "iclientmode.h"
  45. #include "vgui_int.h"
  46. #ifdef PORTAL2
  47. #include "radialmenu.h"
  48. #include "vgui/portal_stats_panel.h"
  49. #endif // PORTAL2
  50. // memdbgon must be the last include file in a .cpp file!!!
  51. #include "tier0/memdbgon.h"
  52. static IViewPort *s_pFullscreenViewportInterface;
  53. static IViewPort *s_pViewportInterfaces[ MAX_SPLITSCREEN_PLAYERS ];
  54. IViewPort *GetViewPortInterface()
  55. {
  56. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  57. return s_pViewportInterfaces[ GET_ACTIVE_SPLITSCREEN_SLOT() ];
  58. }
  59. IViewPort *GetFullscreenViewPortInterface()
  60. {
  61. return s_pFullscreenViewportInterface;
  62. }
  63. vgui::Panel *g_lastPanel = NULL; // used for mouseover buttons, keeps track of the last active panel
  64. vgui::Button *g_lastButton = NULL; // used for mouseover buttons, keeps track of the last active button
  65. using namespace vgui;
  66. ConVar hud_autoreloadscript("hud_autoreloadscript", "0", FCVAR_NONE, "Automatically reloads the animation script each time one is ran");
  67. static ConVar cl_leveloverviewmarker( "cl_leveloverviewmarker", "0", FCVAR_CHEAT );
  68. CON_COMMAND( showpanel, "Shows a viewport panel <name>" )
  69. {
  70. if ( !GetViewPortInterface() )
  71. return;
  72. if ( args.ArgC() != 2 )
  73. return;
  74. GetViewPortInterface()->ShowPanel( args[ 1 ], true );
  75. }
  76. CON_COMMAND( hidepanel, "Hides a viewport panel <name>" )
  77. {
  78. if ( !GetViewPortInterface() )
  79. return;
  80. if ( args.ArgC() != 2 )
  81. return;
  82. GetViewPortInterface()->ShowPanel( args[ 1 ], false );
  83. }
  84. /* global helper functions
  85. bool Helper_LoadFile( IBaseFileSystem *pFileSystem, const char *pFilename, CUtlVector<char> &buf )
  86. {
  87. FileHandle_t hFile = pFileSystem->Open( pFilename, "rt" );
  88. if ( hFile == FILESYSTEM_INVALID_HANDLE )
  89. {
  90. Warning( "Helper_LoadFile: missing %s\n", pFilename );
  91. return false;
  92. }
  93. unsigned long len = pFileSystem->Size( hFile );
  94. buf.SetSize( len );
  95. pFileSystem->Read( buf.Base(), buf.Count(), hFile );
  96. pFileSystem->Close( hFile );
  97. return true;
  98. } */
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. // Output : Returns true on success, false on failure.
  102. //-----------------------------------------------------------------------------
  103. bool CBaseViewport::LoadHudAnimations( void )
  104. {
  105. const char *HUDANIMATION_MANIFEST_FILE = "scripts/hudanimations_manifest.txt";
  106. KeyValues *manifest = new KeyValues( HUDANIMATION_MANIFEST_FILE );
  107. if ( manifest->LoadFromFile( g_pFullFileSystem, HUDANIMATION_MANIFEST_FILE, "GAME" ) == false )
  108. {
  109. manifest->deleteThis();
  110. return false;
  111. }
  112. bool bClearScript = true;
  113. // Load each file defined in the text
  114. for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
  115. {
  116. if ( !Q_stricmp( sub->GetName(), "file" ) )
  117. {
  118. // Add it
  119. if ( m_pAnimController->SetScriptFile( GetVPanel(), sub->GetString(), bClearScript ) == false )
  120. {
  121. Assert( 0 );
  122. }
  123. bClearScript = false;
  124. continue;
  125. }
  126. }
  127. manifest->deleteThis();
  128. return true;
  129. }
  130. //================================================================
  131. CBaseViewport::CBaseViewport() : vgui::EditablePanel( NULL, "CBaseViewport" )
  132. {
  133. SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
  134. m_bInitialized = false;
  135. m_bFullscreenViewport = false;
  136. m_GameuiFuncs = NULL;
  137. m_GameEventManager = NULL;
  138. SetKeyBoardInputEnabled( false );
  139. SetMouseInputEnabled( false );
  140. m_pBackGround = NULL;
  141. m_bHasParent = false;
  142. m_pActivePanel = NULL;
  143. #if !defined( CSTRIKE15 )
  144. m_pLastActivePanel = NULL;
  145. #endif
  146. g_lastPanel = NULL;
  147. m_OldSize[ 0 ] = m_OldSize[ 1 ] = -1;
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Purpose:
  151. //-----------------------------------------------------------------------------
  152. vgui::VPANEL CBaseViewport::GetSchemeSizingVPanel( void )
  153. {
  154. return VGui_GetFullscreenRootVPANEL();
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Purpose: Updates hud to handle the new screen size
  158. //-----------------------------------------------------------------------------
  159. void CBaseViewport::OnScreenSizeChanged(int iOldWide, int iOldTall)
  160. {
  161. BaseClass::OnScreenSizeChanged(iOldWide, iOldTall);
  162. IViewPortPanel* pSpecGuiPanel = FindPanelByName(PANEL_SPECGUI);
  163. bool bSpecGuiWasVisible = pSpecGuiPanel && pSpecGuiPanel->IsVisible();
  164. // reload the script file, so the screen positions in it are correct for the new resolution
  165. ReloadScheme( NULL );
  166. // recreate all the default panels
  167. RemoveAllPanels();
  168. m_pBackGround = new CBackGroundPanel( NULL );
  169. m_pBackGround->SetZPos( -20 ); // send it to the back
  170. m_pBackGround->SetVisible( false );
  171. if ( !IsFullscreenViewport() )
  172. {
  173. CreateDefaultPanels();
  174. }
  175. vgui::ipanel()->MoveToBack( m_pBackGround->GetVPanel() ); // really send it to the back
  176. // hide all panels when reconnecting
  177. ShowPanel( PANEL_ALL, false );
  178. // re-enable the spectator gui if it was previously visible
  179. if ( bSpecGuiWasVisible )
  180. {
  181. ShowPanel( PANEL_SPECGUI, true );
  182. }
  183. }
  184. void CBaseViewport::CreateDefaultPanels( void )
  185. {
  186. #ifdef PORTAL2
  187. AddNewPanel( CreatePanelByName( PANEL_RADIAL_MENU ), "PANEL_RADIAL_MENU" );
  188. #endif // PORTAL2
  189. AddNewPanel( CreatePanelByName( PANEL_SCOREBOARD ), "PANEL_SCOREBOARD" );
  190. AddNewPanel( CreatePanelByName( PANEL_INFO ), "PANEL_INFO" );
  191. AddNewPanel( CreatePanelByName( PANEL_SPECGUI ), "PANEL_SPECGUI" );
  192. AddNewPanel( CreatePanelByName( PANEL_SPECMENU ), "PANEL_SPECMENU" );
  193. AddNewPanel( CreatePanelByName( PANEL_NAV_PROGRESS ), "PANEL_NAV_PROGRESS" );
  194. }
  195. void CBaseViewport::UpdateAllPanels( void )
  196. {
  197. ACTIVE_SPLITSCREEN_PLAYER_GUARD_VGUI( vgui::ipanel()->GetMessageContextId( GetVPanel() ) );
  198. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  199. {
  200. IViewPortPanel *p = m_UnorderedPanels[i];
  201. if ( p->IsVisible() )
  202. {
  203. p->Update();
  204. }
  205. }
  206. }
  207. IViewPortPanel* CBaseViewport::CreatePanelByName(const char *szPanelName)
  208. {
  209. IViewPortPanel* newpanel = NULL;
  210. if ( Q_strcmp(PANEL_SCOREBOARD, szPanelName) == 0 )
  211. {
  212. newpanel = new CClientScoreBoardDialog( this );
  213. }
  214. else if ( Q_strcmp(PANEL_INFO, szPanelName) == 0 )
  215. {
  216. newpanel = new CTextWindow( this );
  217. }
  218. /* else if ( Q_strcmp(PANEL_OVERVIEW, szPanelName) == 0 )
  219. {
  220. newpanel = new CMapOverview( this );
  221. }
  222. */
  223. //else if ( Q_strcmp(PANEL_TEAM, szPanelName) == 0 )
  224. //{
  225. // newpanel = new CTeamMenu( this );
  226. //}
  227. else if ( Q_strcmp(PANEL_NAV_PROGRESS, szPanelName) == 0 )
  228. {
  229. newpanel = new CNavProgress( this );
  230. }
  231. #ifdef PORTAL2
  232. else if ( Q_strcmp( PANEL_RADIAL_MENU, szPanelName ) == 0 )
  233. {
  234. newpanel = new CRadialMenuPanel( this );
  235. }
  236. #endif // PORTAL2
  237. if ( Q_strcmp(PANEL_COMMENTARY_MODELVIEWER, szPanelName) == 0 )
  238. {
  239. newpanel = new CCommentaryModelViewer( this );
  240. }
  241. return newpanel;
  242. }
  243. bool CBaseViewport::AddNewPanel( IViewPortPanel* pPanel, char const *pchDebugName )
  244. {
  245. if ( !pPanel )
  246. {
  247. return false;
  248. }
  249. // we created a new panel, initialize it
  250. if ( FindPanelByName( pPanel->GetName() ) != NULL )
  251. {
  252. DevMsg("CBaseViewport::AddNewPanel: panel with name '%s' already exists.\n", pPanel->GetName() );
  253. return false;
  254. }
  255. m_Panels.Insert( pPanel->GetName(), pPanel );
  256. pPanel->SetParent( GetVPanel() );
  257. m_UnorderedPanels.AddToTail( pPanel );
  258. return true;
  259. }
  260. IViewPortPanel* CBaseViewport::FindPanelByName(const char *szPanelName)
  261. {
  262. int idx = m_Panels.Find( szPanelName );
  263. if ( idx == m_Panels.InvalidIndex() )
  264. return NULL;
  265. return m_Panels[ idx ];
  266. }
  267. void CBaseViewport::PostMessageToPanel( IViewPortPanel* pPanel, KeyValues *pKeyValues )
  268. {
  269. PostMessage( pPanel->GetVPanel(), pKeyValues );
  270. }
  271. void CBaseViewport::PostMessageToPanel( const char *pName, KeyValues *pKeyValues )
  272. {
  273. if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
  274. {
  275. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  276. {
  277. IViewPortPanel *p = m_UnorderedPanels[i];
  278. PostMessageToPanel( p, pKeyValues );
  279. }
  280. return;
  281. }
  282. IViewPortPanel * panel = NULL;
  283. if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
  284. {
  285. panel = m_pActivePanel;
  286. }
  287. else
  288. {
  289. panel = FindPanelByName( pName );
  290. }
  291. if ( !panel )
  292. return;
  293. PostMessageToPanel( panel, pKeyValues );
  294. }
  295. void CBaseViewport::ShowPanel( const char *pName, bool state, KeyValues *data, bool autoDeleteData )
  296. {
  297. if ( !data )
  298. {
  299. ShowPanel( pName, state );
  300. return;
  301. }
  302. // Also try to show the panel in the full screen viewport
  303. if ( this != s_pFullscreenViewportInterface )
  304. {
  305. GetFullscreenViewPortInterface()->ShowPanel( pName, state, data, false );
  306. }
  307. IViewPortPanel *panel = FindPanelByName( pName );
  308. if ( panel )
  309. {
  310. panel->SetData( data );
  311. GetViewPortInterface()->ShowPanel( panel, state );
  312. }
  313. if ( autoDeleteData )
  314. {
  315. data->deleteThis();
  316. }
  317. }
  318. void CBaseViewport::ShowPanel( const char *pName, bool state )
  319. {
  320. // Also try to show the panel in the full screen viewport
  321. if ( this != s_pFullscreenViewportInterface )
  322. {
  323. GetFullscreenViewPortInterface()->ShowPanel( pName, state );
  324. }
  325. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  326. if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
  327. {
  328. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  329. {
  330. IViewPortPanel *p = m_UnorderedPanels[i];
  331. ShowPanel( p, state );
  332. }
  333. return;
  334. }
  335. IViewPortPanel * panel = NULL;
  336. if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
  337. {
  338. panel = m_pActivePanel;
  339. }
  340. else
  341. {
  342. panel = FindPanelByName( pName );
  343. }
  344. if ( !panel )
  345. return;
  346. ShowPanel( panel, state );
  347. }
  348. void CBaseViewport::ShowPanel( IViewPortPanel* pPanel, bool state )
  349. {
  350. // Extra guard to get layout stuff correct
  351. ACTIVE_SPLITSCREEN_PLAYER_GUARD_VGUI( GET_ACTIVE_SPLITSCREEN_SLOT() );
  352. if ( state )
  353. {
  354. // if this is an 'active' panel, deactivate old active panel
  355. if ( pPanel->HasInputElements() )
  356. {
  357. // don't show input panels during normal demo playback
  358. if ( engine->IsPlayingDemo() && !g_bEngineIsHLTV
  359. #if defined( REPLAY_ENABLED )
  360. && !engine->IsReplay()
  361. #endif
  362. )
  363. return;
  364. if ( (m_pActivePanel != NULL) && (m_pActivePanel != pPanel) && (m_pActivePanel->IsVisible()) )
  365. {
  366. // store a pointer to the currently active panel
  367. // so we can restore it later
  368. if ( pPanel->CanReplace( m_pActivePanel->GetName() ) )
  369. {
  370. #if !defined( CSTRIKE15 )
  371. m_pLastActivePanel = m_pActivePanel;
  372. #endif
  373. #ifdef CSTRIKE15
  374. // in cs, if the scoreboard tries to hide the spectator via this method, just skip it
  375. IViewPortPanel* pSpecGuiPanel = FindPanelByName(PANEL_SPECGUI);
  376. if ( pSpecGuiPanel != m_pActivePanel )
  377. {
  378. SFDevMsg("CBaseViewport::ShowPanel(0) %s\n", m_pActivePanel->GetName());
  379. m_pActivePanel->ShowPanel( false );
  380. }
  381. #else
  382. SFDevMsg("CBaseViewport::ShowPanel(0) %s\n", m_pActivePanel->GetName());
  383. m_pActivePanel->ShowPanel( false );
  384. #endif
  385. }
  386. else
  387. {
  388. #if !defined( CSTRIKE15 )
  389. m_pLastActivePanel = pPanel;
  390. #endif
  391. return;
  392. }
  393. }
  394. m_pActivePanel = pPanel;
  395. }
  396. }
  397. else
  398. {
  399. // if this is our current active panel
  400. // update m_pActivePanel pointer
  401. if ( m_pActivePanel == pPanel )
  402. {
  403. m_pActivePanel = NULL;
  404. }
  405. #if !defined( CSTRIKE15 )
  406. // restore the previous active panel if it exists
  407. if( m_pLastActivePanel )
  408. {
  409. m_pActivePanel = m_pLastActivePanel;
  410. m_pLastActivePanel = NULL;
  411. SFDevMsg("CBaseViewport::ShowPanel(1) %s\n", m_pActivePanel->GetName());
  412. m_pActivePanel->ShowPanel( true );
  413. }
  414. #endif
  415. }
  416. // just show/hide panel
  417. SFDevMsg("CBaseViewport::ShowPanel(%d) %s\n", (int)state, pPanel->GetName());
  418. pPanel->ShowPanel( state );
  419. UpdateAllPanels(); // let other panels rearrange
  420. }
  421. IViewPortPanel* CBaseViewport::GetActivePanel( void )
  422. {
  423. return m_pActivePanel;
  424. }
  425. void CBaseViewport::RecreatePanel( const char *szPanelName )
  426. {
  427. IViewPortPanel *panel = FindPanelByName( szPanelName );
  428. if ( panel )
  429. {
  430. m_Panels.Remove( szPanelName );
  431. for ( int i = m_UnorderedPanels.Count() - 1; i >= 0; --i )
  432. {
  433. if ( m_UnorderedPanels[ i ] == panel )
  434. {
  435. m_UnorderedPanels.Remove( i );
  436. break;
  437. }
  438. }
  439. vgui::VPANEL vPanel = panel->GetVPanel();
  440. if ( vPanel )
  441. {
  442. vgui::ipanel()->DeletePanel( vPanel );
  443. }
  444. else
  445. {
  446. delete panel;
  447. }
  448. if ( m_pActivePanel == panel )
  449. {
  450. m_pActivePanel = NULL;
  451. }
  452. #if !defined( CSTRIKE15 )
  453. if ( m_pLastActivePanel == panel )
  454. {
  455. m_pLastActivePanel = NULL;
  456. }
  457. #endif
  458. AddNewPanel( CreatePanelByName( szPanelName ), szPanelName );
  459. }
  460. }
  461. void CBaseViewport::RemoveAllPanels( void)
  462. {
  463. g_lastPanel = NULL;
  464. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  465. {
  466. IViewPortPanel *p = m_UnorderedPanels[i];
  467. vgui::VPANEL vPanel = p->GetVPanel();
  468. if ( vPanel )
  469. {
  470. vgui::ipanel()->DeletePanel( vPanel );
  471. }
  472. else
  473. {
  474. delete p;
  475. }
  476. }
  477. if ( m_pBackGround )
  478. {
  479. m_pBackGround->MarkForDeletion();
  480. m_pBackGround = NULL;
  481. }
  482. m_Panels.RemoveAll();
  483. m_UnorderedPanels.RemoveAll();
  484. m_pActivePanel = NULL;
  485. #if !defined( CSTRIKE15 )
  486. m_pLastActivePanel = NULL;
  487. #endif
  488. }
  489. CBaseViewport::~CBaseViewport()
  490. {
  491. m_bInitialized = false;
  492. if ( !m_bHasParent && m_pBackGround )
  493. {
  494. m_pBackGround->MarkForDeletion();
  495. }
  496. m_pBackGround = NULL;
  497. RemoveAllPanels();
  498. }
  499. void CBaseViewport::InitViewportSingletons( void )
  500. {
  501. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  502. s_pViewportInterfaces[ GET_ACTIVE_SPLITSCREEN_SLOT() ] = this;
  503. }
  504. //-----------------------------------------------------------------------------
  505. // Purpose: called when the VGUI subsystem starts up
  506. // Creates the sub panels and initialises them
  507. //-----------------------------------------------------------------------------
  508. void CBaseViewport::Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 * pGameEventManager )
  509. {
  510. InitViewportSingletons();
  511. m_GameuiFuncs = pGameUIFuncs;
  512. m_GameEventManager = pGameEventManager;
  513. m_pBackGround = new CBackGroundPanel( NULL );
  514. m_pBackGround->SetZPos( -20 ); // send it to the back
  515. m_pBackGround->SetVisible( false );
  516. ListenForGameEvent( "game_newmap" );
  517. SetScheme( "ClientScheme" );
  518. SetProportional( true );
  519. if ( !IsFullscreenViewport() )
  520. {
  521. CreateDefaultPanels();
  522. }
  523. m_pAnimController = new vgui::AnimationController(this);
  524. // create our animation controller
  525. m_pAnimController->SetScheme( GetScheme() );
  526. m_pAnimController->SetProportional(true);
  527. // Attempt to load all hud animations
  528. if ( LoadHudAnimations() == false )
  529. {
  530. // Fall back to just the main
  531. if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
  532. {
  533. Assert(0);
  534. }
  535. }
  536. m_bInitialized = true;
  537. }
  538. /*
  539. //-----------------------------------------------------------------------------
  540. // Purpose: Updates the spectator panel with new player info
  541. //-----------------------------------------------------------------------------
  542. void CBaseViewport::UpdateSpectatorPanel()
  543. {
  544. char bottomText[128];
  545. int player = -1;
  546. const char *name;
  547. Q_snprintf(bottomText,sizeof( bottomText ), "#Spec_Mode%d", m_pClientDllInterface->SpectatorMode() );
  548. m_pClientDllInterface->CheckSettings();
  549. // check if we're locked onto a target, show the player's name
  550. if ( (m_pClientDllInterface->SpectatorTarget() > 0) && (m_pClientDllInterface->SpectatorTarget() <= m_pClientDllInterface->GetMaxPlayers()) && (m_pClientDllInterface->SpectatorMode() != OBS_ROAMING) )
  551. {
  552. player = m_pClientDllInterface->SpectatorTarget();
  553. }
  554. // special case in free map and inset off, don't show names
  555. if ( ((m_pClientDllInterface->SpectatorMode() == OBS_MAP_FREE) && !m_pClientDllInterface->PipInsetOff()) || player == -1 )
  556. name = NULL;
  557. else
  558. name = m_pClientDllInterface->GetPlayerInfo(player).name;
  559. // create player & health string
  560. if ( player && name )
  561. {
  562. Q_strncpy( bottomText, name, sizeof( bottomText ) );
  563. }
  564. char szMapName[64];
  565. Q_FileBase( const_cast<char *>(m_pClientDllInterface->GetLevelName()), szMapName );
  566. m_pSpectatorGUI->Update(bottomText, player, m_pClientDllInterface->SpectatorMode(), m_pClientDllInterface->IsSpectateOnly(), m_pClientDllInterface->SpectatorNumber(), szMapName );
  567. m_pSpectatorGUI->UpdateSpectatorPlayerList();
  568. } */
  569. // Return TRUE if the HUD's allowed to print text messages
  570. bool CBaseViewport::AllowedToPrintText( void )
  571. {
  572. /* int iId = GetCurrentMenuID();
  573. if ( iId == MENU_TEAM || iId == MENU_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP )
  574. return false; */
  575. // TODO ask every aktive elemet if it allows to draw text while visible
  576. return ( m_pActivePanel == NULL);
  577. }
  578. void CBaseViewport::OnThink()
  579. {
  580. ABS_QUERY_GUARD( true );
  581. // Clear our active panel pointer if the panel has made
  582. // itself invisible. Need this so we don't bring up dead panels
  583. // if they are stored as the last active panel
  584. if( m_pActivePanel && !m_pActivePanel->IsVisible() )
  585. {
  586. #if !defined( CSTRIKE15 )
  587. if( m_pLastActivePanel )
  588. {
  589. if ( m_pLastActivePanel->CanBeReopened() )
  590. {
  591. m_pActivePanel = m_pLastActivePanel;
  592. ShowPanel( m_pActivePanel, true );
  593. }
  594. else
  595. {
  596. m_pActivePanel = NULL;
  597. }
  598. m_pLastActivePanel = NULL;
  599. }
  600. else
  601. #endif
  602. m_pActivePanel = NULL;
  603. }
  604. m_pAnimController->UpdateAnimations( gpGlobals->curtime );
  605. // check the auto-reload cvar
  606. m_pAnimController->SetAutoReloadScript(hud_autoreloadscript.GetBool());
  607. ACTIVE_SPLITSCREEN_PLAYER_GUARD_VGUI( vgui::ipanel()->GetMessageContextId( GetVPanel() ) );
  608. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  609. {
  610. IViewPortPanel *p = m_UnorderedPanels[i];
  611. if ( p )
  612. {
  613. p->UpdateVisibility();
  614. if ( p->IsVisible() )
  615. {
  616. if ( p->NeedsUpdate() )
  617. {
  618. p->Update();
  619. }
  620. p->ViewportThink();
  621. }
  622. }
  623. }
  624. int w, h;
  625. vgui::ipanel()->GetSize( VGui_GetClientDLLRootPanel(), w, h );
  626. if ( m_OldSize[ 0 ] != w || m_OldSize[ 1 ] != h )
  627. {
  628. m_OldSize[ 0 ] = w;
  629. m_OldSize[ 1 ] = h;
  630. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  631. GetClientMode()->Layout();
  632. }
  633. BaseClass::OnThink();
  634. }
  635. //-----------------------------------------------------------------------------
  636. // Purpose: Sets the parent for each panel to use
  637. //-----------------------------------------------------------------------------
  638. void CBaseViewport::SetParent(vgui::VPANEL parent)
  639. {
  640. EditablePanel::SetParent( parent );
  641. // force ourselves to be proportional - when we set our parent above, if our new
  642. // parent happened to be non-proportional (such as the vgui root panel), we got
  643. // slammed to be nonproportional
  644. EditablePanel::SetProportional( true );
  645. m_pBackGround->SetParent( (vgui::VPANEL)parent );
  646. // set proportionality on animation controller
  647. m_pAnimController->SetProportional( true );
  648. m_bHasParent = (parent != 0);
  649. }
  650. //-----------------------------------------------------------------------------
  651. // Purpose: called when the engine shows the base client VGUI panel (i.e when entering a new level or exiting GameUI )
  652. //-----------------------------------------------------------------------------
  653. void CBaseViewport::ActivateClientUI()
  654. {
  655. }
  656. //-----------------------------------------------------------------------------
  657. // Purpose: called when the engine hides the base client VGUI panel (i.e when the GameUI is comming up )
  658. //-----------------------------------------------------------------------------
  659. void CBaseViewport::HideClientUI()
  660. {
  661. }
  662. //-----------------------------------------------------------------------------
  663. // Purpose: passes death msgs to the scoreboard to display specially
  664. //-----------------------------------------------------------------------------
  665. void CBaseViewport::FireGameEvent( IGameEvent * event)
  666. {
  667. const char * type = event->GetName();
  668. if ( Q_strcmp(type, "game_newmap") == 0 )
  669. {
  670. // hide all panels when reconnecting
  671. ShowPanel( PANEL_ALL, false );
  672. if ( g_bEngineIsHLTV
  673. #if defined( REPLAY_ENABLED )
  674. || engine->IsReplay()
  675. #endif
  676. )
  677. {
  678. ShowPanel( PANEL_SPECGUI, true );
  679. }
  680. }
  681. }
  682. //-----------------------------------------------------------------------------
  683. // Purpose:
  684. //-----------------------------------------------------------------------------
  685. void CBaseViewport::ReloadScheme(const char *fromFile)
  686. {
  687. // See if scheme should change
  688. if ( fromFile != NULL )
  689. {
  690. // "resource/ClientScheme.res"
  691. vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( GetSchemeSizingVPanel(), fromFile, "HudScheme" );
  692. SetScheme(scheme);
  693. SetProportional( true );
  694. m_pAnimController->SetScheme(scheme);
  695. }
  696. // Force a reload
  697. if ( LoadHudAnimations() == false )
  698. {
  699. // Fall back to just the main
  700. if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
  701. {
  702. Assert(0);
  703. }
  704. }
  705. SetProportional( true );
  706. LoadHudLayout();
  707. if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 )
  708. {
  709. HudIcons().RefreshHudTextures();
  710. }
  711. InvalidateLayout( true, true );
  712. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  713. {
  714. IViewPortPanel *p = m_UnorderedPanels[i];
  715. p->ReloadScheme();
  716. }
  717. // reset the hud
  718. GetHud().ResetHUD();
  719. }
  720. extern ConVar ss_verticalsplit;
  721. void AddSubKeyNamed( KeyValues *pKeys, const char *pszName )
  722. {
  723. KeyValues *pNewKey = new KeyValues( pszName );
  724. if ( pNewKey )
  725. {
  726. pKeys->AddSubKey( pNewKey );
  727. }
  728. }
  729. void CBaseViewport::LoadHudLayout( void )
  730. {
  731. VGUI_ABSPOS_SPLITSCREEN_GUARD( GET_ACTIVE_SPLITSCREEN_SLOT() );
  732. // reload the .res file from disk
  733. KeyValues *pConditions = NULL;
  734. if ( engine->IsSplitScreenActive() )
  735. {
  736. pConditions = new KeyValues( "conditions" );
  737. if ( pConditions )
  738. {
  739. AddSubKeyNamed( pConditions, "if_split_screen_active" );
  740. ConVarRef ss_verticalsplit( "ss_verticalsplit" );
  741. if ( ss_verticalsplit.IsValid() && ss_verticalsplit.GetBool() )
  742. {
  743. AddSubKeyNamed( pConditions, "if_split_screen_vertical" );
  744. if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 )
  745. {
  746. AddSubKeyNamed( pConditions, "if_split_screen_left" );
  747. }
  748. else
  749. {
  750. AddSubKeyNamed( pConditions, "if_split_screen_right" );
  751. }
  752. }
  753. else
  754. {
  755. AddSubKeyNamed( pConditions, "if_split_screen_horizontal" );
  756. if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 )
  757. {
  758. AddSubKeyNamed( pConditions, "if_split_screen_top" );
  759. }
  760. else
  761. {
  762. AddSubKeyNamed( pConditions, "if_split_screen_bottom" );
  763. }
  764. }
  765. }
  766. }
  767. LoadControlSettings( "scripts/HudLayout.res", NULL, NULL, pConditions );
  768. if ( pConditions )
  769. {
  770. pConditions->deleteThis();
  771. }
  772. }
  773. int CBaseViewport::GetDeathMessageStartHeight( void )
  774. {
  775. return YRES(2);
  776. }
  777. void CBaseViewport::Paint()
  778. {
  779. if ( cl_leveloverviewmarker.GetInt() > 0 )
  780. {
  781. int size = cl_leveloverviewmarker.GetInt();
  782. // draw a 1024x1024 pixel box
  783. vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
  784. vgui::surface()->DrawLine( size, 0, size, size );
  785. vgui::surface()->DrawLine( 0, size, size, size );
  786. }
  787. }
  788. void CBaseViewport::SetAsFullscreenViewportInterface( void )
  789. {
  790. s_pFullscreenViewportInterface = this;
  791. m_bFullscreenViewport = true;
  792. }
  793. bool CBaseViewport::IsFullscreenViewport() const
  794. {
  795. return m_bFullscreenViewport;
  796. }
  797. void CBaseViewport::LevelInit( void )
  798. {
  799. for ( int i = 0; i < m_UnorderedPanels.Count(); ++i )
  800. {
  801. IViewPortPanel *p = m_UnorderedPanels[i];
  802. if ( p )
  803. {
  804. p->LevelInit();
  805. }
  806. }
  807. }