//========= 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 );