aboutsummaryrefslogtreecommitdiff
path: root/sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp')
-rw-r--r--sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp1698
1 files changed, 849 insertions, 849 deletions
diff --git a/sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp b/sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp
index 437f536a..c177ffaf 100644
--- a/sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp
+++ b/sp/src/vgui2/vgui_controls/KeyBoardEditorDialog.cpp
@@ -1,849 +1,849 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "vgui_controls/KeyBoardEditorDialog.h"
-#include "vgui_controls/ListPanel.h"
-#include "vgui_controls/Button.h"
-#include "vgui_controls/TextEntry.h"
-#include "vgui/ISurface.h"
-#include "vgui/IInput.h"
-#include "vgui/IVGui.h"
-#include "vgui/ILocalize.h"
-#include "KeyValues.h"
-#include "vgui/Cursor.h"
-#include "tier1/utldict.h"
-
-// NOTE: This has to be the last file included!
-#include "tier0/memdbgon.h"
-
-
-using namespace vgui;
-
-static char *CopyString( const char *in )
-{
- if ( !in )
- return NULL;
-
- int len = strlen( in );
- char *n = new char[ len + 1 ];
- Q_strncpy( n, in, len + 1 );
- return n;
-}
-
-CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t() : map( 0 )
-{
-}
-
-CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t( const SaveMapping_t& src )
-{
- map = src.map;
- current = src.current;
- original = src.original;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Special list subclass to handle drawing of trap mode prompt on top of
-// lists client area
-//-----------------------------------------------------------------------------
-class VControlsListPanel : public ListPanel
-{
- DECLARE_CLASS_SIMPLE( VControlsListPanel, ListPanel );
-
-public:
- // Construction
- VControlsListPanel( vgui::Panel *parent, const char *listName );
- virtual ~VControlsListPanel();
-
- // Start/end capturing
- virtual void StartCaptureMode(vgui::HCursor hCursor = NULL);
- virtual void EndCaptureMode(vgui::HCursor hCursor = NULL);
- virtual bool IsCapturing();
-
- // Set which item should be associated with the prompt
- virtual void SetItemOfInterest(int itemID);
- virtual int GetItemOfInterest();
-
- virtual void OnMousePressed(vgui::MouseCode code);
- virtual void OnMouseDoublePressed(vgui::MouseCode code);
-
- KEYBINDING_FUNC( clearbinding, KEY_DELETE, 0, OnClearBinding, 0, 0 );
-
-private:
- void ApplySchemeSettings(vgui::IScheme *pScheme );
-
- // Are we showing the prompt?
- bool m_bCaptureMode;
- // If so, where?
- int m_nClickRow;
- // Font to use for showing the prompt
- vgui::HFont m_hFont;
- // panel used to edit
- class CInlineEditPanel *m_pInlineEditPanel;
- int m_iMouseX, m_iMouseY;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: panel used for inline editing of key bindings
-//-----------------------------------------------------------------------------
-class CInlineEditPanel : public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CInlineEditPanel, vgui::Panel );
-
-public:
- CInlineEditPanel() : vgui::Panel(NULL, "InlineEditPanel")
- {
- }
-
- virtual void Paint()
- {
- int wide, tall;
- GetSize(wide, tall);
-
- // Draw a white rectangle around that cell
- vgui::surface()->DrawSetColor( 63, 63, 63, 255 );
- vgui::surface()->DrawFilledRect( 0, 0, wide, tall );
-
- vgui::surface()->DrawSetColor( 0, 255, 0, 255 );
- vgui::surface()->DrawOutlinedRect( 0, 0, wide, tall );
- }
-
- virtual void OnKeyCodeTyped(KeyCode code)
- {
- // forward up
- if (GetParent())
- {
- GetParent()->OnKeyCodeTyped(code);
- }
- }
-
- virtual void ApplySchemeSettings(IScheme *pScheme)
- {
- Panel::ApplySchemeSettings(pScheme);
- SetBorder(pScheme->GetBorder("DepressedButtonBorder"));
- }
-
- void OnMousePressed(vgui::MouseCode code)
- {
- // forward up mouse pressed messages to be handled by the key options
- if (GetParent())
- {
- GetParent()->OnMousePressed(code);
- }
- }
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: Construction
-//-----------------------------------------------------------------------------
-VControlsListPanel::VControlsListPanel( vgui::Panel *parent, const char *listName ) : BaseClass( parent, listName )
-{
- m_bCaptureMode = false;
- m_nClickRow = 0;
- m_pInlineEditPanel = new CInlineEditPanel();
- m_hFont = INVALID_FONT;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-VControlsListPanel::~VControlsListPanel()
-{
- m_pInlineEditPanel->MarkForDeletion();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void VControlsListPanel::ApplySchemeSettings(IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
- m_hFont = pScheme->GetFont("DefaultVerySmall", IsProportional() );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Start capture prompt display
-//-----------------------------------------------------------------------------
-void VControlsListPanel::StartCaptureMode( HCursor hCursor )
-{
- m_bCaptureMode = true;
- EnterEditMode(m_nClickRow, 1, m_pInlineEditPanel);
- input()->SetMouseFocus(m_pInlineEditPanel->GetVPanel());
- input()->SetMouseCapture(m_pInlineEditPanel->GetVPanel());
-
- if (hCursor)
- {
- m_pInlineEditPanel->SetCursor(hCursor);
-
- // save off the cursor position so we can restore it
- vgui::input()->GetCursorPos( m_iMouseX, m_iMouseY );
- }
-}
-
-void VControlsListPanel::OnClearBinding()
-{
- if ( m_bCaptureMode )
- return;
-
- if ( GetItemOfInterest() < 0 )
- return;
-
- PostMessage( GetParent()->GetVPanel(), new KeyValues( "ClearBinding", "item", GetItemOfInterest() ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Finish capture prompt display
-//-----------------------------------------------------------------------------
-void VControlsListPanel::EndCaptureMode( HCursor hCursor )
-{
- m_bCaptureMode = false;
- input()->SetMouseCapture(NULL);
- LeaveEditMode();
- RequestFocus();
- input()->SetMouseFocus(GetVPanel());
- if (hCursor)
- {
- m_pInlineEditPanel->SetCursor(hCursor);
- surface()->SetCursor(hCursor);
- if ( hCursor != dc_none )
- {
- vgui::input()->SetCursorPos ( m_iMouseX, m_iMouseY );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Set active row column
-//-----------------------------------------------------------------------------
-void VControlsListPanel::SetItemOfInterest(int itemID)
-{
- m_nClickRow = itemID;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Retrieve row, column of interest
-//-----------------------------------------------------------------------------
-int VControlsListPanel::GetItemOfInterest()
-{
- return m_nClickRow;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: returns true if we're currently waiting to capture a key
-//-----------------------------------------------------------------------------
-bool VControlsListPanel::IsCapturing( void )
-{
- return m_bCaptureMode;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Forwards mouse pressed message up to keyboard page when in capture
-//-----------------------------------------------------------------------------
-void VControlsListPanel::OnMousePressed(vgui::MouseCode code)
-{
- if (IsCapturing())
- {
- // forward up mouse pressed messages to be handled by the key options
- if (GetParent())
- {
- GetParent()->OnMousePressed(code);
- }
- }
- else
- {
- BaseClass::OnMousePressed(code);
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: input handler
-//-----------------------------------------------------------------------------
-void VControlsListPanel::OnMouseDoublePressed( vgui::MouseCode code )
-{
- int c = GetSelectedItemsCount();
- if ( c > 0 )
- {
- // enter capture mode
- OnKeyCodeTyped(KEY_ENTER);
- }
- else
- {
- BaseClass::OnMouseDoublePressed(code);
- }
-}
-
-CKeyBoardEditorPage::CKeyBoardEditorPage( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
- : BaseClass( parent, "KeyBoardEditorPage" ),
- m_pPanel( panelToEdit ),
- m_Handle( handle )
-{
- Assert( m_pPanel );
-
- m_pList = new VControlsListPanel( this, "KeyBindings" );
- m_pList->SetIgnoreDoubleClick( true );
- m_pList->AddColumnHeader(0, "Action", "#KBEditorBindingName", 175, 0);
- m_pList->AddColumnHeader(1, "Binding", "#KBEditorBinding", 175, 0);
- m_pList->AddColumnHeader(2, "Description", "#KBEditorDescription", 300, 0);
-
- LoadControlSettings( "resource/KeyBoardEditorPage.res" );
-
- SaveMappings();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-CKeyBoardEditorPage::~CKeyBoardEditorPage()
-{
- int c = m_Save.Count();
- for ( int i = 0 ; i < c; ++i )
- {
- delete m_Save[ i ];
- }
- m_Save.RemoveAll();
-}
-
-void CKeyBoardEditorPage::ApplySchemeSettings( IScheme *scheme )
-{
- BaseClass::ApplySchemeSettings( scheme );
- PopulateList();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void CKeyBoardEditorPage::SaveMappings()
-{
- Assert( m_Save.Count() == 0 );
-
- CUtlVector< PanelKeyBindingMap * > maps;
- GetMappingList( m_pPanel, maps );
-
- // add header item
- int c = maps.Count();
- for ( int i = 0; i < c; ++i )
- {
- PanelKeyBindingMap *m = maps[ i ];
- SaveMapping_t *sm = new SaveMapping_t;
- sm->map = m;
- sm->current = m->boundkeys;
- sm->original = m->boundkeys;
- m_Save.AddToTail( sm );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void CKeyBoardEditorPage::UpdateCurrentMappings()
-{
- int c = m_Save.Count();
- for ( int i = 0 ; i < c; ++i )
- {
- PanelKeyBindingMap *m = m_Save[ i ]->map;
- Assert( m );
- m_Save[ i ]->current = m->boundkeys;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-//-----------------------------------------------------------------------------
-void CKeyBoardEditorPage::RestoreMappings()
-{
- int c = m_Save.Count();
- for ( int i = 0; i < c; ++i )
- {
- SaveMapping_t *sm = m_Save[ i ];
- sm->current = sm->original;
- }
-}
-
-void CKeyBoardEditorPage::ApplyMappings()
-{
- int c = m_Save.Count();
- for ( int i = 0; i < c; ++i )
- {
- SaveMapping_t *sm = m_Save[ i ];
- sm->map->boundkeys = sm->current;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: User clicked on item: remember where last active row/column was
-//-----------------------------------------------------------------------------
-void CKeyBoardEditorPage::ItemSelected()
-{
- int c = m_pList->GetSelectedItemsCount();
- if ( c > 0 )
- {
- m_pList->SetItemOfInterest( m_pList->GetSelectedItem( 0 ) );
- }
-}
-
-void CKeyBoardEditorPage::BindKey( KeyCode code )
-{
- bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
- bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
- bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
-
- int modifiers = 0;
- if ( shift )
- {
- modifiers |= MODIFIER_SHIFT;
- }
- if ( ctrl )
- {
- modifiers |= MODIFIER_CONTROL;
- }
- if ( alt )
- {
- modifiers |= MODIFIER_ALT;
- }
-
- int r = m_pList->GetItemOfInterest();
-
- // Retrieve clicked row and column
- m_pList->EndCaptureMode(dc_arrow);
-
- // Find item for this row
- KeyValues *item = m_pList->GetItem(r);
- if ( item )
- {
- BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( item->GetPtr( "Item", 0 ) );
- if ( kbMap )
- {
- KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
- if ( binding && Q_stricmp( kbMap->bindingname, binding->bindingname ) )
- {
- // Key is already rebound!!!
- Warning( "Can't bind to '%S', key is already bound to '%s'\n",
- Panel::KeyCodeToDisplayString( code ), binding->bindingname );
- return;
- }
-
- kbMap->keycode = code;
- kbMap->modifiers = modifiers;
-
- PopulateList();
- }
-
- KeyBindingMap_t *bindingMap = reinterpret_cast< KeyBindingMap_t * >( item->GetPtr( "Unbound", 0 ) );
- if ( bindingMap )
- {
- KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
- if ( binding && Q_stricmp( bindingMap->bindingname, binding->bindingname ) )
- {
- // Key is already rebound!!!
- Warning( "Can't bind to '%S', key is already bound to '%s'\n",
- Panel::KeyCodeToDisplayString( code ), binding->bindingname );
- return;
- }
-
- // Need to add to current entries
- m_pPanel->AddKeyBinding( bindingMap->bindingname, code, modifiers );
- UpdateCurrentMappings();
- PopulateList();
- }
- }
-}
-
-void CKeyBoardEditorPage::OnPageHide()
-{
- if ( m_pList->IsCapturing() )
- {
- // Cancel capturing
- m_pList->EndCaptureMode(dc_arrow);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: binds double-clicking or hitting enter in the keybind list to changing the key
-//-----------------------------------------------------------------------------
-void CKeyBoardEditorPage::OnKeyCodeTyped(vgui::KeyCode code)
-{
- switch ( code )
- {
- case KEY_ENTER:
- {
- if ( !m_pList->IsCapturing() )
- {
- OnCommand( "ChangeKey" );
- }
- else
- {
- BindKey( code );
- }
- }
- break;
- case KEY_LSHIFT:
- case KEY_RSHIFT:
- case KEY_LALT:
- case KEY_RALT:
- case KEY_LCONTROL:
- case KEY_RCONTROL:
- {
- // Swallow these
- break;
- }
- break;
- default:
- {
- if ( m_pList->IsCapturing() )
- {
- BindKey( code );
- }
- else
- {
- BaseClass::OnKeyCodeTyped(code);
- }
- }
- }
-}
-
-void CKeyBoardEditorPage::OnCommand( char const *cmd )
-{
- if ( !m_pList->IsCapturing() && !Q_stricmp( cmd, "ChangeKey" ) )
- {
- m_pList->StartCaptureMode(dc_blank);
- }
- else
- {
- BaseClass::OnCommand( cmd );
- }
-}
-
-void CKeyBoardEditorPage::OnSaveChanges()
-{
- ApplyMappings();
-}
-
-void CKeyBoardEditorPage::OnRevert()
-{
- RestoreMappings();
- PopulateList();
-}
-
-void CKeyBoardEditorPage::OnUseDefaults()
-{
- m_pPanel->RevertKeyBindingsToDefault();
- UpdateCurrentMappings();
- PopulateList();
-}
-
-void CKeyBoardEditorPage::GetMappingList( Panel *panel, CUtlVector< PanelKeyBindingMap * >& maps )
-{
- PanelKeyBindingMap *map = panel->GetKBMap();
- while ( map )
- {
- maps.AddToTail( map );
- map = map->baseMap;
- }
-}
-
-static bool BindingLessFunc( KeyValues * const & lhs, KeyValues * const &rhs )
-{
- KeyValues *p1, *p2;
-
- p1 = const_cast< KeyValues * >( lhs );
- p2 = const_cast< KeyValues * >( rhs );
- return ( Q_stricmp( p1->GetString( "Action" ), p2->GetString( "Action" ) ) < 0 ) ? true : false;
-}
-
-void CKeyBoardEditorPage::AnsiText( char const *token, char *out, size_t buflen )
-{
- out[ 0 ] = 0;
-
- wchar_t *str = g_pVGuiLocalize->Find( token );
- if ( !str )
- {
- Q_strncpy( out, token, buflen );
- }
- else
- {
- g_pVGuiLocalize->ConvertUnicodeToANSI( str, out, buflen );
- }
-}
-
-void CKeyBoardEditorPage::PopulateList()
-{
- m_pList->DeleteAllItems();
-
- int i, j;
-
- CUtlRBTree< KeyValues *, int > sorted( 0, 0, BindingLessFunc );
-
- // add header item
- int c = m_Save.Count();
- for ( i = 0; i < c; ++i )
- {
- SaveMapping_t* sm = m_Save[ i ];
-
- PanelKeyBindingMap *m = sm->map;
- Assert( m );
-
- int bindings = sm->current.Count();
- for ( j = 0; j < bindings; ++j )
- {
- BoundKey_t *kbMap = &sm->current[ j ];
- Assert( kbMap );
-
- // Create a new: blank item
- KeyValues *item = new KeyValues( "Item" );
-
- // Fill in data
- char loc[ 128 ];
- Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
-
- char ansi[ 256 ];
- AnsiText( loc, ansi, sizeof( ansi ) );
-
- item->SetString( "Action", ansi );
- item->SetWString( "Binding", Panel::KeyCodeModifiersToDisplayString( (KeyCode)kbMap->keycode, kbMap->modifiers ) );
-
- // Find the binding
- KeyBindingMap_t *bindingMap = m_pPanel->LookupBinding( kbMap->bindingname );
- if ( bindingMap &&
- bindingMap->helpstring )
- {
- AnsiText( bindingMap->helpstring, ansi, sizeof( ansi ) );
- item->SetString( "Description", ansi);
- }
-
- item->SetPtr( "Item", kbMap );
-
- sorted.Insert( item );
- }
-
- // Now try and find any "unbound" keys...
- int mappings = m->entries.Count();
- for ( j = 0; j < mappings; ++j )
- {
- KeyBindingMap_t *kbMap = &m->entries[ j ];
-
- // See if it's bound
- CUtlVector< BoundKey_t * > list;
- m_pPanel->LookupBoundKeys( kbMap->bindingname, list );
- if ( list.Count() > 0 )
- continue;
-
- // Not bound, add a placeholder entry
- // Create a new: blank item
- KeyValues *item = new KeyValues( "Item" );
-
- // fill in data
- char loc[ 128 ];
- Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
-
- char ansi[ 256 ];
- AnsiText( loc, ansi, sizeof( ansi ) );
-
- item->SetString( "Action", ansi );
- item->SetWString( "Binding", L"" );
- if ( kbMap->helpstring )
- {
- AnsiText( kbMap->helpstring, ansi, sizeof( ansi ) );
- item->SetString( "Description", ansi );
- }
-
- item->SetPtr( "Unbound", kbMap );
-
- sorted.Insert( item );
- }
- }
-
- for ( j = sorted.FirstInorder() ; j != sorted.InvalidIndex(); j = sorted.NextInorder( j ) )
- {
- KeyValues *item = sorted[ j ];
-
- // Add to list
- m_pList->AddItem( item, 0, false, false );
-
- item->deleteThis();
- }
-
- sorted.RemoveAll();
-}
-
-void CKeyBoardEditorPage::OnClearBinding( int item )
-{
- // Find item for this row
- KeyValues *kv = m_pList->GetItem(item );
- if ( !kv )
- {
- return;
- }
-
- BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( kv->GetPtr( "Item", 0 ) );
- if ( !kbMap )
- {
- return;
- }
-
- kbMap->keycode = KEY_NONE;
- kbMap->modifiers = 0;
-
- PopulateList();
-}
-
-CKeyBoardEditorSheet::CKeyBoardEditorSheet( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
- : BaseClass( parent, "KeyBoardEditorSheet" ),
- m_bSaveToExternalFile( false ),
- m_Handle( handle ),
- m_SaveFileName( UTL_INVAL_SYMBOL ),
- m_SaveFilePathID( UTL_INVAL_SYMBOL )
-{
- m_hPanel = panelToEdit;
-
- SetSmallTabs( true );
-
- // Create this sheet and add the subcontrols
- CKeyBoardEditorPage *active = NULL;
-
- int subCount = Panel::GetPanelsWithKeyBindingsCount( handle );
- for ( int i = 0; i < subCount; ++i )
- {
- Panel *p = Panel::GetPanelWithKeyBindings( handle, i );
- if ( !p )
- continue;
-
- // Don't display panels with no keymappings
- if ( p->GetKeyMappingCount() == 0 )
- continue;
-
- CKeyBoardEditorPage *newPage = new CKeyBoardEditorPage( this, p, handle );
- AddPage( newPage, p->GetName() );
- if ( p == panelToEdit )
- {
- active = newPage;
- }
- }
-
- if ( active )
- {
- SetActivePage( active );
- }
-
- LoadControlSettings( "resource/KeyBoardEditorSheet.res" );
-}
-
-void CKeyBoardEditorSheet::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
-{
- Assert( filename );
- m_bSaveToExternalFile = true;
- m_SaveFileName = filename;
- if ( pathID != NULL )
- {
- m_SaveFilePathID = pathID;
- }
- else
- {
- m_SaveFilePathID = UTL_INVAL_SYMBOL;
- }
-}
-
-void CKeyBoardEditorSheet::OnSaveChanges()
-{
- int c = GetNumPages();
- for ( int i = 0 ; i < c; ++i )
- {
- CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
- page->OnSaveChanges();
- }
-
- if ( m_bSaveToExternalFile )
- {
- m_hPanel->SaveKeyBindingsToFile( m_Handle, m_SaveFileName.String(), m_SaveFilePathID.IsValid() ? m_SaveFilePathID.String() : NULL );
- }
- else
- {
- m_hPanel->SaveKeyBindings( m_Handle );
- }
-}
-
-void CKeyBoardEditorSheet::OnRevert()
-{
- int c = GetNumPages();
- for ( int i = 0 ; i < c; ++i )
- {
- CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
- page->OnRevert();
- }
-}
-
-void CKeyBoardEditorSheet::OnUseDefaults()
-{
- int c = GetNumPages();
- for ( int i = 0 ; i < c; ++i )
- {
- CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
- page->OnUseDefaults();
- }
-}
-
-CKeyBoardEditorDialog::CKeyBoardEditorDialog( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
- : BaseClass( parent, "KeyBoardEditorDialog" )
-{
- m_pSave = new Button( this, "Save", "#KBEditorSave", this, "save" );
- m_pCancel = new Button( this, "Cancel", "#KBEditorCancel", this, "cancel" );
- m_pRevert = new Button( this, "Revert", "#KBEditorRevert", this, "revert" );
- m_pUseDefaults = new Button( this, "Defaults", "#KBEditorUseDefaults", this, "defaults" );
-
- m_pKBEditor = new CKeyBoardEditorSheet( this, panelToEdit, handle );
-
- LoadControlSettings( "resource/KeyBoardEditorDialog.res" );
-
- SetTitle( "#KBEditorTitle", true );
-
- SetSmallCaption( true );
- SetMinimumSize( 640, 200 );
- SetMinimizeButtonVisible( false );
- SetMaximizeButtonVisible( false );
- SetSizeable( true );
- SetMoveable( true );
- SetMenuButtonVisible( false );
-
- SetVisible( true );
-
- MoveToCenterOfScreen();
-}
-
-void CKeyBoardEditorDialog::OnCommand( char const *cmd )
-{
- if ( !Q_stricmp( cmd, "save" ) )
- {
- m_pKBEditor->OnSaveChanges();
- MarkForDeletion();
- }
- else if ( !Q_stricmp( cmd, "cancel" ) ||
- !Q_stricmp( cmd, "Close" ) )
- {
- m_pKBEditor->OnRevert();
- MarkForDeletion();
- }
- else if ( !Q_stricmp( cmd, "revert" ) )
- {
- m_pKBEditor->OnRevert();
- }
- else if ( !Q_stricmp( cmd, "defaults" ) )
- {
- m_pKBEditor->OnUseDefaults();
- }
- else
- {
- BaseClass::OnCommand( cmd );
- }
-}
-
-void CKeyBoardEditorDialog::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
-{
- m_pKBEditor->SetKeybindingsSaveFile( filename, pathID );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "vgui_controls/KeyBoardEditorDialog.h"
+#include "vgui_controls/ListPanel.h"
+#include "vgui_controls/Button.h"
+#include "vgui_controls/TextEntry.h"
+#include "vgui/ISurface.h"
+#include "vgui/IInput.h"
+#include "vgui/IVGui.h"
+#include "vgui/ILocalize.h"
+#include "KeyValues.h"
+#include "vgui/Cursor.h"
+#include "tier1/utldict.h"
+
+// NOTE: This has to be the last file included!
+#include "tier0/memdbgon.h"
+
+
+using namespace vgui;
+
+static char *CopyString( const char *in )
+{
+ if ( !in )
+ return NULL;
+
+ int len = strlen( in );
+ char *n = new char[ len + 1 ];
+ Q_strncpy( n, in, len + 1 );
+ return n;
+}
+
+CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t() : map( 0 )
+{
+}
+
+CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t( const SaveMapping_t& src )
+{
+ map = src.map;
+ current = src.current;
+ original = src.original;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Special list subclass to handle drawing of trap mode prompt on top of
+// lists client area
+//-----------------------------------------------------------------------------
+class VControlsListPanel : public ListPanel
+{
+ DECLARE_CLASS_SIMPLE( VControlsListPanel, ListPanel );
+
+public:
+ // Construction
+ VControlsListPanel( vgui::Panel *parent, const char *listName );
+ virtual ~VControlsListPanel();
+
+ // Start/end capturing
+ virtual void StartCaptureMode(vgui::HCursor hCursor = NULL);
+ virtual void EndCaptureMode(vgui::HCursor hCursor = NULL);
+ virtual bool IsCapturing();
+
+ // Set which item should be associated with the prompt
+ virtual void SetItemOfInterest(int itemID);
+ virtual int GetItemOfInterest();
+
+ virtual void OnMousePressed(vgui::MouseCode code);
+ virtual void OnMouseDoublePressed(vgui::MouseCode code);
+
+ KEYBINDING_FUNC( clearbinding, KEY_DELETE, 0, OnClearBinding, 0, 0 );
+
+private:
+ void ApplySchemeSettings(vgui::IScheme *pScheme );
+
+ // Are we showing the prompt?
+ bool m_bCaptureMode;
+ // If so, where?
+ int m_nClickRow;
+ // Font to use for showing the prompt
+ vgui::HFont m_hFont;
+ // panel used to edit
+ class CInlineEditPanel *m_pInlineEditPanel;
+ int m_iMouseX, m_iMouseY;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: panel used for inline editing of key bindings
+//-----------------------------------------------------------------------------
+class CInlineEditPanel : public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CInlineEditPanel, vgui::Panel );
+
+public:
+ CInlineEditPanel() : vgui::Panel(NULL, "InlineEditPanel")
+ {
+ }
+
+ virtual void Paint()
+ {
+ int wide, tall;
+ GetSize(wide, tall);
+
+ // Draw a white rectangle around that cell
+ vgui::surface()->DrawSetColor( 63, 63, 63, 255 );
+ vgui::surface()->DrawFilledRect( 0, 0, wide, tall );
+
+ vgui::surface()->DrawSetColor( 0, 255, 0, 255 );
+ vgui::surface()->DrawOutlinedRect( 0, 0, wide, tall );
+ }
+
+ virtual void OnKeyCodeTyped(KeyCode code)
+ {
+ // forward up
+ if (GetParent())
+ {
+ GetParent()->OnKeyCodeTyped(code);
+ }
+ }
+
+ virtual void ApplySchemeSettings(IScheme *pScheme)
+ {
+ Panel::ApplySchemeSettings(pScheme);
+ SetBorder(pScheme->GetBorder("DepressedButtonBorder"));
+ }
+
+ void OnMousePressed(vgui::MouseCode code)
+ {
+ // forward up mouse pressed messages to be handled by the key options
+ if (GetParent())
+ {
+ GetParent()->OnMousePressed(code);
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Construction
+//-----------------------------------------------------------------------------
+VControlsListPanel::VControlsListPanel( vgui::Panel *parent, const char *listName ) : BaseClass( parent, listName )
+{
+ m_bCaptureMode = false;
+ m_nClickRow = 0;
+ m_pInlineEditPanel = new CInlineEditPanel();
+ m_hFont = INVALID_FONT;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+VControlsListPanel::~VControlsListPanel()
+{
+ m_pInlineEditPanel->MarkForDeletion();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VControlsListPanel::ApplySchemeSettings(IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+ m_hFont = pScheme->GetFont("DefaultVerySmall", IsProportional() );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Start capture prompt display
+//-----------------------------------------------------------------------------
+void VControlsListPanel::StartCaptureMode( HCursor hCursor )
+{
+ m_bCaptureMode = true;
+ EnterEditMode(m_nClickRow, 1, m_pInlineEditPanel);
+ input()->SetMouseFocus(m_pInlineEditPanel->GetVPanel());
+ input()->SetMouseCapture(m_pInlineEditPanel->GetVPanel());
+
+ if (hCursor)
+ {
+ m_pInlineEditPanel->SetCursor(hCursor);
+
+ // save off the cursor position so we can restore it
+ vgui::input()->GetCursorPos( m_iMouseX, m_iMouseY );
+ }
+}
+
+void VControlsListPanel::OnClearBinding()
+{
+ if ( m_bCaptureMode )
+ return;
+
+ if ( GetItemOfInterest() < 0 )
+ return;
+
+ PostMessage( GetParent()->GetVPanel(), new KeyValues( "ClearBinding", "item", GetItemOfInterest() ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Finish capture prompt display
+//-----------------------------------------------------------------------------
+void VControlsListPanel::EndCaptureMode( HCursor hCursor )
+{
+ m_bCaptureMode = false;
+ input()->SetMouseCapture(NULL);
+ LeaveEditMode();
+ RequestFocus();
+ input()->SetMouseFocus(GetVPanel());
+ if (hCursor)
+ {
+ m_pInlineEditPanel->SetCursor(hCursor);
+ surface()->SetCursor(hCursor);
+ if ( hCursor != dc_none )
+ {
+ vgui::input()->SetCursorPos ( m_iMouseX, m_iMouseY );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Set active row column
+//-----------------------------------------------------------------------------
+void VControlsListPanel::SetItemOfInterest(int itemID)
+{
+ m_nClickRow = itemID;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Retrieve row, column of interest
+//-----------------------------------------------------------------------------
+int VControlsListPanel::GetItemOfInterest()
+{
+ return m_nClickRow;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if we're currently waiting to capture a key
+//-----------------------------------------------------------------------------
+bool VControlsListPanel::IsCapturing( void )
+{
+ return m_bCaptureMode;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Forwards mouse pressed message up to keyboard page when in capture
+//-----------------------------------------------------------------------------
+void VControlsListPanel::OnMousePressed(vgui::MouseCode code)
+{
+ if (IsCapturing())
+ {
+ // forward up mouse pressed messages to be handled by the key options
+ if (GetParent())
+ {
+ GetParent()->OnMousePressed(code);
+ }
+ }
+ else
+ {
+ BaseClass::OnMousePressed(code);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: input handler
+//-----------------------------------------------------------------------------
+void VControlsListPanel::OnMouseDoublePressed( vgui::MouseCode code )
+{
+ int c = GetSelectedItemsCount();
+ if ( c > 0 )
+ {
+ // enter capture mode
+ OnKeyCodeTyped(KEY_ENTER);
+ }
+ else
+ {
+ BaseClass::OnMouseDoublePressed(code);
+ }
+}
+
+CKeyBoardEditorPage::CKeyBoardEditorPage( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
+ : BaseClass( parent, "KeyBoardEditorPage" ),
+ m_pPanel( panelToEdit ),
+ m_Handle( handle )
+{
+ Assert( m_pPanel );
+
+ m_pList = new VControlsListPanel( this, "KeyBindings" );
+ m_pList->SetIgnoreDoubleClick( true );
+ m_pList->AddColumnHeader(0, "Action", "#KBEditorBindingName", 175, 0);
+ m_pList->AddColumnHeader(1, "Binding", "#KBEditorBinding", 175, 0);
+ m_pList->AddColumnHeader(2, "Description", "#KBEditorDescription", 300, 0);
+
+ LoadControlSettings( "resource/KeyBoardEditorPage.res" );
+
+ SaveMappings();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+CKeyBoardEditorPage::~CKeyBoardEditorPage()
+{
+ int c = m_Save.Count();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ delete m_Save[ i ];
+ }
+ m_Save.RemoveAll();
+}
+
+void CKeyBoardEditorPage::ApplySchemeSettings( IScheme *scheme )
+{
+ BaseClass::ApplySchemeSettings( scheme );
+ PopulateList();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CKeyBoardEditorPage::SaveMappings()
+{
+ Assert( m_Save.Count() == 0 );
+
+ CUtlVector< PanelKeyBindingMap * > maps;
+ GetMappingList( m_pPanel, maps );
+
+ // add header item
+ int c = maps.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ PanelKeyBindingMap *m = maps[ i ];
+ SaveMapping_t *sm = new SaveMapping_t;
+ sm->map = m;
+ sm->current = m->boundkeys;
+ sm->original = m->boundkeys;
+ m_Save.AddToTail( sm );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CKeyBoardEditorPage::UpdateCurrentMappings()
+{
+ int c = m_Save.Count();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ PanelKeyBindingMap *m = m_Save[ i ]->map;
+ Assert( m );
+ m_Save[ i ]->current = m->boundkeys;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CKeyBoardEditorPage::RestoreMappings()
+{
+ int c = m_Save.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ SaveMapping_t *sm = m_Save[ i ];
+ sm->current = sm->original;
+ }
+}
+
+void CKeyBoardEditorPage::ApplyMappings()
+{
+ int c = m_Save.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ SaveMapping_t *sm = m_Save[ i ];
+ sm->map->boundkeys = sm->current;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: User clicked on item: remember where last active row/column was
+//-----------------------------------------------------------------------------
+void CKeyBoardEditorPage::ItemSelected()
+{
+ int c = m_pList->GetSelectedItemsCount();
+ if ( c > 0 )
+ {
+ m_pList->SetItemOfInterest( m_pList->GetSelectedItem( 0 ) );
+ }
+}
+
+void CKeyBoardEditorPage::BindKey( KeyCode code )
+{
+ bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
+ bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
+ bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
+
+ int modifiers = 0;
+ if ( shift )
+ {
+ modifiers |= MODIFIER_SHIFT;
+ }
+ if ( ctrl )
+ {
+ modifiers |= MODIFIER_CONTROL;
+ }
+ if ( alt )
+ {
+ modifiers |= MODIFIER_ALT;
+ }
+
+ int r = m_pList->GetItemOfInterest();
+
+ // Retrieve clicked row and column
+ m_pList->EndCaptureMode(dc_arrow);
+
+ // Find item for this row
+ KeyValues *item = m_pList->GetItem(r);
+ if ( item )
+ {
+ BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( item->GetPtr( "Item", 0 ) );
+ if ( kbMap )
+ {
+ KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
+ if ( binding && Q_stricmp( kbMap->bindingname, binding->bindingname ) )
+ {
+ // Key is already rebound!!!
+ Warning( "Can't bind to '%S', key is already bound to '%s'\n",
+ Panel::KeyCodeToDisplayString( code ), binding->bindingname );
+ return;
+ }
+
+ kbMap->keycode = code;
+ kbMap->modifiers = modifiers;
+
+ PopulateList();
+ }
+
+ KeyBindingMap_t *bindingMap = reinterpret_cast< KeyBindingMap_t * >( item->GetPtr( "Unbound", 0 ) );
+ if ( bindingMap )
+ {
+ KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
+ if ( binding && Q_stricmp( bindingMap->bindingname, binding->bindingname ) )
+ {
+ // Key is already rebound!!!
+ Warning( "Can't bind to '%S', key is already bound to '%s'\n",
+ Panel::KeyCodeToDisplayString( code ), binding->bindingname );
+ return;
+ }
+
+ // Need to add to current entries
+ m_pPanel->AddKeyBinding( bindingMap->bindingname, code, modifiers );
+ UpdateCurrentMappings();
+ PopulateList();
+ }
+ }
+}
+
+void CKeyBoardEditorPage::OnPageHide()
+{
+ if ( m_pList->IsCapturing() )
+ {
+ // Cancel capturing
+ m_pList->EndCaptureMode(dc_arrow);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: binds double-clicking or hitting enter in the keybind list to changing the key
+//-----------------------------------------------------------------------------
+void CKeyBoardEditorPage::OnKeyCodeTyped(vgui::KeyCode code)
+{
+ switch ( code )
+ {
+ case KEY_ENTER:
+ {
+ if ( !m_pList->IsCapturing() )
+ {
+ OnCommand( "ChangeKey" );
+ }
+ else
+ {
+ BindKey( code );
+ }
+ }
+ break;
+ case KEY_LSHIFT:
+ case KEY_RSHIFT:
+ case KEY_LALT:
+ case KEY_RALT:
+ case KEY_LCONTROL:
+ case KEY_RCONTROL:
+ {
+ // Swallow these
+ break;
+ }
+ break;
+ default:
+ {
+ if ( m_pList->IsCapturing() )
+ {
+ BindKey( code );
+ }
+ else
+ {
+ BaseClass::OnKeyCodeTyped(code);
+ }
+ }
+ }
+}
+
+void CKeyBoardEditorPage::OnCommand( char const *cmd )
+{
+ if ( !m_pList->IsCapturing() && !Q_stricmp( cmd, "ChangeKey" ) )
+ {
+ m_pList->StartCaptureMode(dc_blank);
+ }
+ else
+ {
+ BaseClass::OnCommand( cmd );
+ }
+}
+
+void CKeyBoardEditorPage::OnSaveChanges()
+{
+ ApplyMappings();
+}
+
+void CKeyBoardEditorPage::OnRevert()
+{
+ RestoreMappings();
+ PopulateList();
+}
+
+void CKeyBoardEditorPage::OnUseDefaults()
+{
+ m_pPanel->RevertKeyBindingsToDefault();
+ UpdateCurrentMappings();
+ PopulateList();
+}
+
+void CKeyBoardEditorPage::GetMappingList( Panel *panel, CUtlVector< PanelKeyBindingMap * >& maps )
+{
+ PanelKeyBindingMap *map = panel->GetKBMap();
+ while ( map )
+ {
+ maps.AddToTail( map );
+ map = map->baseMap;
+ }
+}
+
+static bool BindingLessFunc( KeyValues * const & lhs, KeyValues * const &rhs )
+{
+ KeyValues *p1, *p2;
+
+ p1 = const_cast< KeyValues * >( lhs );
+ p2 = const_cast< KeyValues * >( rhs );
+ return ( Q_stricmp( p1->GetString( "Action" ), p2->GetString( "Action" ) ) < 0 ) ? true : false;
+}
+
+void CKeyBoardEditorPage::AnsiText( char const *token, char *out, size_t buflen )
+{
+ out[ 0 ] = 0;
+
+ wchar_t *str = g_pVGuiLocalize->Find( token );
+ if ( !str )
+ {
+ Q_strncpy( out, token, buflen );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConvertUnicodeToANSI( str, out, buflen );
+ }
+}
+
+void CKeyBoardEditorPage::PopulateList()
+{
+ m_pList->DeleteAllItems();
+
+ int i, j;
+
+ CUtlRBTree< KeyValues *, int > sorted( 0, 0, BindingLessFunc );
+
+ // add header item
+ int c = m_Save.Count();
+ for ( i = 0; i < c; ++i )
+ {
+ SaveMapping_t* sm = m_Save[ i ];
+
+ PanelKeyBindingMap *m = sm->map;
+ Assert( m );
+
+ int bindings = sm->current.Count();
+ for ( j = 0; j < bindings; ++j )
+ {
+ BoundKey_t *kbMap = &sm->current[ j ];
+ Assert( kbMap );
+
+ // Create a new: blank item
+ KeyValues *item = new KeyValues( "Item" );
+
+ // Fill in data
+ char loc[ 128 ];
+ Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
+
+ char ansi[ 256 ];
+ AnsiText( loc, ansi, sizeof( ansi ) );
+
+ item->SetString( "Action", ansi );
+ item->SetWString( "Binding", Panel::KeyCodeModifiersToDisplayString( (KeyCode)kbMap->keycode, kbMap->modifiers ) );
+
+ // Find the binding
+ KeyBindingMap_t *bindingMap = m_pPanel->LookupBinding( kbMap->bindingname );
+ if ( bindingMap &&
+ bindingMap->helpstring )
+ {
+ AnsiText( bindingMap->helpstring, ansi, sizeof( ansi ) );
+ item->SetString( "Description", ansi);
+ }
+
+ item->SetPtr( "Item", kbMap );
+
+ sorted.Insert( item );
+ }
+
+ // Now try and find any "unbound" keys...
+ int mappings = m->entries.Count();
+ for ( j = 0; j < mappings; ++j )
+ {
+ KeyBindingMap_t *kbMap = &m->entries[ j ];
+
+ // See if it's bound
+ CUtlVector< BoundKey_t * > list;
+ m_pPanel->LookupBoundKeys( kbMap->bindingname, list );
+ if ( list.Count() > 0 )
+ continue;
+
+ // Not bound, add a placeholder entry
+ // Create a new: blank item
+ KeyValues *item = new KeyValues( "Item" );
+
+ // fill in data
+ char loc[ 128 ];
+ Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
+
+ char ansi[ 256 ];
+ AnsiText( loc, ansi, sizeof( ansi ) );
+
+ item->SetString( "Action", ansi );
+ item->SetWString( "Binding", L"" );
+ if ( kbMap->helpstring )
+ {
+ AnsiText( kbMap->helpstring, ansi, sizeof( ansi ) );
+ item->SetString( "Description", ansi );
+ }
+
+ item->SetPtr( "Unbound", kbMap );
+
+ sorted.Insert( item );
+ }
+ }
+
+ for ( j = sorted.FirstInorder() ; j != sorted.InvalidIndex(); j = sorted.NextInorder( j ) )
+ {
+ KeyValues *item = sorted[ j ];
+
+ // Add to list
+ m_pList->AddItem( item, 0, false, false );
+
+ item->deleteThis();
+ }
+
+ sorted.RemoveAll();
+}
+
+void CKeyBoardEditorPage::OnClearBinding( int item )
+{
+ // Find item for this row
+ KeyValues *kv = m_pList->GetItem(item );
+ if ( !kv )
+ {
+ return;
+ }
+
+ BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( kv->GetPtr( "Item", 0 ) );
+ if ( !kbMap )
+ {
+ return;
+ }
+
+ kbMap->keycode = KEY_NONE;
+ kbMap->modifiers = 0;
+
+ PopulateList();
+}
+
+CKeyBoardEditorSheet::CKeyBoardEditorSheet( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
+ : BaseClass( parent, "KeyBoardEditorSheet" ),
+ m_bSaveToExternalFile( false ),
+ m_Handle( handle ),
+ m_SaveFileName( UTL_INVAL_SYMBOL ),
+ m_SaveFilePathID( UTL_INVAL_SYMBOL )
+{
+ m_hPanel = panelToEdit;
+
+ SetSmallTabs( true );
+
+ // Create this sheet and add the subcontrols
+ CKeyBoardEditorPage *active = NULL;
+
+ int subCount = Panel::GetPanelsWithKeyBindingsCount( handle );
+ for ( int i = 0; i < subCount; ++i )
+ {
+ Panel *p = Panel::GetPanelWithKeyBindings( handle, i );
+ if ( !p )
+ continue;
+
+ // Don't display panels with no keymappings
+ if ( p->GetKeyMappingCount() == 0 )
+ continue;
+
+ CKeyBoardEditorPage *newPage = new CKeyBoardEditorPage( this, p, handle );
+ AddPage( newPage, p->GetName() );
+ if ( p == panelToEdit )
+ {
+ active = newPage;
+ }
+ }
+
+ if ( active )
+ {
+ SetActivePage( active );
+ }
+
+ LoadControlSettings( "resource/KeyBoardEditorSheet.res" );
+}
+
+void CKeyBoardEditorSheet::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
+{
+ Assert( filename );
+ m_bSaveToExternalFile = true;
+ m_SaveFileName = filename;
+ if ( pathID != NULL )
+ {
+ m_SaveFilePathID = pathID;
+ }
+ else
+ {
+ m_SaveFilePathID = UTL_INVAL_SYMBOL;
+ }
+}
+
+void CKeyBoardEditorSheet::OnSaveChanges()
+{
+ int c = GetNumPages();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
+ page->OnSaveChanges();
+ }
+
+ if ( m_bSaveToExternalFile )
+ {
+ m_hPanel->SaveKeyBindingsToFile( m_Handle, m_SaveFileName.String(), m_SaveFilePathID.IsValid() ? m_SaveFilePathID.String() : NULL );
+ }
+ else
+ {
+ m_hPanel->SaveKeyBindings( m_Handle );
+ }
+}
+
+void CKeyBoardEditorSheet::OnRevert()
+{
+ int c = GetNumPages();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
+ page->OnRevert();
+ }
+}
+
+void CKeyBoardEditorSheet::OnUseDefaults()
+{
+ int c = GetNumPages();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
+ page->OnUseDefaults();
+ }
+}
+
+CKeyBoardEditorDialog::CKeyBoardEditorDialog( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
+ : BaseClass( parent, "KeyBoardEditorDialog" )
+{
+ m_pSave = new Button( this, "Save", "#KBEditorSave", this, "save" );
+ m_pCancel = new Button( this, "Cancel", "#KBEditorCancel", this, "cancel" );
+ m_pRevert = new Button( this, "Revert", "#KBEditorRevert", this, "revert" );
+ m_pUseDefaults = new Button( this, "Defaults", "#KBEditorUseDefaults", this, "defaults" );
+
+ m_pKBEditor = new CKeyBoardEditorSheet( this, panelToEdit, handle );
+
+ LoadControlSettings( "resource/KeyBoardEditorDialog.res" );
+
+ SetTitle( "#KBEditorTitle", true );
+
+ SetSmallCaption( true );
+ SetMinimumSize( 640, 200 );
+ SetMinimizeButtonVisible( false );
+ SetMaximizeButtonVisible( false );
+ SetSizeable( true );
+ SetMoveable( true );
+ SetMenuButtonVisible( false );
+
+ SetVisible( true );
+
+ MoveToCenterOfScreen();
+}
+
+void CKeyBoardEditorDialog::OnCommand( char const *cmd )
+{
+ if ( !Q_stricmp( cmd, "save" ) )
+ {
+ m_pKBEditor->OnSaveChanges();
+ MarkForDeletion();
+ }
+ else if ( !Q_stricmp( cmd, "cancel" ) ||
+ !Q_stricmp( cmd, "Close" ) )
+ {
+ m_pKBEditor->OnRevert();
+ MarkForDeletion();
+ }
+ else if ( !Q_stricmp( cmd, "revert" ) )
+ {
+ m_pKBEditor->OnRevert();
+ }
+ else if ( !Q_stricmp( cmd, "defaults" ) )
+ {
+ m_pKBEditor->OnUseDefaults();
+ }
+ else
+ {
+ BaseClass::OnCommand( cmd );
+ }
+}
+
+void CKeyBoardEditorDialog::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
+{
+ m_pKBEditor->SetKeybindingsSaveFile( filename, pathID );
+}