diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/game_controls/navigationpanel.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/game_controls/navigationpanel.cpp')
| -rw-r--r-- | game/client/game_controls/navigationpanel.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/game/client/game_controls/navigationpanel.cpp b/game/client/game_controls/navigationpanel.cpp new file mode 100644 index 0000000..0cf616d --- /dev/null +++ b/game/client/game_controls/navigationpanel.cpp @@ -0,0 +1,324 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// + +#include "cbase.h" +#include "game_controls/navigationpanel.h" +#include "econ/econ_controls.h" +#include "vgui_controls/Frame.h" +#include "vgui/IInput.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- + +using namespace vgui; + +//----------------------------------------------------------------------------- + +DECLARE_BUILD_FACTORY( CNavigationPanel ); + +//----------------------------------------------------------------------------- + +class CNavButton : public CExImageButton +{ + DECLARE_CLASS_SIMPLE( CNavButton, CExImageButton ); +public: + CNavButton( Panel *parent, const char *name, const char *text = "", Panel *pActionSignalTarget = NULL, const char *cmd = NULL ) + : CExImageButton( parent, name, text, pActionSignalTarget, cmd ), m_iUserData( -1 ) {} + + CNavButton( Panel *parent, const char *name, const wchar_t *wszText = L"", Panel *pActionSignalTarget = NULL, const char *cmd = NULL ) + : CExImageButton( parent, name, wszText, pActionSignalTarget, cmd ) , m_iUserData( -1 ) {} + + virtual void ApplySettings( KeyValues *pInResourceData ) + { + BaseClass::ApplySettings( pInResourceData ); + + if ( m_iUserData < 0 ) + { + m_iUserData = pInResourceData->GetInt( "userdata", -1 ); AssertMsg( m_iUserData != -1, "Any messages sent for this button will have invalid user data!" ); + } + } + + int m_iUserData; +}; + +//----------------------------------------------------------------------------- + +CNavigationPanel::CNavigationPanel( Panel *pParent, const char *pName, bool bAddParentAsActionSignalTarget/*=true*/ ) +: BaseClass( pParent, pName ), + m_bAutoLayout( false ), + m_bAutoScale( true ), + m_bDisplayVertical( false ), + m_iSelectedButton( 0 ), +// m_nAlignment( ALIGN_CENTER ), + m_pKVButtonSettings( NULL ) +{ + if ( bAddParentAsActionSignalTarget && pParent ) + { + AddActionSignalTarget( pParent ); + } +} + +CNavigationPanel::~CNavigationPanel() +{ +} + +void CNavigationPanel::AddButton( int iUserData, const char *pTextToken ) +{ + const int i = m_vecButtons.Count(); + CNavButton *pNewButton = new CNavButton( this, CFmtStr( "button_%i", i ).Access(), pTextToken ); + pNewButton->m_iUserData = iUserData; + pNewButton->InvalidateLayout( true, false ); + pNewButton->SetCommand( CFmtStr( "select_%i", i ).Access() ); + m_vecButtons.AddToTail( pNewButton ); +} + +CExImageButton *CNavigationPanel::GetButton( int index ) +{ + return m_vecButtons[ index ]; +} + +void CNavigationPanel::ApplySettings( KeyValues *pInResourceData ) +{ + BaseClass::ApplySettings( pInResourceData ); + + /* + const char *pAlignment = pInResourceData->GetString( "align", NULL ); + if ( pAlignment ) + { + if ( !V_strnicmp( pAlignment, "west", 4 ) ) + { + m_nAlignment = ALIGN_WEST; + } + else if ( !V_strnicmp( pAlignment, "center", 6 ) ) + { + m_nAlignment = ALIGN_CENTER; + } + else if ( !V_strnicmp( pAlignment, "east", 4 ) ) + { + AssertMsg( 0, "This type of alignment is not supported." ); + } + } + */ + + m_bAutoLayout = pInResourceData->GetBool( "auto_layout", false ); + m_bAutoScale = pInResourceData->GetBool( "auto_scale", true ); + m_bDisplayVertical = pInResourceData->GetBool( "display_vertically", false ); + + KeyValues *pKVButtonSettings = pInResourceData->FindKey( "ButtonSettings" ); AssertMsg( pKVButtonSettings, "This is required" ); + if ( !pKVButtonSettings ) + { + AssertMsg( 0, "No button settings specified. CNavigationPanel is useless without this data." ); + return; + } + + // Cache this off for later + if ( m_pKVButtonSettings ) + { + m_pKVButtonSettings->deleteThis(); + m_pKVButtonSettings = NULL; + } + m_pKVButtonSettings = pKVButtonSettings->MakeCopy(); + + // Get individual button data and apply now + KeyValues *pKVButtons = pInResourceData->FindKey( "Buttons" ); + if ( !pKVButtons ) + return; + + // Go through each image description and create a button + if ( m_vecButtons.Count() ) + return; + + int i = 0; + FOR_EACH_SUBKEY( pKVButtons, pKVCurButton ) + { + CNavButton *pNewButton = new CNavButton( this, pKVCurButton->GetString( "FieldName", pKVCurButton->GetName() ), L"" ); + pNewButton->ApplySettings( pKVCurButton ); + pNewButton->InvalidateLayout( true, false ); + pNewButton->SetCommand( CFmtStr( "select_%i", i ).Access() ); + m_vecButtons.AddToTail( pNewButton ); + ++i; + } + + if ( m_vecButtons.IsValidIndex( m_iSelectedButtonDefault ) ) + { + UpdateButtonSelectionStates( m_iSelectedButtonDefault ); + m_vecButtons[ m_iSelectedButtonDefault ]->InvalidateLayout( true ); + + const int iUserData = m_vecButtons[ m_iSelectedButtonDefault ]->m_iUserData; + PostActionSignal( new KeyValues( "NavButtonSelected", "userdata", iUserData ) ); + } +} + +void CNavigationPanel::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); +} + +void CNavigationPanel::PerformLayout() +{ + if ( !m_vecButtons.Count() ) + return; + + if ( !m_pKVButtonSettings ) + return; + + BaseClass::PerformLayout(); + + // Get from settings + int nSettingWidth = m_pKVButtonSettings->GetInt( "wide" ); + int nSettingHeight = m_pKVButtonSettings->GetInt( "tall" ); + + // Button dimensions for setting positions + int nButtonWidth = nSettingWidth; + int nButtonHeight = nSettingHeight; + + if ( m_bAutoScale ) + { + // Get image size + int nImageW, nImageH; + m_vecButtons[0]->GetImage()->GetSize( nImageW, nImageH ); + + int nWidth, nHeight; + if ( m_bDisplayVertical ) + { + nWidth = GetWide(); + nHeight = nSettingHeight * nWidth / ( nSettingWidth > 0 ? nSettingWidth : 1 ); + } + else + { + nHeight = GetTall(); + nWidth = nSettingWidth * nHeight / ( nSettingHeight > 0 ? nSettingHeight : 1 ); + } + + // Update button dimensions to scaled versions + nButtonWidth = nWidth; + nButtonHeight = nHeight; + } + + FOR_EACH_VEC( m_vecButtons, i ) + { + if ( m_vecButtons[i] && m_pKVButtonSettings ) + { + // Apply generic settings + m_vecButtons[i]->ApplySettings( m_pKVButtonSettings ); + } + + if ( m_bAutoLayout ) + { + // Display buttons vertically or horizontally? + if ( m_bDisplayVertical ) + { + m_vecButtons[i]->SetPos( 0, i * ( nButtonHeight + m_nVerticalBuffer ) ); + } + else + { + const int nStartX = 0;//0.5f * ( GetWide() - NumButtons() * ( nButtonWidth + m_nHorizontalBuffer ) ); + m_vecButtons[i]->SetPos( nStartX + i * ( nButtonWidth + m_nHorizontalBuffer ), 0 ); + } + } + + if ( m_bAutoScale ) + { + m_vecButtons[i]->SetSize( nButtonWidth, nButtonHeight ); + m_vecButtons[i]->GetImage()->SetSize( nButtonWidth, nButtonHeight ); + } + + m_vecButtons[i]->SetVisible( true ); + } +} + +void CNavigationPanel::OnCommand( const char *pCommand ) +{ + if ( !V_strnicmp( pCommand, "select_", 7 ) ) + { + const int iButton = atoi( pCommand + 7 ); AssertMsg( m_vecButtons.IsValidIndex( iButton ), "Button index out of range!" ); + if ( !m_vecButtons.IsValidIndex( iButton ) ) + return; + + UpdateButtonSelectionStates( iButton ); + + const int iUserData = m_vecButtons[ iButton ]->m_iUserData; + PostActionSignal( new KeyValues( "NavButtonSelected", "userdata", iUserData ) ); + } + else + { + BaseClass::OnCommand( pCommand ); + } +} + +void CNavigationPanel::OnThink() +{ + BaseClass::OnThink(); + + // Make sure we only ever have one button in the selection state, since it's + // possible to do this if you select a button, then click and drag on another + // button, and release the mouse elsewhere. + if ( !vgui::input()->IsMouseDown( MOUSE_LEFT ) ) + { + UpdateButtonSelectionStates( m_iSelectedButton ); + } +} + + +void CNavigationPanel::UpdateButtonSelectionStates( int iButton ) +{ + if ( m_iSelectedButton != iButton ) + { + m_iSelectedButton = iButton; + } + + // Set the correct button as selected, all other buttons as not selected + for ( int i = 0; i < NumButtons(); ++i ) + { + CNavButton *pCurButton = m_vecButtons[ i ]; + if ( !pCurButton ) + continue; + + bool bShouldSelect = iButton == i; + pCurButton->SetSelected( bShouldSelect ); + pCurButton->InvalidateLayout(); + } +} + +//----------------------------------------------------------------------------- + +#ifdef _DEBUG + +class CNavPanelTest : public Frame +{ + DECLARE_CLASS_SIMPLE( CNavPanelTest, Frame ); + +public: + CNavPanelTest( vgui::Panel *pParent ) + : Frame( pParent, "NavPanelTest" ) + { + SetProportional( true ); + LoadControlSettings( "Resource/UI/NavigationPanelTest.res" ); + } +}; + +CON_COMMAND( open_navpanel_test, "" ) +{ + CNavPanelTest *pPanel = SETUP_PANEL( new CNavPanelTest( NULL ) ); + pPanel->SetVisible( true ); + pPanel->InvalidateLayout( false, true ); + + engine->ClientCmd_Unrestricted( "gameui_activate" ); + + const int nWidth = XRES( 300 ); + const int nHeight = YRES( 300 ); + + pPanel->SetBounds( + ( ScreenWidth() - nWidth ) / 2, + ( ScreenHeight() - nHeight ) / 2, + nWidth, + nHeight + ); + + pPanel->Activate(); +} + +#endif // _DEBUG |