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.
160 lines
5.5 KiB
160 lines
5.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "vgui_controls/ControllerMap.h" |
|
#include "vgui/ISurface.h" |
|
#include "vgui/KeyCode.h" |
|
#include "KeyValues.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
using namespace vgui; |
|
|
|
struct keystring_t |
|
{ |
|
int code; |
|
const char *name; |
|
}; |
|
|
|
static const keystring_t s_ControllerButtons[] = { { KEY_XBUTTON_UP, "KEY_XBUTTON_UP" }, |
|
{ KEY_XBUTTON_DOWN, "KEY_XBUTTON_DOWN" }, |
|
{ KEY_XBUTTON_LEFT, "KEY_XBUTTON_LEFT" }, |
|
{ KEY_XBUTTON_RIGHT, "KEY_XBUTTON_RIGHT" }, |
|
{ KEY_XBUTTON_START, "KEY_XBUTTON_START" }, |
|
{ KEY_XBUTTON_BACK, "KEY_XBUTTON_BACK" }, |
|
{ KEY_XBUTTON_STICK1, "KEY_XBUTTON_STICK1" }, |
|
{ KEY_XBUTTON_STICK2, "KEY_XBUTTON_STICK2" }, |
|
{ KEY_XBUTTON_A, "KEY_XBUTTON_A" }, |
|
{ KEY_XBUTTON_B, "KEY_XBUTTON_B" }, |
|
{ KEY_XBUTTON_X, "KEY_XBUTTON_X" }, |
|
{ KEY_XBUTTON_Y, "KEY_XBUTTON_Y" }, |
|
{ KEY_XBUTTON_LEFT_SHOULDER, "KEY_XBUTTON_LEFT_SHOULDER" }, |
|
{ KEY_XBUTTON_RIGHT_SHOULDER, "KEY_XBUTTON_RIGHT_SHOULDER" }, |
|
{ KEY_XBUTTON_LTRIGGER, "KEY_XBUTTON_LTRIGGER" }, |
|
{ KEY_XBUTTON_RTRIGGER, "KEY_XBUTTON_RTRIGGER" }, |
|
{ KEY_XSTICK1_UP, "KEY_XSTICK1_UP" }, |
|
{ KEY_XSTICK1_DOWN, "KEY_XSTICK1_DOWN" }, |
|
{ KEY_XSTICK1_LEFT, "KEY_XSTICK1_LEFT" }, |
|
{ KEY_XSTICK1_RIGHT, "KEY_XSTICK1_RIGHT" }, |
|
{ KEY_XSTICK2_UP, "KEY_XSTICK2_UP" }, |
|
{ KEY_XSTICK2_DOWN, "KEY_XSTICK2_DOWN" }, |
|
{ KEY_XSTICK2_LEFT, "KEY_XSTICK2_LEFT" }, |
|
{ KEY_XSTICK2_RIGHT, "KEY_XSTICK2_RIGHT" } }; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: for the UtlMap |
|
//----------------------------------------------------------------------------- |
|
bool lessFunc( const int &lhs, const int &rhs ) |
|
{ |
|
return lhs < rhs; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: converts a button name string to the equivalent keycode |
|
//----------------------------------------------------------------------------- |
|
int StringToButtonCode( const char *name ) |
|
{ |
|
for ( int i = 0; i < ARRAYSIZE( s_ControllerButtons ); ++i ) |
|
{ |
|
if ( !Q_stricmp( s_ControllerButtons[i].name, name ) ) |
|
return s_ControllerButtons[i].code; |
|
} |
|
return -1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: intercepts the keycode from its parent, and handles it according to |
|
// the button map. If the keycode isn't handled, it gets passed on to the parent. |
|
//----------------------------------------------------------------------------- |
|
void CControllerMap::OnKeyCodeTyped( vgui::KeyCode code ) |
|
{ |
|
int idx = m_buttonMap.Find( code ); |
|
if ( idx != m_buttonMap.InvalidIndex() ) |
|
{ |
|
GetParent()->OnCommand( m_buttonMap[idx].cmd.String() ); |
|
} |
|
else |
|
{ |
|
// Disable input before forwarding the message |
|
// so it doesn't feed back here again. |
|
SetKeyBoardInputEnabled( false ); |
|
GetParent()->OnKeyCodeTyped( code ); |
|
SetKeyBoardInputEnabled( true ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: constructor |
|
//----------------------------------------------------------------------------- |
|
CControllerMap::CControllerMap( vgui::Panel *parent, const char *name ) : BaseClass( parent, name ) |
|
{ |
|
m_buttonMap.SetLessFunc( lessFunc ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: sets up the button/command bindings |
|
//----------------------------------------------------------------------------- |
|
void CControllerMap::ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
BaseClass::ApplySettings( inResourceData ); |
|
|
|
// loop through all the data adding items to the menu |
|
for (KeyValues *dat = inResourceData->GetFirstSubKey(); dat != NULL; dat = dat->GetNextKey()) |
|
{ |
|
if ( !Q_stricmp( dat->GetName(), "button" ) ) |
|
{ |
|
const char *buttonName = dat->GetString( "name", "" ); |
|
int keycode = StringToButtonCode( buttonName ); |
|
if ( keycode != -1 ) |
|
{ |
|
button_t b; |
|
b.cmd = CUtlSymbol( dat->GetString( "command", "" ) ); |
|
|
|
// text and icon are optional - their existence means this button |
|
// should be displayed in the footer panel. |
|
const char *helpText = dat->GetString( "text", NULL ); |
|
if ( helpText ) |
|
{ |
|
b.text = CUtlSymbol( helpText ); |
|
b.icon = CUtlSymbol( dat->GetString( "icon", NULL ) ); |
|
} |
|
|
|
m_buttonMap.Insert( keycode, b ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: gets the help text for a binding, if it exists |
|
//----------------------------------------------------------------------------- |
|
const char *CControllerMap::GetBindingText( int idx ) |
|
{ |
|
CUtlSymbol s = m_buttonMap[idx].text; |
|
if ( s.IsValid() ) |
|
{ |
|
return s.String(); |
|
} |
|
return NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: gets the icon for a binding, if it exists |
|
//----------------------------------------------------------------------------- |
|
const char *CControllerMap::GetBindingIcon( int idx ) |
|
{ |
|
CUtlSymbol s = m_buttonMap[idx].icon; |
|
if ( s.IsValid() ) |
|
{ |
|
return s.String(); |
|
} |
|
return NULL; |
|
} |
|
|
|
DECLARE_BUILD_FACTORY( CControllerMap ); |
|
|
|
|