summaryrefslogtreecommitdiff
path: root/gameui/OptionsSubKeyboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gameui/OptionsSubKeyboard.cpp')
-rw-r--r--gameui/OptionsSubKeyboard.cpp839
1 files changed, 839 insertions, 0 deletions
diff --git a/gameui/OptionsSubKeyboard.cpp b/gameui/OptionsSubKeyboard.cpp
new file mode 100644
index 0000000..f545917
--- /dev/null
+++ b/gameui/OptionsSubKeyboard.cpp
@@ -0,0 +1,839 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//===========================================================================//
+
+
+#include "OptionsSubKeyboard.h"
+#include "EngineInterface.h"
+#include "vcontrolslistpanel.h"
+
+#include <vgui_controls/Button.h>
+#include <vgui_controls/Label.h>
+#include <vgui_controls/ListPanel.h>
+#include <vgui_controls/QueryBox.h>
+
+#include <vgui/Cursor.h>
+#include <vgui/IVGui.h>
+#include <vgui/ISurface.h>
+#include "tier1/KeyValues.h"
+#include "tier1/convar.h"
+#include <vgui/KeyCode.h>
+#include <vgui/MouseCode.h>
+#include <vgui/ISystem.h>
+#include <vgui/IInput.h>
+
+#include "filesystem.h"
+#include "tier1/utlbuffer.h"
+#include "IGameUIFuncs.h"
+#include <vstdlib/IKeyValuesSystem.h>
+#include "tier2/tier2.h"
+#include "inputsystem/iinputsystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+COptionsSubKeyboard::COptionsSubKeyboard(vgui::Panel *parent) : PropertyPage(parent, NULL)
+{
+ memset( m_Bindings, 0, sizeof( m_Bindings ));
+
+ // create the key bindings list
+ CreateKeyBindingList();
+ // Store all current key bindings
+ SaveCurrentBindings();
+ // Parse default descriptions
+ ParseActionDescriptions();
+
+ m_pSetBindingButton = new Button(this, "ChangeKeyButton", "");
+ m_pClearBindingButton = new Button(this, "ClearKeyButton", "");
+
+ LoadControlSettings("Resource/OptionsSubKeyboard.res");
+
+ m_pSetBindingButton->SetEnabled(false);
+ m_pClearBindingButton->SetEnabled(false);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+COptionsSubKeyboard::~COptionsSubKeyboard()
+{
+ DeleteSavedBindings();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: reloads current keybinding
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnResetData()
+{
+ // Populate list based on current settings
+ FillInCurrentBindings();
+ if ( IsVisible() )
+ {
+ m_pKeyBindList->SetSelectedItem(0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: saves out keybinding changes
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnApplyChanges()
+{
+ ApplyAllBindings();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Create key bindings list control
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::CreateKeyBindingList()
+{
+ // Create the control
+ m_pKeyBindList = new VControlsListPanel(this, "listpanel_keybindlist");
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: binds double-clicking or hitting enter in the keybind list to changing the key
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnKeyCodeTyped(vgui::KeyCode code)
+{
+ if (code == KEY_ENTER)
+ {
+ OnCommand("ChangeKey");
+ }
+ else
+ {
+ BaseClass::OnKeyCodeTyped(code);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: command handler
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnCommand( const char *command )
+{
+ if ( !stricmp( command, "Defaults" ) )
+ {
+ // open a box asking if we want to restore defaults
+ QueryBox *box = new QueryBox("#GameUI_KeyboardSettings", "#GameUI_KeyboardSettingsText");
+ box->AddActionSignalTarget(this);
+ box->SetOKCommand(new KeyValues("Command", "command", "DefaultsOK"));
+ box->DoModal();
+ }
+ else if ( !stricmp(command, "DefaultsOK"))
+ {
+ // Restore defaults from default keybindings file
+ FillInDefaultBindings();
+ m_pKeyBindList->RequestFocus();
+ }
+ else if ( !m_pKeyBindList->IsCapturing() && !stricmp( command, "ChangeKey" ) )
+ {
+ m_pKeyBindList->StartCaptureMode(dc_blank);
+ }
+ else if ( !m_pKeyBindList->IsCapturing() && !stricmp( command, "ClearKey" ) )
+ {
+ OnKeyCodePressed(KEY_DELETE);
+ m_pKeyBindList->RequestFocus();
+ }
+ else if ( !stricmp(command, "Advanced") )
+ {
+ OpenKeyboardAdvancedDialog();
+ }
+ else
+ {
+ BaseClass::OnCommand( command );
+ }
+}
+
+const char *UTIL_Parse( const char *data, char *token, int sizeofToken )
+{
+ data = engine->ParseFile( data, token, sizeofToken );
+ return data;
+}
+static char *UTIL_CopyString( const char *in )
+{
+ int len = strlen( in ) + 1;
+ char *out = new char[ len ];
+ Q_strncpy( out, in, len );
+ return out;
+}
+
+#ifndef _XBOX
+char *UTIL_va(char *format, ...)
+{
+ va_list argptr;
+ static char string[4][1024];
+ static int curstring = 0;
+
+ curstring = ( curstring + 1 ) % 4;
+
+ va_start (argptr, format);
+ Q_vsnprintf( string[curstring], 1024, format, argptr );
+ va_end (argptr);
+
+ return string[curstring];
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::ParseActionDescriptions( void )
+{
+ char szBinding[256];
+ char szDescription[256];
+
+ KeyValues *item;
+
+ // Load the default keys list
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+ if ( !g_pFullFileSystem->ReadFile( "scripts/kb_act.lst", NULL, buf ) )
+ return;
+
+ const char *data = (const char*)buf.Base();
+
+ int sectionIndex = 0;
+ char token[512];
+ while ( 1 )
+ {
+ data = UTIL_Parse( data, token, sizeof(token) );
+ // Done.
+ if ( strlen( token ) <= 0 )
+ break;
+
+ Q_strncpy( szBinding, token, sizeof( szBinding ) );
+
+ data = UTIL_Parse( data, token, sizeof(token) );
+ if ( strlen(token) <= 0 )
+ {
+ break;
+ }
+
+ Q_strncpy(szDescription, token, sizeof( szDescription ) );
+
+ // Skip '======' rows
+ if ( szDescription[ 0 ] != '=' )
+ {
+ // Flag as special header row if binding is "blank"
+ if (!stricmp(szBinding, "blank"))
+ {
+ // add header item
+ m_pKeyBindList->AddSection(++sectionIndex, szDescription);
+ m_pKeyBindList->AddColumnToSection(sectionIndex, "Action", szDescription, SectionedListPanel::COLUMN_BRIGHT, 286);
+ m_pKeyBindList->AddColumnToSection(sectionIndex, "Key", "#GameUI_KeyButton", SectionedListPanel::COLUMN_BRIGHT, 128);
+ }
+ else
+ {
+ // Create a new: blank item
+ item = new KeyValues( "Item" );
+
+ // fill in data
+ item->SetString("Action", szDescription);
+ item->SetString("Binding", szBinding);
+ item->SetString("Key", "");
+
+ // Add to list
+ m_pKeyBindList->AddItem(sectionIndex, item);
+ item->deleteThis();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Search current data set for item which has the specified binding string
+// Input : *binding - string to find
+// Output : KeyValues or NULL on failure
+//-----------------------------------------------------------------------------
+KeyValues *COptionsSubKeyboard::GetItemForBinding( const char *binding )
+{
+ static int bindingSymbol = KeyValuesSystem()->GetSymbolForString("Binding");
+
+ // Loop through all items
+ for (int i = 0; i < m_pKeyBindList->GetItemCount(); i++)
+ {
+ KeyValues *item = m_pKeyBindList->GetItemData(m_pKeyBindList->GetItemIDFromRow(i));
+ if ( !item )
+ continue;
+
+ KeyValues *bindingItem = item->FindKey(bindingSymbol);
+ const char *bindString = bindingItem->GetString();
+
+ // Check the "Binding" key
+ if (!stricmp(bindString, binding))
+ return item;
+ }
+ // Didn't find it
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Bind the specified keyname to the specified item
+// Input : *item - Item to which to add the key
+// *keyname - The key to be added
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::AddBinding( KeyValues *item, const char *keyname )
+{
+ // See if it's already there as a binding
+ if ( !stricmp( item->GetString( "Key", "" ), keyname ) )
+ return;
+
+ // Make sure it doesn't live anywhere
+ RemoveKeyFromBindItems( item, keyname );
+
+ const char *binding = item->GetString( "Binding", "" );
+
+ // Loop through all the key bindings and set all entries that have
+ // the same binding. This allows us to have multiple entries pointing
+ // to the same binding.
+ for (int i = 0; i < m_pKeyBindList->GetItemCount(); i++)
+ {
+ KeyValues *curitem = m_pKeyBindList->GetItemData(m_pKeyBindList->GetItemIDFromRow(i));
+ if ( !curitem )
+ continue;
+
+ const char *curbinding = curitem->GetString( "Binding", "" );
+
+ if (!stricmp(curbinding, binding))
+ {
+ curitem->SetString( "Key", keyname );
+ m_pKeyBindList->InvalidateItem(i);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Remove all keys from list
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::ClearBindItems( void )
+{
+ for (int i = 0; i < m_pKeyBindList->GetItemCount(); i++)
+ {
+ KeyValues *item = m_pKeyBindList->GetItemData(m_pKeyBindList->GetItemIDFromRow(i));
+ if ( !item )
+ continue;
+
+ // Reset keys
+ item->SetString( "Key", "" );
+
+ m_pKeyBindList->InvalidateItem(i);
+ }
+
+ m_pKeyBindList->InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Remove all instances of the specified key from bindings
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::RemoveKeyFromBindItems( KeyValues *org_item, const char *key )
+{
+ Assert( key && key[ 0 ] );
+ if ( !key || !key[ 0 ] )
+ return;
+
+ int len = Q_strlen( key );
+ char *pszKey = new char[len + 1];
+
+ if ( !pszKey )
+ return;
+
+ Q_memcpy( pszKey, key, len+1 );
+
+ for (int i = 0; i < m_pKeyBindList->GetItemCount(); i++)
+ {
+ KeyValues *item = m_pKeyBindList->GetItemData(m_pKeyBindList->GetItemIDFromRow(i));
+ if ( !item )
+ continue;
+
+ // If it's bound to the primary: then remove it
+ if ( !stricmp( pszKey, item->GetString( "Key", "" ) ) )
+ {
+ bool bClearEntry = true;
+
+ if ( org_item )
+ {
+ // Only clear it out if the actual binding isn't the same. This allows
+ // us to have the same key bound to multiple entries in the keybinding list
+ // if they point to the same command.
+ const char *org_binding = org_item->GetString( "Binding", "" );
+ const char *binding = item->GetString( "Binding", "" );
+ if ( !stricmp( org_binding, binding ) )
+ {
+ bClearEntry = false;
+ }
+ }
+
+ if ( bClearEntry )
+ {
+ item->SetString( "Key", "" );
+ m_pKeyBindList->InvalidateItem(i);
+ }
+ }
+ }
+
+ delete [] pszKey;
+
+ // Make sure the display is up to date
+ m_pKeyBindList->InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Ask the engine for all bindings and set up the list
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::FillInCurrentBindings( void )
+{
+ // reset the unbind list
+ // we only unbind keys used by the normal config items (not custom binds)
+ m_KeysToUnbind.RemoveAll();
+
+ // Clear any current settings
+ ClearBindItems();
+
+ bool bJoystick = false;
+ ConVarRef var( "joystick" );
+ if ( var.IsValid() )
+ {
+ bJoystick = var.GetBool();
+ }
+
+ // NVNT see if we have a falcon connected.
+ bool bFalcon = false;
+ ConVarRef falconVar("hap_HasDevice");
+ if ( var.IsValid() )
+ {
+ bFalcon = var.GetBool();
+ }
+
+ for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
+ {
+ // Look up binding
+ const char *binding = gameuifuncs->GetBindingForButtonCode( (ButtonCode_t)i );
+ if ( !binding )
+ continue;
+
+ // See if there is an item for this one?
+ KeyValues *item = GetItemForBinding( binding );
+ if ( item )
+ {
+ // Bind it by name
+ const char *keyName = g_pInputSystem->ButtonCodeToString( (ButtonCode_t)i );
+
+ // Already in list, means user had two keys bound to this item. We'll only note the first one we encounter
+ char const *currentKey = item->GetString( "Key", "" );
+ if ( currentKey && currentKey[ 0 ] )
+ {
+ ButtonCode_t currentBC = (ButtonCode_t)gameuifuncs->GetButtonCodeForBind( currentKey );
+
+ // If we're using a joystick, joystick bindings override keyboard ones
+ bool bShouldOverride = bJoystick && IsJoystickCode((ButtonCode_t)i) && !IsJoystickCode(currentBC);
+ // NVNT If we're not using a joystick, falcon bindings override keyboard ones
+ if( !bShouldOverride && bFalcon && IsNovintCode((ButtonCode_t)i) && !IsNovintCode(currentBC) )
+ bShouldOverride = true;
+
+ if ( !bShouldOverride )
+ continue;
+
+ // Remove the key we're about to override from the unbinding list
+ m_KeysToUnbind.FindAndRemove( currentKey );
+ }
+
+ AddBinding( item, keyName );
+
+ // remember to apply unbinding of this key when we apply
+ m_KeysToUnbind.AddToTail( keyName );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Clean up memory used by saved bindings
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::DeleteSavedBindings( void )
+{
+ for ( int i = 0; i < BUTTON_CODE_LAST; i++ )
+ {
+ if ( m_Bindings[ i ].binding )
+ {
+ delete[] m_Bindings[ i ].binding;
+ m_Bindings[ i ].binding = NULL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Copy all bindings into save array
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::SaveCurrentBindings( void )
+{
+ DeleteSavedBindings();
+ for (int i = 0; i < BUTTON_CODE_LAST; i++)
+ {
+ const char *binding = gameuifuncs->GetBindingForButtonCode( (ButtonCode_t)i );
+ if ( !binding || !binding[0])
+ continue;
+
+ // Copy the binding string
+ m_Bindings[ i ].binding = UTIL_CopyString( binding );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Tells the engine to bind a key
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::BindKey( const char *key, const char *binding )
+{
+#ifndef _XBOX
+ engine->ClientCmd_Unrestricted( UTIL_va( "bind \"%s\" \"%s\"\n", key, binding ) );
+#else
+ char buff[256];
+ Q_snprintf(buff, sizeof(buff), "bind \"%s\" \"%s\"\n", key, binding);
+ engine->ClientCmd_Unrestricted(buff);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Tells the engine to unbind a key
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::UnbindKey( const char *key )
+{
+#ifndef _XBOX
+ engine->ClientCmd_Unrestricted( UTIL_va( "unbind \"%s\"\n", key ) );
+#else
+ char buff[256];
+ Q_snprintf(buff, sizeof(buff), "unbind \"%s\"\n", key);
+ engine->ClientCmd_Unrestricted(buff);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Go through list and bind specified keys to actions
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::ApplyAllBindings( void )
+{
+ // unbind everything that the user unbound
+ {for (int i = 0; i < m_KeysToUnbind.Count(); i++)
+ {
+ UnbindKey(m_KeysToUnbind[i].String());
+ }}
+ m_KeysToUnbind.RemoveAll();
+
+ // free binding memory
+ DeleteSavedBindings();
+
+ for (int i = 0; i < m_pKeyBindList->GetItemCount(); i++)
+ {
+ KeyValues *item = m_pKeyBindList->GetItemData(m_pKeyBindList->GetItemIDFromRow(i));
+ if ( !item )
+ continue;
+
+ // See if it has a binding
+ const char *binding = item->GetString( "Binding", "" );
+ if ( !binding || !binding[ 0 ] )
+ continue;
+
+ const char *keyname;
+
+ // Check main binding
+ keyname = item->GetString( "Key", "" );
+ if ( keyname && keyname[ 0 ] )
+ {
+ // Tell the engine
+ BindKey( keyname, binding );
+ ButtonCode_t code = g_pInputSystem->StringToButtonCode( keyname );
+ if ( code != BUTTON_CODE_INVALID )
+ {
+ m_Bindings[ code ].binding = UTIL_CopyString( binding );
+ }
+ }
+ }
+
+ // Now exec their custom bindings
+ engine->ClientCmd_Unrestricted( "exec userconfig.cfg\nhost_writeconfig\n" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Read in defaults from game's default config file and populate list
+// using those defaults
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::FillInDefaultBindings( void )
+{
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+ if ( !g_pFullFileSystem->ReadFile( "cfg/config_default.cfg", NULL, buf ) )
+ return;
+
+ // Clear out all current bindings
+ ClearBindItems();
+
+ const char *data = (const char*)buf.Base();
+
+ // loop through all the binding
+ while ( data != NULL )
+ {
+ char cmd[64];
+ data = UTIL_Parse( data, cmd, sizeof(cmd) );
+ if ( strlen( cmd ) <= 0 )
+ break;
+
+ if ( !stricmp(cmd, "bind") )
+ {
+ // Key name
+ char szKeyName[256];
+ data = UTIL_Parse( data, szKeyName, sizeof(szKeyName) );
+ if ( strlen( szKeyName ) <= 0 )
+ break; // Error
+
+ char szBinding[256];
+ data = UTIL_Parse( data, szBinding, sizeof(szBinding) );
+ if ( strlen( szKeyName ) <= 0 )
+ break; // Error
+
+ // Find item
+ KeyValues *item = GetItemForBinding( szBinding );
+ if ( item )
+ {
+ // Bind it
+ AddBinding( item, szKeyName );
+ }
+ }
+ }
+
+ PostActionSignal(new KeyValues("ApplyButtonEnable"));
+
+ // Make sure console and escape key are always valid
+ KeyValues *item = GetItemForBinding( "toggleconsole" );
+ if (item)
+ {
+ // Bind it
+ AddBinding( item, "`" );
+ }
+ item = GetItemForBinding( "cancelselect" );
+ if (item)
+ {
+ // Bind it
+ AddBinding( item, "ESCAPE" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: User clicked on item: remember where last active row/column was
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::ItemSelected(int itemID)
+{
+ m_pKeyBindList->SetItemOfInterest(itemID);
+
+ if (m_pKeyBindList->IsItemIDValid(itemID))
+ {
+ // find the details, see if we should be enabled/clear/whatever
+ m_pSetBindingButton->SetEnabled(true);
+
+ KeyValues *kv = m_pKeyBindList->GetItemData(itemID);
+ if (kv)
+ {
+ const char *key = kv->GetString("Key", NULL);
+ if (key && *key)
+ {
+ m_pClearBindingButton->SetEnabled(true);
+ }
+ else
+ {
+ m_pClearBindingButton->SetEnabled(false);
+ }
+
+ if (kv->GetInt("Header"))
+ {
+ m_pSetBindingButton->SetEnabled(false);
+ }
+ }
+ }
+ else
+ {
+ m_pSetBindingButton->SetEnabled(false);
+ m_pClearBindingButton->SetEnabled(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the capture has finished
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::Finish( ButtonCode_t code )
+{
+ int r = m_pKeyBindList->GetItemOfInterest();
+
+ // Retrieve clicked row and column
+ m_pKeyBindList->EndCaptureMode( dc_arrow );
+
+ // Find item for this row
+ KeyValues *item = m_pKeyBindList->GetItemData(r);
+ if ( item )
+ {
+ // Handle keys: but never rebind the escape key
+ // Esc just exits bind mode silently
+ if ( code != BUTTON_CODE_NONE && code != KEY_ESCAPE && code != BUTTON_CODE_INVALID )
+ {
+ // Bind the named key
+ AddBinding( item, g_pInputSystem->ButtonCodeToString( code ) );
+ PostActionSignal( new KeyValues( "ApplyButtonEnable" ) );
+ }
+
+ m_pKeyBindList->InvalidateItem(r);
+ }
+
+ m_pSetBindingButton->SetEnabled(true);
+ m_pClearBindingButton->SetEnabled(true);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Scans for captured key presses
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnThink()
+{
+ BaseClass::OnThink();
+
+ if ( m_pKeyBindList->IsCapturing() )
+ {
+ ButtonCode_t code = BUTTON_CODE_INVALID;
+ if ( engine->CheckDoneKeyTrapping( code ) )
+ {
+ Finish( code );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Check for enter key and go into keybinding mode if it was pressed
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OnKeyCodePressed(vgui::KeyCode code)
+{
+ // Enter key pressed and not already trapping next key/button press
+ if ( !m_pKeyBindList->IsCapturing() )
+ {
+ // Grab which item was set as interesting
+ int r = m_pKeyBindList->GetItemOfInterest();
+
+ // Check that it's visible
+ int x, y, w, h;
+ bool visible = m_pKeyBindList->GetCellBounds(r, 1, x, y, w, h);
+ if (visible)
+ {
+ if ( KEY_DELETE == code )
+ {
+ // find the current binding and remove it
+ KeyValues *kv = m_pKeyBindList->GetItemData(r);
+
+ const char *key = kv->GetString("Key", NULL);
+ if (key && *key)
+ {
+ RemoveKeyFromBindItems(NULL, key);
+ }
+
+ m_pClearBindingButton->SetEnabled(false);
+ m_pKeyBindList->InvalidateItem(r);
+ PostActionSignal(new KeyValues("ApplyButtonEnable"));
+
+ // message handled, don't pass on
+ return;
+ }
+ }
+ }
+
+ // Allow base class to process message instead
+ BaseClass::OnKeyCodePressed( code );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: advanced keyboard settings dialog
+//-----------------------------------------------------------------------------
+class COptionsSubKeyboardAdvancedDlg : public vgui::Frame
+{
+ DECLARE_CLASS_SIMPLE( COptionsSubKeyboardAdvancedDlg, vgui::Frame );
+public:
+ COptionsSubKeyboardAdvancedDlg( vgui::VPANEL hParent ) : BaseClass( NULL, NULL )
+ {
+ // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below)
+
+ SetTitle("#GameUI_KeyboardAdvanced_Title", true);
+ SetSize( 280, 140 );
+ LoadControlSettings( "resource/OptionsSubKeyboardAdvancedDlg.res" );
+ MoveToCenterOfScreen();
+ SetSizeable( false );
+ SetDeleteSelfOnClose( true );
+ }
+
+ virtual void Activate()
+ {
+ BaseClass::Activate();
+
+ input()->SetAppModalSurface(GetVPanel());
+
+ // reset the data
+ ConVarRef con_enable( "con_enable" );
+ if ( con_enable.IsValid() )
+ {
+ SetControlInt("ConsoleCheck", con_enable.GetInt() ? 1 : 0);
+ }
+
+ ConVarRef hud_fastswitch( "hud_fastswitch" );
+ if ( hud_fastswitch.IsValid() )
+ {
+ SetControlInt("FastSwitchCheck", hud_fastswitch.GetInt() ? 1 : 0);
+ }
+ }
+
+ virtual void OnApplyData()
+ {
+ // apply data
+ ConVarRef con_enable( "con_enable" );
+ con_enable.SetValue( GetControlInt( "ConsoleCheck", 0 ) );
+
+ ConVarRef hud_fastswitch( "hud_fastswitch" );
+ hud_fastswitch.SetValue( GetControlInt( "FastSwitchCheck", 0 ) );
+ }
+
+ virtual void OnCommand( const char *command )
+ {
+ if ( !stricmp(command, "OK") )
+ {
+ // apply the data
+ OnApplyData();
+ Close();
+ }
+ else
+ {
+ BaseClass::OnCommand( command );
+ }
+ }
+
+ void OnKeyCodeTyped(KeyCode code)
+ {
+ // force ourselves to be closed if the escape key it pressed
+ if (code == KEY_ESCAPE)
+ {
+ Close();
+ }
+ else
+ {
+ BaseClass::OnKeyCodeTyped(code);
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Open advanced keyboard options
+//-----------------------------------------------------------------------------
+void COptionsSubKeyboard::OpenKeyboardAdvancedDialog()
+{
+ if (!m_OptionsSubKeyboardAdvancedDlg.Get())
+ {
+ m_OptionsSubKeyboardAdvancedDlg = new COptionsSubKeyboardAdvancedDlg(GetVParent());
+ }
+ m_OptionsSubKeyboardAdvancedDlg->Activate();
+}