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.

891 lines
24 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "gameuidefinition.h"
  8. #include "gamelayer.h"
  9. #include "gamerect.h"
  10. #include "gametext.h"
  11. #include "hitarea.h"
  12. #include "graphicgroup.h"
  13. #include "tier1/utlstringmap.h"
  14. #include "tier1/utlbuffer.h"
  15. #include "gameuisystem.h"
  16. #include "gameuiscript.h"
  17. #include "gameuisystemmgr.h"
  18. #include "tier1/fmtstr.h"
  19. #include "materialsystem/imaterial.h"
  20. #include "materialsystem/imaterialvar.h"
  21. #include "materialsystem/imaterialsystem.h"
  22. #include "materialsystem/imesh.h"
  23. #include "rendersystem/irenderdevice.h"
  24. #include "rendersystem/irendercontext.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. static unsigned int s_nBaseTextureVarCache = 0;
  28. BEGIN_DMXELEMENT_UNPACK ( CGameUIDefinition )
  29. DMXELEMENT_UNPACK_FIELD_UTLSTRING( "name", "", m_pName )
  30. END_DMXELEMENT_UNPACK( CGameUIDefinition, s_GameUIDefinitionUnpack )
  31. //-----------------------------------------------------------------------------
  32. // Constructor / Destructor.
  33. //-----------------------------------------------------------------------------
  34. CGameUIDefinition::CGameUIDefinition( IGameUISystem *pGameUISystem /* = NULL */ ) :
  35. m_pGameUISystem( pGameUISystem )
  36. {
  37. m_pName = "";
  38. m_bVisible = true;
  39. m_bCanAcceptInput = false;
  40. m_hScheme = 0;
  41. m_pGameStage = NULL;
  42. // All menus currently default so that
  43. // if mouse focus changes then keyboard focus will match it.
  44. // When keyboard focus changes in response to mouse focus we do not play any anims or send any
  45. // script commands.
  46. // This makes it so one hitarea in the menu has input focus at a time.
  47. // If a menu needs them to be separate we can add a script command to turn this off.
  48. bMouseFocusEqualsKeyboardFocus = true;
  49. }
  50. CGameUIDefinition::~CGameUIDefinition()
  51. {
  52. Shutdown();
  53. }
  54. //-----------------------------------------------------------------------------
  55. //
  56. //-----------------------------------------------------------------------------
  57. void CGameUIDefinition::Shutdown()
  58. {
  59. int nGroups = m_Groups.Count();
  60. for ( int i = 0; i < nGroups; ++i )
  61. {
  62. if ( m_Groups[i] )
  63. {
  64. delete m_Groups[i];
  65. m_Groups[i] = NULL;
  66. }
  67. }
  68. m_Groups.RemoveAll();
  69. int nLayers = m_Layers.Count();
  70. for ( int i = 0; i < nLayers; ++i )
  71. {
  72. m_Layers[i]->Shutdown();
  73. delete m_Layers[i];
  74. m_Layers[i] = NULL;
  75. }
  76. m_Layers.RemoveAll();
  77. int nScripts = m_Scripts.Count();
  78. for ( int i = 0; i < nScripts; ++i )
  79. {
  80. m_Scripts[i]->Shutdown();
  81. delete m_Scripts[i];
  82. m_Scripts[i] = NULL;
  83. }
  84. m_Scripts.RemoveAll();
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Creates an empty GameUI, just has one layer in it. No graphics.
  88. //-----------------------------------------------------------------------------
  89. bool CGameUIDefinition::CreateDefault( const char *pName )
  90. {
  91. m_pName = pName;
  92. const char *pSchemeName = "resource\\ClientScheme.res";
  93. m_hScheme = g_pGameUISchemeManager->LoadSchemeFromFile( pSchemeName, "nouiloadedscheme" );
  94. // Static graphics
  95. CGameLayer *pGameLayer = new CGameLayer;
  96. pGameLayer->SetLayerType( SUBLAYER_STATIC );
  97. m_Layers.AddToTail( pGameLayer );
  98. // Dynamic graphics.
  99. pGameLayer = new CGameLayer;
  100. pGameLayer->SetLayerType( SUBLAYER_DYNAMIC );
  101. m_Layers.AddToTail( pGameLayer );
  102. // Font graphics
  103. pGameLayer = new CGameLayer;
  104. pGameLayer->SetLayerType( SUBLAYER_FONT);
  105. m_Layers.AddToTail( pGameLayer );
  106. // Create a default stage
  107. m_pGameStage = new CGameStage;
  108. m_Groups.InsertBefore( 0, m_pGameStage );
  109. m_bCanAcceptInput = false;
  110. return true;
  111. }
  112. //-----------------------------------------------------------------------------
  113. // Load in data from file
  114. //-----------------------------------------------------------------------------
  115. bool CGameUIDefinition::Unserialize( CDmxElement *pElement )
  116. {
  117. if ( Q_stricmp( pElement->GetTypeString(), "VguiCompiledDoc" ) )
  118. {
  119. return false;
  120. }
  121. pElement->UnpackIntoStructure( this, s_GameUIDefinitionUnpack );
  122. const char *pSchemeName = pElement->GetValueString( "scheme" );
  123. IGameUIScheme *pDefaultScheme = g_pGameUISchemeManager->GetDefaultScheme();
  124. m_hScheme = g_pGameUISchemeManager->GetScheme( pSchemeName );
  125. if ( m_hScheme == pDefaultScheme )
  126. {
  127. // It fell back to the default so didn't find it.
  128. m_hScheme = g_pGameUISchemeManager->LoadSchemeFromFile( pSchemeName, pSchemeName );
  129. Assert( m_hScheme );
  130. }
  131. g_pGameUISystemMgrImpl->SetScheme( m_hScheme );
  132. CDmxAttribute *pLayers = pElement->GetAttribute( "layers" );
  133. if ( !pLayers || pLayers->GetType() != AT_ELEMENT_ARRAY )
  134. {
  135. return false;
  136. }
  137. // Create dynamic image mapping.
  138. CDmxAttribute *pImageListAttr = pElement->GetAttribute( "dynamicimagelist" );
  139. if ( pImageListAttr )
  140. {
  141. const CUtlVector< CUtlString > &imageList = pImageListAttr->GetArray< CUtlString >( );
  142. for ( int i = 0; i < imageList.Count(); ++i )
  143. {
  144. const char *pAlias = imageList[i].Get();
  145. g_pGameUISystemMgrImpl->LoadImageAliasTexture( pAlias, "" );
  146. }
  147. }
  148. // Map graphics to their DMX Element.
  149. CUtlDict< CGameGraphic *, int > unserializedGraphicMapping;
  150. const CUtlVector< CDmxElement * > &layers = pLayers->GetArray< CDmxElement * >( );
  151. int nCount = layers.Count();
  152. for ( int i = 0; i < nCount; ++i )
  153. {
  154. if ( !Q_stricmp( layers[i]->GetTypeString(), "DmeCompiledSubLayer" ) )
  155. {
  156. if ( !UnserializeLayer( layers[i], unserializedGraphicMapping ) )
  157. {
  158. return false;
  159. }
  160. }
  161. }
  162. // Add default layers, these layer will contain anything created from scripting.
  163. // Static graphics
  164. CGameLayer *pGameLayer = new CGameLayer;
  165. pGameLayer->SetLayerType( SUBLAYER_STATIC );
  166. m_Layers.AddToTail( pGameLayer );
  167. // Dynamic graphics.
  168. pGameLayer = new CGameLayer;
  169. pGameLayer->SetLayerType( SUBLAYER_DYNAMIC );
  170. m_Layers.AddToTail( pGameLayer );
  171. // Font graphics
  172. pGameLayer = new CGameLayer;
  173. pGameLayer->SetLayerType( SUBLAYER_FONT);
  174. m_Layers.AddToTail( pGameLayer );
  175. // Groups
  176. CDmxAttribute *pGroups = pElement->GetAttribute( "groups" );
  177. if ( !pGroups )
  178. {
  179. return true;
  180. }
  181. if ( pGroups->GetType() != AT_ELEMENT_ARRAY )
  182. {
  183. return false;
  184. }
  185. const CUtlVector< CDmxElement * > &groups = pGroups->GetArray< CDmxElement * >( );
  186. nCount = groups.Count();
  187. if ( nCount == 0 )
  188. {
  189. Msg( "Error: No stage found" );
  190. return false; // no stage would be fail.
  191. }
  192. bool bStageFound = false;
  193. for ( int i = nCount-1; i >= 0; --i )
  194. {
  195. if ( !Q_stricmp( groups[i]->GetTypeString(), "DmeCompiledStage" ) )
  196. {
  197. bStageFound = true;
  198. break;
  199. }
  200. }
  201. if ( !bStageFound )
  202. {
  203. return false; // no stage would be fail.
  204. }
  205. // Add groups to the graphic mapping so groups can contain other groups.
  206. // This means the groups get created and put in the list before they get unserialized.
  207. // Groups should always be in order parents before children.
  208. // This makes sure parents update before children in update loops
  209. for ( int i = 0; i < nCount; ++i )
  210. {
  211. if ( !Q_stricmp( groups[i]->GetTypeString(), "DmeCompiledGroup" ) )
  212. {
  213. CGraphicGroup *pGraphicGroup = new CGraphicGroup;
  214. char pBuf[255];
  215. UniqueIdToString( groups[i]->GetId(), pBuf, 255 );
  216. unserializedGraphicMapping.Insert( pBuf, pGraphicGroup );
  217. m_Groups.AddToTail( pGraphicGroup );
  218. }
  219. else if ( !Q_stricmp( groups[i]->GetTypeString(), "DmeCompiledStage" ) )
  220. {
  221. Assert( i == 0 );
  222. CGameStage *pGraphicGroup = new CGameStage;
  223. m_Groups.InsertBefore( 0, pGraphicGroup );
  224. m_pGameStage = pGraphicGroup;
  225. }
  226. }
  227. // Now unserialize the groups
  228. for ( int i = 0; i < nCount; ++i )
  229. {
  230. if ( !Q_stricmp( groups[i]->GetTypeString(), "DmeCompiledGroup" ) )
  231. {
  232. if ( !m_Groups[i]->Unserialize( groups[i], unserializedGraphicMapping ) )
  233. {
  234. return false;
  235. }
  236. }
  237. else if ( !Q_stricmp( groups[i]->GetTypeString(), "DmeCompiledStage" ) )
  238. {
  239. Assert( i == 0 );
  240. CGameStage *pStage = (CGameStage *)m_Groups[i];
  241. if ( !pStage->Unserialize( groups[i], unserializedGraphicMapping ) )
  242. {
  243. return false;
  244. }
  245. }
  246. else
  247. {
  248. Assert(0); // something is in the group list that isn't a group!
  249. }
  250. }
  251. return true;
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Load in data from file for a layer
  255. //-----------------------------------------------------------------------------
  256. bool CGameUIDefinition::UnserializeLayer( CDmxElement *pLayer,
  257. CUtlDict< CGameGraphic *, int > &unserializedGraphicMapping )
  258. {
  259. // Static graphics
  260. CDmxAttribute *pGraphics = pLayer->GetAttribute( "staticGraphics" );
  261. // The layer may have no static graphics ( it could be only fonts! )
  262. if ( pGraphics && pGraphics->GetType() == AT_ELEMENT_ARRAY )
  263. {
  264. CDmxAttribute *pGraphics = pLayer->GetAttribute( "staticGraphics" );
  265. const CUtlVector< CDmxElement * > &graphics = pGraphics->GetArray< CDmxElement * >( );
  266. if ( graphics.Count() != 0 )
  267. {
  268. CGameLayer *pGameLayer = new CGameLayer;
  269. pGameLayer->SetLayerType( SUBLAYER_STATIC );
  270. pGameLayer->Unserialize( pLayer, unserializedGraphicMapping );
  271. m_Layers.AddToTail( pGameLayer );
  272. }
  273. }
  274. // repeat above for dynamic graphics.
  275. // The layer may have no dynamic graphics
  276. if ( pGraphics && pGraphics->GetType() == AT_ELEMENT_ARRAY )
  277. {
  278. CDmxAttribute *pGraphics = pLayer->GetAttribute( "dynamicGraphics" );
  279. const CUtlVector< CDmxElement * > &graphics = pGraphics->GetArray< CDmxElement * >( );
  280. if ( graphics.Count() != 0 )
  281. {
  282. CGameLayer *pGameLayer = new CGameLayer;
  283. pGameLayer->SetLayerType( SUBLAYER_DYNAMIC );
  284. pGameLayer->Unserialize( pLayer, unserializedGraphicMapping );
  285. m_Layers.AddToTail( pGameLayer );
  286. }
  287. }
  288. // Font graphics
  289. pGraphics = pLayer->GetAttribute( "fontGraphics" );
  290. // The layer may have no font graphics
  291. if ( pGraphics && pGraphics->GetType() == AT_ELEMENT_ARRAY )
  292. {
  293. CDmxAttribute *pGraphics = pLayer->GetAttribute( "fontGraphics" );
  294. const CUtlVector< CDmxElement * > &graphics = pGraphics->GetArray< CDmxElement * >( );
  295. if ( graphics.Count() != 0 )
  296. {
  297. CGameLayer *pGameLayer = new CGameLayer;
  298. pGameLayer->SetLayerType( SUBLAYER_FONT );
  299. pGameLayer->Unserialize( pLayer, unserializedGraphicMapping );
  300. m_Layers.AddToTail( pGameLayer );
  301. }
  302. }
  303. return true;
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Path is always vguiedit\menuname.lua
  307. //-----------------------------------------------------------------------------
  308. void CGameUIDefinition::InitializeScripts()
  309. {
  310. // First time?
  311. if ( m_Scripts.Count() == 0 )
  312. {
  313. CFmtStr path[2];
  314. path[0].sprintf( "vguiedit\\%s.lua", m_pName.Get() );
  315. path[1].sprintf( "vguiedit\\%s\\%s.lua", m_pName.Get(), m_pName.Get() );
  316. for ( int k = 0; k < ARRAYSIZE( path ); ++ k )
  317. {
  318. CFmtStr scriptPath;
  319. scriptPath.sprintf( "scripts\\%s", path[k].Access() );
  320. // Does this menu have a script?
  321. if ( g_pFullFileSystem->FileExists( scriptPath, "MOD" ) )
  322. {
  323. CGameUIScript *pScript = new CGameUIScript();
  324. bool bResult = pScript->SetScript( path[k], this );
  325. if ( bResult )
  326. {
  327. m_Scripts.AddToTail( pScript );
  328. DevMsg( "Loaded script %s for %s\n", scriptPath.Access(), m_pName.Get() );
  329. break; // break as soon as the first script is loaded successfully
  330. }
  331. else
  332. {
  333. Warning( "Invalid script %s for %s\n", scriptPath.Access(), m_pName.Get() );
  334. delete pScript;
  335. }
  336. }
  337. else
  338. {
  339. DevMsg( "No default script %s found for %s\n", scriptPath.Access(), m_pName.Get() );
  340. }
  341. }
  342. }
  343. SetAcceptInput( false );
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Execute a script function
  347. // The function to call is denoted by executionType
  348. //-----------------------------------------------------------------------------
  349. bool CGameUIDefinition::ExecuteScript( KeyValues *args, KeyValues **ppResult )
  350. {
  351. Assert( !ppResult || !*ppResult ); // storing return value, might overwrite caller's keyvalues
  352. //////////////////////////////////////////////////////////////////////////
  353. // TEMP: special events for unit-tests state control
  354. char const *szEvent = args->GetName();
  355. if ( !Q_stricmp( "AdvanceState", szEvent ) )
  356. {
  357. AdvanceState();
  358. return true;
  359. }
  360. if ( !Q_stricmp( "StartPlaying", szEvent ) )
  361. {
  362. StartPlaying();
  363. return true;
  364. }
  365. if ( !Q_stricmp( "StopPlaying", szEvent ) )
  366. {
  367. StopPlaying();
  368. return true;
  369. }
  370. if ( !Q_stricmp( "ShowCursorCoords", szEvent ) )
  371. {
  372. g_pGameUISystemMgrImpl->ShowCursorCoords();
  373. return true;
  374. }
  375. if ( !Q_stricmp( "ShowGraphicName", szEvent ) )
  376. {
  377. g_pGameUISystemMgrImpl->ShowGraphicName();
  378. return true;
  379. }
  380. //////////////////////////////////////////////////////////////////////////
  381. //////////////////////////////////////////////////////////////////////////
  382. // Graphic access
  383. if ( !Q_stricmp( "FindGraphic", szEvent ) )
  384. {
  385. CGameGraphic *pGraphic = FindGraphicByName( args->GetString( "graphic" ) );
  386. if ( pGraphic && ppResult )
  387. {
  388. *ppResult = new KeyValues( "" );
  389. (*ppResult)->SetInt( "graphichandle", pGraphic->GetScriptHandle() );
  390. }
  391. return true;
  392. }
  393. if ( !Q_stricmp( "SetInput", szEvent ) )
  394. {
  395. SetAcceptInput( args->GetBool( "input", true ) );
  396. return true;
  397. }
  398. if ( !Q_stricmp( "InitAnims", szEvent ) )
  399. {
  400. InitAnims();
  401. return true;
  402. }
  403. if ( !Q_stricmp( "Sound", szEvent ) )
  404. {
  405. if ( args->GetBool( "play", true ) )
  406. g_pGameUISystemMgrImpl->PlayMenuSound( args->GetString( "sound" ) );
  407. else
  408. g_pGameUISystemMgrImpl->StopMenuSound( args->GetString( "sound" ) );
  409. }
  410. //////////////////////////////////////////////////////////////////////////
  411. if ( !Q_stricmp( "setdynamictexture", szEvent ) )
  412. {
  413. g_pGameUISystemMgrImpl->LoadImageAliasTexture( args->GetString( "aliasname", "" ), args->GetString( "texturename", "" ) );
  414. }
  415. bool bExecuted = false;
  416. if ( m_Scripts.Count() != 0 && m_Scripts[ 0 ] )
  417. {
  418. m_Scripts[ 0 ]->SetActive( true );
  419. bExecuted = m_Scripts[ 0 ]->Execute( args, ppResult );
  420. m_Scripts[ 0 ]->SetActive( false );
  421. }
  422. if ( !bExecuted )
  423. {
  424. // If the menu doesn't handle its exit just hide it.
  425. if ( !Q_stricmp( szEvent, "OnExit" ) )
  426. {
  427. SetVisible( false );
  428. return true;
  429. }
  430. }
  431. return bExecuted;
  432. }
  433. //-----------------------------------------------------------------------------
  434. // Return the number of layers in this menu
  435. //-----------------------------------------------------------------------------
  436. int CGameUIDefinition::GetLayerCount()
  437. {
  438. return m_Layers.Count();
  439. }
  440. //-----------------------------------------------------------------------------
  441. //
  442. //-----------------------------------------------------------------------------
  443. void CGameUIDefinition::InvalidateSheetSymbols()
  444. {
  445. int nCount = m_Layers.Count();
  446. for ( int j = 0; j < nCount; ++j )
  447. {
  448. m_Layers[j]->InvalidateSheetSymbol();
  449. }
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Update from front to back so input consequences go right in.
  453. //-----------------------------------------------------------------------------
  454. void CGameUIDefinition::UpdateGeometry()
  455. {
  456. m_pGameStage->UpdateGeometry();
  457. }
  458. //-----------------------------------------------------------------------------
  459. // Update the render to screen matrices of all graphics
  460. // Children use thier parent's viewport/matrix and build off that.
  461. //-----------------------------------------------------------------------------
  462. void CGameUIDefinition::UpdateRenderTransforms( const Rect_t &viewport )
  463. {
  464. m_pGameStage->UpdateRenderTransforms( viewport );
  465. }
  466. //-----------------------------------------------------------------------------
  467. // Get lists of rendering data needed to draw the ui.
  468. // Each layer has a different type, static, dynamic, and font
  469. // a new render list is created whenever the layer type changes
  470. // and when the texture needed to render changes.
  471. // Layers live in sets of 3's, static, dynamic and font.
  472. // This preserves render order from the editor.
  473. //-----------------------------------------------------------------------------
  474. void CGameUIDefinition::GetRenderData( CUtlVector< LayerRenderLists_t > &renderLists )
  475. {
  476. int nLayers = m_Layers.Count();
  477. for ( int i = 0; i < nLayers; ++i )
  478. {
  479. color32 stageColor = m_pGameStage->GetStageColor();
  480. m_Layers[i]->UpdateRenderData( *this, stageColor, renderLists );
  481. }
  482. }
  483. //-----------------------------------------------------------------------------
  484. // Given a position, return the front most graphic under it.
  485. //-----------------------------------------------------------------------------
  486. CGameGraphic *CGameUIDefinition::GetGraphic( int x, int y )
  487. {
  488. int nLayers = m_Layers.Count();
  489. for ( int i = nLayers-1; i >= 0; --i )
  490. {
  491. CGameGraphic *pGraphic = ( CGameGraphic * )m_Layers[i]->GetGraphic( x, y );
  492. if ( pGraphic )
  493. {
  494. return pGraphic;
  495. }
  496. }
  497. return NULL;
  498. }
  499. //-----------------------------------------------------------------------------
  500. // Given a position, return the front most graphic that can take input under it.
  501. //-----------------------------------------------------------------------------
  502. CHitArea *CGameUIDefinition::GetMouseFocus( int x, int y )
  503. {
  504. if ( CanAcceptInput() )
  505. {
  506. int nLayers = m_Layers.Count();
  507. for ( int i = nLayers-1; i >= 0; --i )
  508. {
  509. CHitArea *pGraphic = ( CHitArea * )m_Layers[i]->GetMouseFocus( x, y );
  510. if ( pGraphic )
  511. {
  512. return pGraphic;
  513. }
  514. }
  515. }
  516. return NULL;
  517. }
  518. //-----------------------------------------------------------------------------
  519. // Given a graphic, return the next graphic that can receive focus.
  520. // Note the default focus order is just the render order.
  521. //-----------------------------------------------------------------------------
  522. CHitArea *CGameUIDefinition::GetNextFocus( CHitArea *pCurrentGraphic )
  523. {
  524. if ( !CanAcceptInput() )
  525. return NULL;
  526. bool bGetNext = false;
  527. if ( pCurrentGraphic == NULL )
  528. {
  529. bGetNext = true;
  530. }
  531. int nLayers = m_Layers.Count();
  532. for ( int i = 0; i < nLayers; ++i )
  533. {
  534. CHitArea *pGraphic = ( CHitArea * )m_Layers[i]->GetNextFocus( bGetNext, pCurrentGraphic );
  535. if ( pGraphic )
  536. {
  537. return pGraphic;
  538. }
  539. }
  540. // We found no next one, we must be at the end then, restart from the back.
  541. bGetNext = true;
  542. for ( int i = 0; i < nLayers; ++i )
  543. {
  544. CHitArea *pGraphic = ( CHitArea * )m_Layers[i]->GetNextFocus( bGetNext, pCurrentGraphic );
  545. if ( pGraphic )
  546. {
  547. return pGraphic;
  548. }
  549. }
  550. return NULL;
  551. }
  552. //-----------------------------------------------------------------------------
  553. // Start playing animations
  554. //-----------------------------------------------------------------------------
  555. void CGameUIDefinition::StartPlaying()
  556. {
  557. m_pGameStage->StartPlaying();
  558. int nCount = m_Layers.Count();
  559. for ( int j = 0; j < nCount; ++j )
  560. {
  561. m_Layers[j]->StartPlaying();
  562. }
  563. }
  564. //-----------------------------------------------------------------------------
  565. // Stop playing animations
  566. //-----------------------------------------------------------------------------
  567. void CGameUIDefinition::StopPlaying()
  568. {
  569. m_pGameStage->StopPlaying();
  570. int nCount = m_Layers.Count();
  571. for ( int j = 0; j < nCount; ++j )
  572. {
  573. m_Layers[j]->StopPlaying();
  574. }
  575. }
  576. //-----------------------------------------------------------------------------
  577. // Move to the next known animation state
  578. //-----------------------------------------------------------------------------
  579. void CGameUIDefinition::AdvanceState()
  580. {
  581. m_pGameStage->AdvanceState();
  582. int nCount = m_Layers.Count();
  583. for ( int j = 0; j < nCount; ++j )
  584. {
  585. m_Layers[j]->AdvanceState();
  586. }
  587. }
  588. //-----------------------------------------------------------------------------
  589. // Set all graphics to "default" state.
  590. //-----------------------------------------------------------------------------
  591. void CGameUIDefinition::InitAnims()
  592. {
  593. m_pGameStage->SetState( "default" );
  594. int nCount = m_Layers.Count();
  595. for ( int j = 0; j < nCount; ++j )
  596. {
  597. m_Layers[j]->InitAnims();
  598. }
  599. }
  600. //-----------------------------------------------------------------------------
  601. // Given a graphic, build its scoped name.
  602. //-----------------------------------------------------------------------------
  603. void CGameUIDefinition::BuildScopedGraphicName( CUtlString &name, CGameGraphic *pGraphic )
  604. {
  605. if ( !pGraphic->GetGroup()->IsStageGroup() )
  606. {
  607. BuildScopedGraphicName( name, pGraphic->GetGroup() );
  608. }
  609. name += pGraphic->GetName();
  610. if ( pGraphic->IsGroup() )
  611. {
  612. name += ":";
  613. }
  614. }
  615. //-----------------------------------------------------------------------------
  616. // Given a scoped name of a graphic, return it if it exists in this menu
  617. //-----------------------------------------------------------------------------
  618. CGameGraphic *CGameUIDefinition::GraphicExists( const char *pName ) const
  619. {
  620. if ( m_pGameStage->IsGraphicNamed( pName ) )
  621. return m_pGameStage;
  622. CSplitString nameparts( pName, ":");
  623. CGameGraphic *parent = m_pGameStage;
  624. CGameGraphic *pGraphic = NULL;
  625. for ( int i = 0; i < nameparts.Count(); ++i )
  626. {
  627. pGraphic = parent->FindGraphicByName( nameparts[i] );
  628. if ( pGraphic )
  629. {
  630. parent = pGraphic;
  631. }
  632. else
  633. {
  634. return NULL; // couldn't find it.
  635. }
  636. }
  637. return pGraphic;
  638. }
  639. //-----------------------------------------------------------------------------
  640. // Given a scoped name of a graphic, find it in this menu.
  641. // This function expects to find the graphic
  642. //-----------------------------------------------------------------------------
  643. CGameGraphic *CGameUIDefinition::FindGraphicByName( const char *pName ) const
  644. {
  645. CGameGraphic *pGraphic = GraphicExists( pName );
  646. if ( pGraphic )
  647. {
  648. return pGraphic;
  649. }
  650. else
  651. {
  652. Warning( "FindGraphicByName: Unable to find graphic named %s\n", pName );
  653. return NULL; // couldn't find it.
  654. }
  655. }
  656. //-----------------------------------------------------------------------------
  657. // Add a text graphic to the front most layer of a given type
  658. //-----------------------------------------------------------------------------
  659. bool CGameUIDefinition::AddGraphicToLayer( CGameGraphic *pGraphic, int nLayerType )
  660. {
  661. pGraphic->SetGroup( m_pGameStage );
  662. m_pGameStage->AddToGroup( pGraphic );
  663. // Find the frontmost player of this type.
  664. int nFrontLayer = -1;
  665. for ( int i = m_Layers.Count()-1; i >= 0; --i )
  666. {
  667. if ( m_Layers[i]->GetLayerType() == nLayerType )
  668. {
  669. nFrontLayer = i;
  670. break;
  671. }
  672. }
  673. if ( nFrontLayer != -1 )
  674. {
  675. AddGraphic( pGraphic, nFrontLayer );
  676. return true;
  677. }
  678. return false;
  679. }
  680. //-----------------------------------------------------------------------------
  681. // Add a graphic to the given layer
  682. //-----------------------------------------------------------------------------
  683. void CGameUIDefinition::AddGraphic( CGameGraphic *pGraphic, int layerIndex )
  684. {
  685. Assert( layerIndex >= 0 );
  686. Assert (layerIndex < m_Layers.Count() );
  687. m_Layers[layerIndex]->AddGraphic( pGraphic );
  688. }
  689. //-----------------------------------------------------------------------------
  690. // Remove this graphic from the UI
  691. //-----------------------------------------------------------------------------
  692. bool CGameUIDefinition::RemoveGraphic( CGameGraphic *pGraphic )
  693. {
  694. for ( int i = 0; i < m_Layers.Count(); ++i )
  695. {
  696. if ( m_Layers[i]->RemoveGraphic( pGraphic ) )
  697. {
  698. return true;
  699. }
  700. }
  701. return false;
  702. }
  703. //-----------------------------------------------------------------------------
  704. // Return true if this graphic is in this menu
  705. //-----------------------------------------------------------------------------
  706. bool CGameUIDefinition::HasGraphic( CGameGraphic *pGraphic )
  707. {
  708. for ( int i = 0; i < m_Layers.Count(); ++i )
  709. {
  710. if ( m_Layers[i]->HasGraphic( pGraphic ) )
  711. {
  712. return true;
  713. }
  714. }
  715. return false;
  716. }
  717. //-----------------------------------------------------------------------------
  718. // Set visibility of the gameui.
  719. //-----------------------------------------------------------------------------
  720. void CGameUIDefinition::SetVisible( bool bVisible )
  721. {
  722. m_bVisible = bVisible;
  723. // Visibility can cause a focus change to be needed!
  724. g_pGameUISystemMgrImpl->ForceFocusUpdate();
  725. }
  726. //-----------------------------------------------------------------------------
  727. //
  728. //-----------------------------------------------------------------------------
  729. void CGameUIDefinition::UpdateAspectRatio( const Rect_t &viewport )
  730. {
  731. m_pGameStage->UpdateAspectRatio( viewport );
  732. }
  733. //-----------------------------------------------------------------------------
  734. // Change the size of the stage.
  735. //-----------------------------------------------------------------------------
  736. void CGameUIDefinition::SetStageSize( int nWide, int nTall )
  737. {
  738. m_pGameStage->SetStageSize( nWide, nTall );
  739. }
  740. //-----------------------------------------------------------------------------
  741. //
  742. //-----------------------------------------------------------------------------
  743. void CGameUIDefinition::GetStageSize( Vector2D &stageSize )
  744. {
  745. m_pGameStage->GetStageSize( stageSize );
  746. }
  747. //-----------------------------------------------------------------------------
  748. //
  749. //-----------------------------------------------------------------------------
  750. void CGameUIDefinition::GetMaintainAspectRatioStageSize( Vector2D &stageSize )
  751. {
  752. m_pGameStage->GetMaintainAspectRatioStageSize( stageSize );
  753. }