mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-09 18:29:35 +00:00
1
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user