Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

803 lines
22 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "base_loadout_panel.h"
  8. #include "item_confirm_delete_dialog.h"
  9. #include "vgui/ISurface.h"
  10. #include "gamestringpool.h"
  11. #include "iclientmode.h"
  12. #include "econ_item_inventory.h"
  13. #include "ienginevgui.h"
  14. #include <vgui/ILocalize.h>
  15. #include "vgui_controls/TextImage.h"
  16. #include "vgui_controls/CheckButton.h"
  17. #include "vgui_controls/ComboBox.h"
  18. #include "vgui/IInput.h"
  19. #include "econ_ui.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include <tier0/memdbgon.h>
  22. #ifdef STAGING_ONLY
  23. ConVar tf_use_card_tooltips( "tf_use_card_tooltips", "0", FCVAR_ARCHIVE );
  24. #endif
  25. //-----------------------------------------------------------------------------
  26. // Purpose:
  27. //-----------------------------------------------------------------------------
  28. CBaseLoadoutPanel::CBaseLoadoutPanel( vgui::Panel *parent, const char *panelName ) : EditablePanel(parent, panelName )
  29. {
  30. SetParent( parent );
  31. // Use the client scheme
  32. vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
  33. SetScheme(scheme);
  34. SetProportional( true );
  35. m_pItemModelPanelKVs = NULL;
  36. m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
  37. m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
  38. m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
  39. #ifdef STAGING_ONLY
  40. m_pMouseOverCardPanel = vgui::SETUP_PANEL( new CTFItemCardPanel( this, "mouseovercardpanel" ) );
  41. m_pMouseOverCardTooltip = new CItemCardPanelToolTip( this );
  42. m_pMouseOverCardTooltip->SetupPanels( this, m_pMouseOverCardPanel );
  43. #endif
  44. m_pItemPanelBeingMousedOver = NULL;
  45. m_pCaratLabel = NULL;
  46. m_pClassLabel = NULL;
  47. m_nCurrentPage = 0;
  48. m_bTooltipKeyPressed = false;
  49. SetMouseInputEnabled( true );
  50. SetKeyBoardInputEnabled( true );
  51. ListenForGameEvent( "inventory_updated" );
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. //-----------------------------------------------------------------------------
  56. CBaseLoadoutPanel::~CBaseLoadoutPanel()
  57. {
  58. if ( m_pItemModelPanelKVs )
  59. {
  60. m_pItemModelPanelKVs->deleteThis();
  61. m_pItemModelPanelKVs = NULL;
  62. }
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose:
  66. //-----------------------------------------------------------------------------
  67. void CBaseLoadoutPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  68. {
  69. BaseClass::ApplySchemeSettings( pScheme );
  70. m_pCaratLabel = dynamic_cast<vgui::Label*>( FindChildByName("CaratLabel") );
  71. m_pClassLabel = dynamic_cast<vgui::Label*>( FindChildByName("ClassLabel") );
  72. m_bReapplyItemKVs = true;
  73. for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
  74. {
  75. SetBorderForItem( m_pItemModelPanels[i], false );
  76. }
  77. m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
  78. CreateItemPanels();
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. void CBaseLoadoutPanel::ApplySettings( KeyValues *inResourceData )
  84. {
  85. BaseClass::ApplySettings( inResourceData );
  86. KeyValues *pItemKV = inResourceData->FindKey( "modelpanels_kv" );
  87. if ( pItemKV )
  88. {
  89. if ( m_pItemModelPanelKVs )
  90. {
  91. m_pItemModelPanelKVs->deleteThis();
  92. }
  93. m_pItemModelPanelKVs = new KeyValues("modelpanels_kv");
  94. pItemKV->CopySubkeys( m_pItemModelPanelKVs );
  95. }
  96. }
  97. extern const char *g_szItemBorders[AE_MAX_TYPES][5];
  98. extern ConVar cl_showbackpackrarities;
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. //-----------------------------------------------------------------------------
  102. void CBaseLoadoutPanel::SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver )
  103. {
  104. if ( !pItemPanel )
  105. return;
  106. const char *pszBorder = NULL;
  107. if ( pItemPanel->IsGreyedOut() )
  108. {
  109. if( pItemPanel->IsSelected() )
  110. {
  111. pszBorder = "BackpackItemGrayedOut_Selected";
  112. }
  113. else
  114. {
  115. pszBorder = "BackpackItemGrayedOut";
  116. }
  117. }
  118. else
  119. {
  120. int iRarity = 0;
  121. if ( pItemPanel->HasItem() && cl_showbackpackrarities.GetBool() )
  122. {
  123. iRarity = pItemPanel->GetItem()->GetItemQuality() ;
  124. uint8 nRarity = pItemPanel->GetItem()->GetItemDefinition()->GetRarity();
  125. if ( ( nRarity != k_unItemRarity_Any ) && ( iRarity != AE_SELFMADE ) )
  126. {
  127. // translate this quality to rarity
  128. iRarity = nRarity + AE_RARITY_DEFAULT;
  129. }
  130. }
  131. if ( pItemPanel->IsSelected() )
  132. {
  133. pszBorder = g_szItemBorders[iRarity][2];
  134. }
  135. if ( bMouseOver )
  136. {
  137. pszBorder = g_szItemBorders[iRarity][1];
  138. }
  139. else
  140. {
  141. pszBorder = g_szItemBorders[iRarity][0];
  142. }
  143. }
  144. vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
  145. pItemPanel->SetBorder( pScheme->GetBorder( pszBorder ) );
  146. }
  147. //-----------------------------------------------------------------------------
  148. // Purpose:
  149. //-----------------------------------------------------------------------------
  150. void CBaseLoadoutPanel::ApplyKVsToItemPanels( void )
  151. {
  152. if ( m_pItemModelPanelKVs )
  153. {
  154. for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
  155. {
  156. m_pItemModelPanels[i]->ApplySettings( m_pItemModelPanelKVs );
  157. SetBorderForItem( m_pItemModelPanels[i], false );
  158. m_pItemModelPanels[i]->InvalidateLayout();
  159. }
  160. }
  161. }
  162. //-----------------------------------------------------------------------------
  163. // Purpose:
  164. //-----------------------------------------------------------------------------
  165. void CBaseLoadoutPanel::PerformLayout( void )
  166. {
  167. if ( m_bReapplyItemKVs )
  168. {
  169. m_bReapplyItemKVs = false;
  170. ApplyKVsToItemPanels();
  171. }
  172. BaseClass::PerformLayout();
  173. // If we're items only, we hide various elements
  174. if ( m_pCaratLabel )
  175. {
  176. m_pCaratLabel->SetVisible( !m_bItemsOnly );
  177. }
  178. if ( m_pClassLabel )
  179. {
  180. m_pClassLabel->SetVisible( !m_bItemsOnly );
  181. }
  182. if ( m_pMouseOverItemPanel->IsVisible() )
  183. {
  184. // The mouseover panel was visible. Fake a panel entry into the original panel to get it to show up again properly.
  185. if ( m_pItemPanelBeingMousedOver )
  186. {
  187. OnItemPanelEntered( m_pItemPanelBeingMousedOver );
  188. }
  189. else
  190. {
  191. HideMouseOverPanel();
  192. }
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Purpose:
  197. //-----------------------------------------------------------------------------
  198. void CBaseLoadoutPanel::AddNewItemPanel( int iPanelIndex )
  199. {
  200. CItemModelPanel *pPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, VarArgs("modelpanel%d", iPanelIndex) ) );
  201. pPanel->SetActAsButton( true, true );
  202. m_pItemModelPanels.AddToTail( pPanel );
  203. #ifdef STAGING_ONLY
  204. if ( tf_use_card_tooltips.GetBool() )
  205. {
  206. pPanel->SetTooltip( m_pMouseOverCardTooltip, "" );
  207. }
  208. else
  209. #endif
  210. pPanel->SetTooltip( m_pMouseOverTooltip, "" );
  211. Assert( iPanelIndex == (m_pItemModelPanels.Count()-1) );
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. void CBaseLoadoutPanel::CreateItemPanels( void )
  217. {
  218. int iNumPanels = GetNumItemPanels();
  219. if ( m_pItemModelPanels.Count() < iNumPanels )
  220. {
  221. for ( int i = m_pItemModelPanels.Count(); i < iNumPanels; i++ )
  222. {
  223. AddNewItemPanel(i);
  224. }
  225. }
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Purpose:
  229. //-----------------------------------------------------------------------------
  230. void CBaseLoadoutPanel::ShowPanel( int iClass, bool bBackpack, bool bReturningFromArmory )
  231. {
  232. bool bShow = (iClass != 0 || bBackpack);
  233. OnShowPanel( bShow, bReturningFromArmory );
  234. SetVisible( bShow );
  235. if ( bShow )
  236. {
  237. HideMouseOverPanel();
  238. CreateItemPanels();
  239. UpdateModelPanels();
  240. // make the first slot be selected so controller input will work
  241. static ConVarRef joystick( "joystick" );
  242. if( joystick.IsValid() && joystick.GetBool() && m_pItemModelPanels.Count() && m_pItemModelPanels[0] )
  243. {
  244. m_pItemModelPanels[0]->SetSelected( true );
  245. m_pItemModelPanels[0]->RequestFocus();
  246. }
  247. }
  248. else
  249. {
  250. // clear items from panels to make sure that items get invalidate on show panel
  251. FOR_EACH_VEC( m_pItemModelPanels, i )
  252. {
  253. m_pItemModelPanels[i]->SetItem( NULL );
  254. }
  255. }
  256. if ( !bReturningFromArmory )
  257. {
  258. PostShowPanel( bShow );
  259. }
  260. }
  261. //-----------------------------------------------------------------------------
  262. // Purpose:
  263. //-----------------------------------------------------------------------------
  264. void CBaseLoadoutPanel::OnCommand( const char *command )
  265. {
  266. engine->ClientCmd( const_cast<char *>( command ) );
  267. BaseClass::OnCommand( command );
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Purpose:
  271. //-----------------------------------------------------------------------------
  272. void CBaseLoadoutPanel::FireGameEvent( IGameEvent *event )
  273. {
  274. // If we're not visible, ignore all events
  275. if ( !IsVisible() )
  276. return;
  277. const char *type = event->GetName();
  278. if ( Q_strcmp( "inventory_updated", type ) == 0 )
  279. {
  280. // We need to refresh our model panels, because the items may have changed.
  281. UpdateModelPanels();
  282. }
  283. }
  284. CItemModelPanel *CBaseLoadoutPanel::FindBestPanelNavigationForDirection( const CItemModelPanel *pCurrentPanel, const Vector2D &vPos, const Vector2D &vDirection )
  285. {
  286. CItemModelPanel *pBestPanel = NULL;
  287. // Start with the worst allowable score
  288. float flDistance = GetWide() + GetTall();
  289. float flDot = -1.0f;
  290. float flClosenessScore = flDistance * ( 1.5f - flDot );
  291. for ( int j = 0; j < m_pItemModelPanels.Count(); j++ )
  292. {
  293. CItemModelPanel *pTempPanel = m_pItemModelPanels[ j ];
  294. if ( !pTempPanel || pTempPanel == pCurrentPanel )
  295. continue;
  296. // Get temp center position
  297. int nX, nY;
  298. pTempPanel->GetPos( nX, nY );
  299. nX += pTempPanel->GetWide() / 2;
  300. nY += pTempPanel->GetTall() / 2;
  301. Vector2D vTempPos( nX, nY );
  302. // Get distance and dot
  303. Vector2D vDiff = vTempPos - vPos;
  304. float flTempDistance = Vector2DNormalize( vDiff );
  305. float flTempDot = vDiff.Dot( vDirection );
  306. // Must be somewhat in the correct direction
  307. if ( flTempDot <= 0.0f )
  308. continue;
  309. float flTempScore = flTempDistance * ( 1.5f - flTempDot );
  310. if ( flClosenessScore > flTempScore )
  311. {
  312. flClosenessScore = flTempScore;
  313. flDistance = flTempDistance;
  314. flDot = flTempDot;
  315. pBestPanel = pTempPanel;
  316. }
  317. }
  318. return pBestPanel;
  319. }
  320. void CBaseLoadoutPanel::LinkModelPanelControllerNavigation( bool bForceRelink )
  321. {
  322. if ( m_pItemModelPanels.Count() < 2 )
  323. return;
  324. // first unlink everything
  325. if( bForceRelink )
  326. {
  327. for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
  328. {
  329. CItemModelPanel *pCurrentPanel = m_pItemModelPanels[ i ];
  330. if ( !pCurrentPanel )
  331. continue;
  332. pCurrentPanel->SetNavUp( (vgui::Panel*)NULL );
  333. pCurrentPanel->SetNavDown( (vgui::Panel*)NULL );
  334. pCurrentPanel->SetNavLeft( (vgui::Panel*)NULL );
  335. pCurrentPanel->SetNavRight( (vgui::Panel*)NULL );
  336. }
  337. }
  338. for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
  339. {
  340. CItemModelPanel *pCurrentPanel = m_pItemModelPanels[ i ];
  341. if ( !pCurrentPanel )
  342. continue;
  343. // Get center position
  344. int nX, nY;
  345. pCurrentPanel->GetPos( nX, nY );
  346. nX += pCurrentPanel->GetWide() / 2;
  347. nY += pCurrentPanel->GetTall() / 2;
  348. Vector2D vPos( nX, nY );
  349. if ( !pCurrentPanel->GetNavUpName() || pCurrentPanel->GetNavUpName()[ 0 ] == '\0' )
  350. {
  351. CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 0, -1 ) );
  352. if ( pBestPanel )
  353. {
  354. pCurrentPanel->SetNavUp( pBestPanel->GetName() );
  355. pBestPanel->SetNavDown( pCurrentPanel->GetName() );
  356. }
  357. }
  358. if ( !pCurrentPanel->GetNavDownName() || pCurrentPanel->GetNavDownName()[ 0 ] == '\0' )
  359. {
  360. CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 0, 1 ) );
  361. if ( pBestPanel )
  362. {
  363. pCurrentPanel->SetNavDown( pBestPanel->GetName() );
  364. pBestPanel->SetNavUp( pCurrentPanel->GetName() );
  365. }
  366. }
  367. if ( !pCurrentPanel->GetNavLeftName() || pCurrentPanel->GetNavLeftName()[ 0 ] == '\0' )
  368. {
  369. CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( -1, 0 ) );
  370. if ( pBestPanel )
  371. {
  372. pCurrentPanel->SetNavLeft( pBestPanel->GetName() );
  373. pBestPanel->SetNavRight( pCurrentPanel->GetName() );
  374. }
  375. }
  376. if ( !pCurrentPanel->GetNavRightName() || pCurrentPanel->GetNavRightName()[ 0 ] == '\0' )
  377. {
  378. CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 1, 0 ) );
  379. if ( pBestPanel )
  380. {
  381. pCurrentPanel->SetNavRight( pBestPanel->GetName() );
  382. pBestPanel->SetNavLeft( pCurrentPanel->GetName() );
  383. }
  384. }
  385. }
  386. }
  387. //-----------------------------------------------------------------------------
  388. // Purpose:
  389. //-----------------------------------------------------------------------------
  390. void CBaseLoadoutPanel::OnItemPanelEntered( vgui::Panel *panel )
  391. {
  392. CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
  393. if ( pItemPanel && IsVisible() )
  394. {
  395. CEconItemView *pItem = pItemPanel->GetItem();
  396. if ( pItem && !IsIgnoringItemPanelEnters() && !pItemPanel->IsGreyedOut() )
  397. {
  398. m_pItemPanelBeingMousedOver = pItemPanel;
  399. }
  400. if ( !pItemPanel->IsSelected() )
  401. {
  402. SetBorderForItem( pItemPanel, true );
  403. }
  404. }
  405. }
  406. //-----------------------------------------------------------------------------
  407. // Purpose:
  408. //-----------------------------------------------------------------------------
  409. void CBaseLoadoutPanel::OnItemPanelExited( vgui::Panel *panel )
  410. {
  411. CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
  412. if ( pItemPanel && IsVisible() )
  413. {
  414. if ( !pItemPanel->IsSelected() )
  415. {
  416. SetBorderForItem( pItemPanel, false );
  417. }
  418. }
  419. }
  420. //-----------------------------------------------------------------------------
  421. // Purpose:
  422. //-----------------------------------------------------------------------------
  423. void CBaseLoadoutPanel::HideMouseOverPanel( void )
  424. {
  425. if ( m_pMouseOverItemPanel->IsVisible() )
  426. {
  427. m_pMouseOverItemPanel->SetVisible( false );
  428. m_pItemPanelBeingMousedOver = NULL;
  429. }
  430. #ifdef STAGING_ONLY
  431. if ( m_pMouseOverCardPanel->IsVisible() )
  432. {
  433. m_pMouseOverCardPanel->SetVisible( false );
  434. m_pItemPanelBeingMousedOver = NULL;
  435. }
  436. #endif
  437. }
  438. //-----------------------------------------------------------------------------
  439. // Purpose: Returns the index of the first selected item.
  440. //-----------------------------------------------------------------------------
  441. int CBaseLoadoutPanel::GetFirstSelectedItemIndex( bool bIncludeEmptySlots )
  442. {
  443. for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
  444. {
  445. if ( m_pItemModelPanels[i]->IsSelected() && ( bIncludeEmptySlots || m_pItemModelPanels[i]->HasItem() ) )
  446. {
  447. return i;
  448. }
  449. }
  450. return -1;
  451. }
  452. //-----------------------------------------------------------------------------
  453. // Purpose: Returns the first selected item model panel or NULL if there is no
  454. // such panel.
  455. //-----------------------------------------------------------------------------
  456. CItemModelPanel *CBaseLoadoutPanel::GetFirstSelectedItemModelPanel (bool bIncludeEmptySlots )
  457. {
  458. int i = GetFirstSelectedItemIndex( bIncludeEmptySlots );
  459. if( i == -1 )
  460. return NULL;
  461. else
  462. return m_pItemModelPanels[ i ];
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Purpose: Returns the first selected econ item view or NULL if there is no
  466. // selected item
  467. //-----------------------------------------------------------------------------
  468. CEconItemView *CBaseLoadoutPanel::GetFirstSelectedItem()
  469. {
  470. CItemModelPanel *pItemModelPanel = GetFirstSelectedItemModelPanel( false );
  471. if( pItemModelPanel )
  472. return pItemModelPanel->GetItem();
  473. else
  474. return NULL;
  475. }
  476. //-----------------------------------------------------------------------------
  477. // Purpose: Returns the next item in the specified direction, possibly switching
  478. // pages to get there
  479. //-----------------------------------------------------------------------------
  480. bool CBaseLoadoutPanel::GetAdjacentItemIndex( int nIndex, int nPage, int *pnNewIndex, int *pnNewPage, int dx, int dy )
  481. {
  482. // if we don't have a valid index the right answer is always the first item on the first page
  483. if( nIndex == -1 )
  484. {
  485. *pnNewIndex = 0;
  486. *pnNewPage = nPage;
  487. return true;
  488. }
  489. int nRow = nIndex / GetNumColumns() + dy;
  490. int nColumn = nIndex % GetNumColumns() + dx;
  491. // just limit us to the top and bottom edges
  492. if( nRow < 0 || nRow >= GetNumRows() )
  493. return false;
  494. // for columns, try to switch pages
  495. int nNewPage = nPage;
  496. while( nColumn < 0 )
  497. {
  498. if( nNewPage == 0 )
  499. break;
  500. nNewPage--;
  501. nColumn += GetNumColumns();
  502. }
  503. while( nColumn >= GetNumColumns() )
  504. {
  505. if( nNewPage == GetNumPages() - 1 )
  506. break;
  507. nNewPage++;
  508. nColumn -= GetNumColumns();
  509. }
  510. if( nColumn < 0 )
  511. {
  512. if( nNewPage != nPage )
  513. {
  514. nColumn = 0;
  515. }
  516. else
  517. {
  518. return false;
  519. }
  520. }
  521. else if( nColumn >= GetNumColumns() )
  522. {
  523. if( nNewPage != nPage )
  524. {
  525. nColumn = GetNumColumns() - 1;
  526. }
  527. else
  528. {
  529. return false;
  530. }
  531. }
  532. // never change to an invisible panel
  533. int nNewIndex = nRow * GetNumColumns() + nColumn;
  534. if( nNewIndex >= m_pItemModelPanels.Count() || !m_pItemModelPanels[ nNewIndex ]->IsVisible() )
  535. {
  536. // try to find a model panel that's still valid so we find the last one on the last valid row
  537. while( nNewIndex >= 0 && !m_pItemModelPanels[ nNewIndex ]->IsVisible() )
  538. nNewIndex--;
  539. if( nNewIndex < 0 || nNewIndex == nIndex )
  540. return false;
  541. }
  542. *pnNewPage = nNewPage;
  543. *pnNewIndex = nNewIndex;
  544. return true;
  545. }
  546. //-----------------------------------------------------------------------------
  547. // Purpose: selects the next item in the specified direction, possibly switching
  548. // pages to get there
  549. //-----------------------------------------------------------------------------
  550. void CBaseLoadoutPanel::SelectAdjacentItem( int dx, int dy )
  551. {
  552. int nSelected = GetFirstSelectedItemIndex( true );
  553. int nNewPage, nNewSelected;
  554. bool bFoundNext = GetAdjacentItemIndex( nSelected, m_nCurrentPage, &nNewSelected, &nNewPage, dx, dy );
  555. if( !bFoundNext )
  556. {
  557. vgui::surface()->PlaySound( "player/suit_denydevice.wav" );
  558. return;
  559. }
  560. // change pages
  561. if( nNewPage != m_nCurrentPage )
  562. {
  563. Assert( nNewPage >= 0 && nNewPage < GetNumPages() );
  564. SetCurrentPage( nNewPage );
  565. UpdateModelPanels();
  566. }
  567. // select the new model
  568. if( nSelected != nNewSelected )
  569. {
  570. if( nSelected != -1 && m_pItemModelPanels[ nSelected ]->IsSelected() )
  571. {
  572. m_pItemModelPanels[ nSelected ]->SetSelected( false );
  573. SetBorderForItem( m_pItemModelPanels[ nSelected ], false );
  574. }
  575. if( nNewSelected != -1 && !m_pItemModelPanels[ nNewSelected ]->IsSelected() )
  576. {
  577. m_pItemModelPanels[ nNewSelected ]->SetSelected( true );
  578. SetBorderForItem( m_pItemModelPanels[ nNewSelected ], false );
  579. if( m_bTooltipKeyPressed )
  580. {
  581. if( m_pItemModelPanels[ nNewSelected ]->HasItem() )
  582. {
  583. m_pMouseOverTooltip->ShowTooltip( m_pItemModelPanels[ nNewSelected ] );
  584. }
  585. else
  586. {
  587. m_pMouseOverTooltip->HideTooltip();
  588. }
  589. }
  590. }
  591. }
  592. OnItemSelectionChanged();
  593. }
  594. //-----------------------------------------------------------------------------
  595. // Purpose: Processes up/down/left/right keys for selecting items in the panel
  596. //-----------------------------------------------------------------------------
  597. bool CBaseLoadoutPanel::HandleItemSelectionKeyPressed( vgui::KeyCode code )
  598. {
  599. ButtonCode_t nButtonCode = GetBaseButtonCode( code );
  600. if ( nButtonCode == KEY_XBUTTON_UP ||
  601. nButtonCode == KEY_XSTICK1_UP ||
  602. nButtonCode == KEY_XSTICK2_UP ||
  603. nButtonCode == KEY_UP )
  604. {
  605. SelectAdjacentItem( 0, -1 );
  606. return true;
  607. }
  608. else if ( nButtonCode == KEY_XBUTTON_DOWN ||
  609. nButtonCode == KEY_XSTICK1_DOWN ||
  610. nButtonCode == KEY_XSTICK2_DOWN ||
  611. nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
  612. nButtonCode == KEY_DOWN )
  613. {
  614. SelectAdjacentItem( 0, 1 );
  615. return true;
  616. }
  617. else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
  618. nButtonCode == KEY_XSTICK1_RIGHT ||
  619. nButtonCode == KEY_XSTICK2_RIGHT ||
  620. nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
  621. nButtonCode == KEY_RIGHT )
  622. {
  623. SelectAdjacentItem( 1, 0 );
  624. return true;
  625. }
  626. else if ( nButtonCode == KEY_XBUTTON_LEFT ||
  627. nButtonCode == KEY_XSTICK1_LEFT ||
  628. nButtonCode == KEY_XSTICK2_LEFT ||
  629. nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
  630. nButtonCode == KEY_LEFT )
  631. {
  632. SelectAdjacentItem( -1, 0 );
  633. return true;
  634. }
  635. else if ( code == KEY_PAGEDOWN ||
  636. nButtonCode == KEY_XBUTTON_RIGHT_SHOULDER )
  637. {
  638. if( m_nCurrentPage < GetNumPages() - 1 )
  639. {
  640. SetCurrentPage( m_nCurrentPage + 1 );
  641. UpdateModelPanels();
  642. }
  643. return true;
  644. }
  645. else if ( code == KEY_PAGEUP ||
  646. nButtonCode == KEY_XBUTTON_LEFT_SHOULDER )
  647. {
  648. if( m_nCurrentPage > 0 )
  649. {
  650. SetCurrentPage( m_nCurrentPage - 1 );
  651. UpdateModelPanels();
  652. }
  653. return true;
  654. }
  655. else if ( nButtonCode == KEY_XBUTTON_Y )
  656. {
  657. m_bTooltipKeyPressed = true;
  658. CItemModelPanel *pSelection = GetFirstSelectedItemModelPanel( false );
  659. if( pSelection )
  660. {
  661. m_pMouseOverTooltip->ResetDelay();
  662. m_pMouseOverTooltip->ShowTooltip( pSelection );
  663. }
  664. return true;
  665. }
  666. else
  667. {
  668. return false;
  669. }
  670. }
  671. //-----------------------------------------------------------------------------
  672. // Purpose: Processes up/down/left/right keys for selecting items in the panel
  673. //-----------------------------------------------------------------------------
  674. bool CBaseLoadoutPanel::HandleItemSelectionKeyReleased( vgui::KeyCode code )
  675. {
  676. ButtonCode_t nButtonCode = GetBaseButtonCode( code );
  677. if( nButtonCode == KEY_XBUTTON_Y )
  678. {
  679. m_bTooltipKeyPressed = false;
  680. m_pMouseOverTooltip->HideTooltip();
  681. return true;
  682. }
  683. else
  684. {
  685. return false;
  686. }
  687. }
  688. //-----------------------------------------------------------------------------
  689. // Purpose:
  690. //-----------------------------------------------------------------------------
  691. void CBaseLoadoutPanel::SetCurrentPage( int nNewPage )
  692. {
  693. if( nNewPage < 0 || nNewPage >= GetNumPages() )
  694. return;
  695. m_nCurrentPage = nNewPage;
  696. }