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.
467 lines
14 KiB
467 lines
14 KiB
//===== Copyright © 1996-2011, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//===========================================================================//
|
|
|
|
#include <stdio.h>
|
|
#include "vgui/ILocalize.h"
|
|
#include "vgui_controls/footerpanel.h"
|
|
#include "vgui_controls/Frame.h"
|
|
#include "vgui/ISurface.h"
|
|
#include "vgui_controls/Label.h"
|
|
#include "vgui_controls/ControllerMap.h"
|
|
|
|
#if defined( _X360 )
|
|
#include "xbox/xbox_launch.h"
|
|
#else
|
|
#include "xbox/xboxstubs.h"
|
|
#endif
|
|
|
|
|
|
#undef MessageBox // Windows helpfully #define's this to MessageBoxA, we're using vgui::MessageBox
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
using namespace vgui;
|
|
|
|
CFooterPanel::CFooterPanel( Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
|
|
{
|
|
SetVisible( true );
|
|
SetAlpha( 0 );
|
|
m_pHelpName = NULL;
|
|
|
|
m_pSizingLabel = new vgui::Label( this, "SizingLabel", "" );
|
|
m_pSizingLabel->SetVisible( false );
|
|
|
|
m_nButtonGap = 32;
|
|
m_nButtonGapDefault = 32;
|
|
m_ButtonPinRight = 100;
|
|
m_FooterTall = 80;
|
|
|
|
int wide, tall;
|
|
surface()->GetScreenSize(wide, tall);
|
|
|
|
if ( tall <= 480 )
|
|
{
|
|
m_FooterTall = 60;
|
|
}
|
|
|
|
m_ButtonOffsetFromTop = 0;
|
|
m_ButtonSeparator = 4;
|
|
m_TextAdjust = 0;
|
|
|
|
m_bPaintBackground = false;
|
|
m_bCenterHorizontal = false;
|
|
|
|
m_szButtonFont[0] = '\0';
|
|
m_szTextFont[0] = '\0';
|
|
m_szFGColor[0] = '\0';
|
|
m_szBGColor[0] = '\0';
|
|
}
|
|
|
|
CFooterPanel::~CFooterPanel()
|
|
{
|
|
SetHelpNameAndReset( NULL );
|
|
|
|
delete m_pSizingLabel;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: apply scheme settings
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
|
{
|
|
BaseClass::ApplySchemeSettings( pScheme );
|
|
|
|
// $FIXME(hpe) quick hack for PC fonts
|
|
if ( IsPC() )
|
|
{
|
|
m_hButtonFont = pScheme->GetFont( ( m_szButtonFont[0] != '\0' ) ? m_szButtonFont : "Default" );
|
|
m_hTextFont = pScheme->GetFont( ( m_szTextFont[0] != '\0' ) ? m_szTextFont : "Default" );
|
|
}
|
|
else
|
|
{
|
|
m_hButtonFont = pScheme->GetFont( ( m_szButtonFont[0] != '\0' ) ? m_szButtonFont : "GameUIButtons" );
|
|
m_hTextFont = pScheme->GetFont( ( m_szTextFont[0] != '\0' ) ? m_szTextFont : "X360_Title_1" );
|
|
}
|
|
|
|
SetFgColor( pScheme->GetColor( m_szFGColor, Color( 255, 255, 255, 255 ) ) );
|
|
SetBgColor( pScheme->GetColor( m_szBGColor, Color( 0, 0, 0, 255 ) ) );
|
|
|
|
int x, y, w, h;
|
|
GetParent()->GetBounds( x, y, w, h );
|
|
SetBounds( x, h - m_FooterTall, w, m_FooterTall );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: apply settings
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::ApplySettings( KeyValues *inResourceData )
|
|
{
|
|
BaseClass::ApplySettings( inResourceData );
|
|
|
|
// gap between hints
|
|
m_nButtonGap = inResourceData->GetInt( "buttongap", 32 );
|
|
m_nButtonGapDefault = m_nButtonGap;
|
|
m_ButtonPinRight = inResourceData->GetInt( "button_pin_right", 100 );
|
|
m_FooterTall = inResourceData->GetInt( "tall", 80 );
|
|
m_ButtonOffsetFromTop = inResourceData->GetInt( "buttonoffsety", 0 );
|
|
m_ButtonSeparator = inResourceData->GetInt( "button_separator", 4 );
|
|
m_TextAdjust = inResourceData->GetInt( "textadjust", 0 );
|
|
|
|
m_bCenterHorizontal = ( inResourceData->GetInt( "center", 0 ) == 1 );
|
|
m_bPaintBackground = ( inResourceData->GetInt( "paintbackground", 0 ) == 1 );
|
|
|
|
// fonts for text and button
|
|
Q_strncpy( m_szTextFont, inResourceData->GetString( "fonttext", "MenuLarge" ), sizeof( m_szTextFont ) );
|
|
Q_strncpy( m_szButtonFont, inResourceData->GetString( "fontbutton", "GameUIButtons" ), sizeof( m_szButtonFont ) );
|
|
|
|
// fg and bg colors
|
|
Q_strncpy( m_szFGColor, inResourceData->GetString( "fgcolor", "White" ), sizeof( m_szFGColor ) );
|
|
Q_strncpy( m_szBGColor, inResourceData->GetString( "bgcolor", "Black" ), sizeof( m_szBGColor ) );
|
|
|
|
for ( KeyValues *pButton = inResourceData->GetFirstSubKey(); pButton != NULL; pButton = pButton->GetNextKey() )
|
|
{
|
|
const char *pName = pButton->GetName();
|
|
|
|
if ( !Q_stricmp( pName, "button" ) )
|
|
{
|
|
// Add a button to the footer
|
|
const char *pText = pButton->GetString( "text", "NULL" );
|
|
const char *pIcon = pButton->GetString( "icon", "NULL" );
|
|
AddNewButtonLabel( pText, pIcon );
|
|
}
|
|
}
|
|
|
|
InvalidateLayout( false, true ); // force ApplySchemeSettings to run
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: adds button icons and help text to the footer panel when activating a menu
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::AddButtonsFromMap( vgui::Frame *pMenu )
|
|
{
|
|
SetHelpNameAndReset( pMenu->GetName() );
|
|
|
|
CControllerMap *pMap = dynamic_cast<CControllerMap*>( pMenu->FindChildByName( "ControllerMap" ) );
|
|
if ( pMap )
|
|
{
|
|
int buttonCt = pMap->NumButtons();
|
|
for ( int i = 0; i < buttonCt; ++i )
|
|
{
|
|
const char *pText = pMap->GetBindingText( i );
|
|
if ( pText )
|
|
{
|
|
AddNewButtonLabel( pText, pMap->GetBindingIcon( i ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CFooterPanel::SetStandardDialogButtons()
|
|
{
|
|
SetHelpNameAndReset( "Dialog" );
|
|
//=============================================================================
|
|
// HPE_BEGIN:
|
|
// [tj] Changed "Action" to "Select"
|
|
//=============================================================================
|
|
AddNewButtonLabel( "#GameUI_Select", "#GameUI_Icons_A_BUTTON" );
|
|
//=============================================================================
|
|
// HPE_END
|
|
//=============================================================================
|
|
AddNewButtonLabel( "#GameUI_Back", "#GameUI_Icons_B_BUTTON" );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Caller must tag the button layout. May support reserved names
|
|
// to provide stock help layouts trivially.
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::SetHelpNameAndReset( const char *pName )
|
|
{
|
|
if ( m_pHelpName )
|
|
{
|
|
free( m_pHelpName );
|
|
m_pHelpName = NULL;
|
|
}
|
|
|
|
if ( pName )
|
|
{
|
|
m_pHelpName = strdup( pName );
|
|
}
|
|
|
|
ClearButtons();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Caller must tag the button layout
|
|
//-----------------------------------------------------------------------------
|
|
const char *CFooterPanel::GetHelpName()
|
|
{
|
|
return m_pHelpName;
|
|
}
|
|
|
|
void CFooterPanel::ClearButtons( void )
|
|
{
|
|
m_ButtonLabels.PurgeAndDeleteElements();
|
|
}
|
|
|
|
//=============================================================================
|
|
// HPE_BEGIN:
|
|
// [smessick]
|
|
//=============================================================================
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Sets the pin right location with adjustments based on the current
|
|
// screen width and height. The given pixel offset is assumed to be based on
|
|
// a 640x480 screen.
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::SetButtonPinRightProportional( int nButtonPinRight )
|
|
{
|
|
int screenWide, screenTall;
|
|
surface()->GetScreenSize(screenWide, screenTall);
|
|
|
|
float tallDiff = screenTall / 480.0f;
|
|
m_ButtonPinRight = ( ( screenWide - ( 640 * tallDiff ) ) * 0.5f ) + ( nButtonPinRight * tallDiff );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Set the y offset from the top of the screen.
|
|
// The given pixel offset is assumed to be based on a 640x480 screen.
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::SetButtonOffsetFromTopProportional( int yOffset )
|
|
{
|
|
int screenWide, screenTall;
|
|
surface()->GetScreenSize(screenWide, screenTall);
|
|
|
|
m_ButtonOffsetFromTop = yOffset * screenTall / 480.0f;
|
|
}
|
|
|
|
//=============================================================================
|
|
// HPE_END
|
|
//=============================================================================
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: creates a new button label with icon and text
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::AddNewButtonLabel( const char *text, const char *icon )
|
|
{
|
|
ButtonLabel_t *button = new ButtonLabel_t;
|
|
|
|
Q_strncpy( button->name, text, MAX_PATH );
|
|
button->bVisible = true;
|
|
|
|
// Button icons are a single character
|
|
wchar_t *pIcon = g_pVGuiLocalize->Find( icon );
|
|
if ( pIcon )
|
|
{
|
|
button->icon[0] = pIcon[0];
|
|
button->icon[1] = '\0';
|
|
}
|
|
else
|
|
{
|
|
button->icon[0] = '\0';
|
|
}
|
|
|
|
// Set the help text
|
|
wchar_t *pText = g_pVGuiLocalize->Find( text );
|
|
if ( pText )
|
|
{
|
|
wcsncpy( button->text, pText, wcslen( pText ) + 1 );
|
|
}
|
|
else
|
|
{
|
|
button->text[0] = '\0';
|
|
}
|
|
|
|
m_ButtonLabels.AddToTail( button );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Shows/Hides a button label
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::ShowButtonLabel( const char *name, bool show )
|
|
{
|
|
for ( int i = 0; i < m_ButtonLabels.Count(); ++i )
|
|
{
|
|
if ( !Q_stricmp( m_ButtonLabels[ i ]->name, name ) )
|
|
{
|
|
m_ButtonLabels[ i ]->bVisible = show;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Changes a button's text
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::SetButtonText( const char *buttonName, const char *text )
|
|
{
|
|
for ( int i = 0; i < m_ButtonLabels.Count(); ++i )
|
|
{
|
|
if ( !Q_stricmp( m_ButtonLabels[ i ]->name, buttonName ) )
|
|
{
|
|
wchar_t *wtext = g_pVGuiLocalize->Find( text );
|
|
if ( text )
|
|
{
|
|
wcsncpy( m_ButtonLabels[ i ]->text, wtext, wcslen( wtext ) + 1 );
|
|
}
|
|
else
|
|
{
|
|
m_ButtonLabels[ i ]->text[ 0 ] = '\0';
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Footer panel background rendering
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::PaintBackground( void )
|
|
{
|
|
if ( !m_bPaintBackground )
|
|
return;
|
|
|
|
BaseClass::PaintBackground();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Footer panel rendering
|
|
//-----------------------------------------------------------------------------
|
|
void CFooterPanel::Paint( void )
|
|
{
|
|
//=============================================================================
|
|
// HPE_BEGIN:
|
|
// [smessick] Don't draw if alpha'd out.
|
|
//=============================================================================
|
|
if ( GetAlpha() == 0 )
|
|
{
|
|
return;
|
|
}
|
|
//=============================================================================
|
|
// HPE_END
|
|
//=============================================================================
|
|
|
|
// inset from right edge
|
|
int wide = GetWide();
|
|
int right = wide - m_ButtonPinRight;
|
|
|
|
// center the text within the button
|
|
int buttonHeight = vgui::surface()->GetFontTall( m_hButtonFont );
|
|
int fontHeight = vgui::surface()->GetFontTall( m_hTextFont );
|
|
int textY = ( buttonHeight - fontHeight )/2 + m_TextAdjust;
|
|
|
|
if ( textY < 0 )
|
|
{
|
|
textY = 0;
|
|
}
|
|
|
|
int y = m_ButtonOffsetFromTop;
|
|
|
|
if ( !m_bCenterHorizontal )
|
|
{
|
|
// draw the buttons, right to left
|
|
int x = right;
|
|
|
|
for ( int i = 0; i < m_ButtonLabels.Count(); ++i )
|
|
{
|
|
ButtonLabel_t *pButton = m_ButtonLabels[i];
|
|
if ( !pButton->bVisible )
|
|
continue;
|
|
|
|
// Get the string length
|
|
m_pSizingLabel->SetFont( m_hTextFont );
|
|
m_pSizingLabel->SetText( pButton->text );
|
|
m_pSizingLabel->SizeToContents();
|
|
|
|
int iTextWidth = m_pSizingLabel->GetWide();
|
|
|
|
if ( iTextWidth == 0 )
|
|
x += m_nButtonGap; // There's no text, so remove the gap between buttons
|
|
else
|
|
x -= iTextWidth;
|
|
|
|
// Draw the string
|
|
vgui::surface()->DrawSetTextFont( m_hTextFont );
|
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
|
vgui::surface()->DrawSetTextPos( x, y + textY );
|
|
vgui::surface()->DrawPrintText( pButton->text, wcslen( pButton->text ) );
|
|
|
|
// Draw the button
|
|
// back up button width and a little extra to leave a gap between button and text
|
|
x -= ( vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] ) + m_ButtonSeparator );
|
|
vgui::surface()->DrawSetTextFont( m_hButtonFont );
|
|
vgui::surface()->DrawSetTextColor( 255, 255, 255, 255 );
|
|
vgui::surface()->DrawSetTextPos( x, y );
|
|
vgui::surface()->DrawPrintText( pButton->icon, 1 );
|
|
|
|
// back up to next string
|
|
x -= m_nButtonGap;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// center the buttons (as a group)
|
|
int x = wide / 2;
|
|
int totalWidth = 0;
|
|
int i = 0;
|
|
int nButtonCount = 0;
|
|
|
|
// need to loop through and figure out how wide our buttons and text are (with gaps between) so we can offset from the center
|
|
for ( i = 0; i < m_ButtonLabels.Count(); ++i )
|
|
{
|
|
ButtonLabel_t *pButton = m_ButtonLabels[i];
|
|
if ( !pButton->bVisible )
|
|
continue;
|
|
|
|
// Get the string length
|
|
m_pSizingLabel->SetFont( m_hTextFont );
|
|
m_pSizingLabel->SetText( pButton->text );
|
|
m_pSizingLabel->SizeToContents();
|
|
|
|
totalWidth += vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] );
|
|
totalWidth += m_ButtonSeparator;
|
|
totalWidth += m_pSizingLabel->GetWide();
|
|
|
|
nButtonCount++; // keep track of how many active buttons we'll be drawing
|
|
}
|
|
|
|
totalWidth += ( nButtonCount - 1 ) * m_nButtonGap; // add in the gaps between the buttons
|
|
x -= ( totalWidth / 2 );
|
|
|
|
for ( i = 0; i < m_ButtonLabels.Count(); ++i )
|
|
{
|
|
ButtonLabel_t *pButton = m_ButtonLabels[i];
|
|
if ( !pButton->bVisible )
|
|
continue;
|
|
|
|
// Get the string length
|
|
m_pSizingLabel->SetFont( m_hTextFont );
|
|
m_pSizingLabel->SetText( pButton->text );
|
|
m_pSizingLabel->SizeToContents();
|
|
|
|
int iTextWidth = m_pSizingLabel->GetWide();
|
|
|
|
// Draw the icon
|
|
vgui::surface()->DrawSetTextFont( m_hButtonFont );
|
|
vgui::surface()->DrawSetTextColor( 255, 255, 255, 255 );
|
|
vgui::surface()->DrawSetTextPos( x, y );
|
|
vgui::surface()->DrawPrintText( pButton->icon, 1 );
|
|
x += vgui::surface()->GetCharacterWidth( m_hButtonFont, pButton->icon[0] ) + m_ButtonSeparator;
|
|
|
|
// Draw the string
|
|
vgui::surface()->DrawSetTextFont( m_hTextFont );
|
|
vgui::surface()->DrawSetTextColor( GetFgColor() );
|
|
vgui::surface()->DrawSetTextPos( x, y + textY );
|
|
vgui::surface()->DrawPrintText( pButton->text, wcslen( pButton->text ) );
|
|
|
|
x += iTextWidth + m_nButtonGap;
|
|
}
|
|
}
|
|
}
|
|
|
|
DECLARE_BUILD_FACTORY( CFooterPanel );
|