Team Fortress 2 Source Code as on 22/4/2020
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.

849 lines
21 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "vgui_controls/KeyBoardEditorDialog.h"
  7. #include "vgui_controls/ListPanel.h"
  8. #include "vgui_controls/Button.h"
  9. #include "vgui_controls/TextEntry.h"
  10. #include "vgui/ISurface.h"
  11. #include "vgui/IInput.h"
  12. #include "vgui/IVGui.h"
  13. #include "vgui/ILocalize.h"
  14. #include "KeyValues.h"
  15. #include "vgui/Cursor.h"
  16. #include "tier1/utldict.h"
  17. // NOTE: This has to be the last file included!
  18. #include "tier0/memdbgon.h"
  19. using namespace vgui;
  20. static char *CopyString( const char *in )
  21. {
  22. if ( !in )
  23. return NULL;
  24. int len = strlen( in );
  25. char *n = new char[ len + 1 ];
  26. Q_strncpy( n, in, len + 1 );
  27. return n;
  28. }
  29. CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t() : map( 0 )
  30. {
  31. }
  32. CKeyBoardEditorPage::SaveMapping_t::SaveMapping_t( const SaveMapping_t& src )
  33. {
  34. map = src.map;
  35. current = src.current;
  36. original = src.original;
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Purpose: Special list subclass to handle drawing of trap mode prompt on top of
  40. // lists client area
  41. //-----------------------------------------------------------------------------
  42. class VControlsListPanel : public ListPanel
  43. {
  44. DECLARE_CLASS_SIMPLE( VControlsListPanel, ListPanel );
  45. public:
  46. // Construction
  47. VControlsListPanel( vgui::Panel *parent, const char *listName );
  48. virtual ~VControlsListPanel();
  49. // Start/end capturing
  50. virtual void StartCaptureMode(vgui::HCursor hCursor = NULL);
  51. virtual void EndCaptureMode(vgui::HCursor hCursor = NULL);
  52. virtual bool IsCapturing();
  53. // Set which item should be associated with the prompt
  54. virtual void SetItemOfInterest(int itemID);
  55. virtual int GetItemOfInterest();
  56. virtual void OnMousePressed(vgui::MouseCode code);
  57. virtual void OnMouseDoublePressed(vgui::MouseCode code);
  58. KEYBINDING_FUNC( clearbinding, KEY_DELETE, 0, OnClearBinding, 0, 0 );
  59. private:
  60. void ApplySchemeSettings(vgui::IScheme *pScheme );
  61. // Are we showing the prompt?
  62. bool m_bCaptureMode;
  63. // If so, where?
  64. int m_nClickRow;
  65. // Font to use for showing the prompt
  66. vgui::HFont m_hFont;
  67. // panel used to edit
  68. class CInlineEditPanel *m_pInlineEditPanel;
  69. int m_iMouseX, m_iMouseY;
  70. };
  71. //-----------------------------------------------------------------------------
  72. // Purpose: panel used for inline editing of key bindings
  73. //-----------------------------------------------------------------------------
  74. class CInlineEditPanel : public vgui::Panel
  75. {
  76. DECLARE_CLASS_SIMPLE( CInlineEditPanel, vgui::Panel );
  77. public:
  78. CInlineEditPanel() : vgui::Panel(NULL, "InlineEditPanel")
  79. {
  80. }
  81. virtual void Paint()
  82. {
  83. int wide, tall;
  84. GetSize(wide, tall);
  85. // Draw a white rectangle around that cell
  86. vgui::surface()->DrawSetColor( 63, 63, 63, 255 );
  87. vgui::surface()->DrawFilledRect( 0, 0, wide, tall );
  88. vgui::surface()->DrawSetColor( 0, 255, 0, 255 );
  89. vgui::surface()->DrawOutlinedRect( 0, 0, wide, tall );
  90. }
  91. virtual void OnKeyCodeTyped(KeyCode code)
  92. {
  93. // forward up
  94. if (GetParent())
  95. {
  96. GetParent()->OnKeyCodeTyped(code);
  97. }
  98. }
  99. virtual void ApplySchemeSettings(IScheme *pScheme)
  100. {
  101. Panel::ApplySchemeSettings(pScheme);
  102. SetBorder(pScheme->GetBorder("DepressedButtonBorder"));
  103. }
  104. void OnMousePressed(vgui::MouseCode code)
  105. {
  106. // forward up mouse pressed messages to be handled by the key options
  107. if (GetParent())
  108. {
  109. GetParent()->OnMousePressed(code);
  110. }
  111. }
  112. };
  113. //-----------------------------------------------------------------------------
  114. // Purpose: Construction
  115. //-----------------------------------------------------------------------------
  116. VControlsListPanel::VControlsListPanel( vgui::Panel *parent, const char *listName ) : BaseClass( parent, listName )
  117. {
  118. m_bCaptureMode = false;
  119. m_nClickRow = 0;
  120. m_pInlineEditPanel = new CInlineEditPanel();
  121. m_hFont = INVALID_FONT;
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose: Destructor
  125. //-----------------------------------------------------------------------------
  126. VControlsListPanel::~VControlsListPanel()
  127. {
  128. m_pInlineEditPanel->MarkForDeletion();
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose:
  132. //-----------------------------------------------------------------------------
  133. void VControlsListPanel::ApplySchemeSettings(IScheme *pScheme )
  134. {
  135. BaseClass::ApplySchemeSettings( pScheme );
  136. m_hFont = pScheme->GetFont("DefaultVerySmall", IsProportional() );
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Purpose: Start capture prompt display
  140. //-----------------------------------------------------------------------------
  141. void VControlsListPanel::StartCaptureMode( HCursor hCursor )
  142. {
  143. m_bCaptureMode = true;
  144. EnterEditMode(m_nClickRow, 1, m_pInlineEditPanel);
  145. input()->SetMouseFocus(m_pInlineEditPanel->GetVPanel());
  146. input()->SetMouseCapture(m_pInlineEditPanel->GetVPanel());
  147. if (hCursor)
  148. {
  149. m_pInlineEditPanel->SetCursor(hCursor);
  150. // save off the cursor position so we can restore it
  151. vgui::input()->GetCursorPos( m_iMouseX, m_iMouseY );
  152. }
  153. }
  154. void VControlsListPanel::OnClearBinding()
  155. {
  156. if ( m_bCaptureMode )
  157. return;
  158. if ( GetItemOfInterest() < 0 )
  159. return;
  160. PostMessage( GetParent()->GetVPanel(), new KeyValues( "ClearBinding", "item", GetItemOfInterest() ) );
  161. }
  162. //-----------------------------------------------------------------------------
  163. // Purpose: Finish capture prompt display
  164. //-----------------------------------------------------------------------------
  165. void VControlsListPanel::EndCaptureMode( HCursor hCursor )
  166. {
  167. m_bCaptureMode = false;
  168. input()->SetMouseCapture(NULL);
  169. LeaveEditMode();
  170. RequestFocus();
  171. input()->SetMouseFocus(GetVPanel());
  172. if (hCursor)
  173. {
  174. m_pInlineEditPanel->SetCursor(hCursor);
  175. surface()->SetCursor(hCursor);
  176. if ( hCursor != dc_none )
  177. {
  178. vgui::input()->SetCursorPos ( m_iMouseX, m_iMouseY );
  179. }
  180. }
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose: Set active row column
  184. //-----------------------------------------------------------------------------
  185. void VControlsListPanel::SetItemOfInterest(int itemID)
  186. {
  187. m_nClickRow = itemID;
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose: Retrieve row, column of interest
  191. //-----------------------------------------------------------------------------
  192. int VControlsListPanel::GetItemOfInterest()
  193. {
  194. return m_nClickRow;
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Purpose: returns true if we're currently waiting to capture a key
  198. //-----------------------------------------------------------------------------
  199. bool VControlsListPanel::IsCapturing( void )
  200. {
  201. return m_bCaptureMode;
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Purpose: Forwards mouse pressed message up to keyboard page when in capture
  205. //-----------------------------------------------------------------------------
  206. void VControlsListPanel::OnMousePressed(vgui::MouseCode code)
  207. {
  208. if (IsCapturing())
  209. {
  210. // forward up mouse pressed messages to be handled by the key options
  211. if (GetParent())
  212. {
  213. GetParent()->OnMousePressed(code);
  214. }
  215. }
  216. else
  217. {
  218. BaseClass::OnMousePressed(code);
  219. }
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose: input handler
  223. //-----------------------------------------------------------------------------
  224. void VControlsListPanel::OnMouseDoublePressed( vgui::MouseCode code )
  225. {
  226. int c = GetSelectedItemsCount();
  227. if ( c > 0 )
  228. {
  229. // enter capture mode
  230. OnKeyCodeTyped(KEY_ENTER);
  231. }
  232. else
  233. {
  234. BaseClass::OnMouseDoublePressed(code);
  235. }
  236. }
  237. CKeyBoardEditorPage::CKeyBoardEditorPage( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
  238. : BaseClass( parent, "KeyBoardEditorPage" ),
  239. m_pPanel( panelToEdit ),
  240. m_Handle( handle )
  241. {
  242. Assert( m_pPanel );
  243. m_pList = new VControlsListPanel( this, "KeyBindings" );
  244. m_pList->SetIgnoreDoubleClick( true );
  245. m_pList->AddColumnHeader(0, "Action", "#KBEditorBindingName", 175, 0);
  246. m_pList->AddColumnHeader(1, "Binding", "#KBEditorBinding", 175, 0);
  247. m_pList->AddColumnHeader(2, "Description", "#KBEditorDescription", 300, 0);
  248. LoadControlSettings( "resource/KeyBoardEditorPage.res" );
  249. SaveMappings();
  250. }
  251. //-----------------------------------------------------------------------------
  252. // Purpose:
  253. // Input : -
  254. //-----------------------------------------------------------------------------
  255. CKeyBoardEditorPage::~CKeyBoardEditorPage()
  256. {
  257. int c = m_Save.Count();
  258. for ( int i = 0 ; i < c; ++i )
  259. {
  260. delete m_Save[ i ];
  261. }
  262. m_Save.RemoveAll();
  263. }
  264. void CKeyBoardEditorPage::ApplySchemeSettings( IScheme *scheme )
  265. {
  266. BaseClass::ApplySchemeSettings( scheme );
  267. PopulateList();
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Purpose:
  271. // Input : -
  272. //-----------------------------------------------------------------------------
  273. void CKeyBoardEditorPage::SaveMappings()
  274. {
  275. Assert( m_Save.Count() == 0 );
  276. CUtlVector< PanelKeyBindingMap * > maps;
  277. GetMappingList( m_pPanel, maps );
  278. // add header item
  279. int c = maps.Count();
  280. for ( int i = 0; i < c; ++i )
  281. {
  282. PanelKeyBindingMap *m = maps[ i ];
  283. SaveMapping_t *sm = new SaveMapping_t;
  284. sm->map = m;
  285. sm->current = m->boundkeys;
  286. sm->original = m->boundkeys;
  287. m_Save.AddToTail( sm );
  288. }
  289. }
  290. //-----------------------------------------------------------------------------
  291. // Purpose:
  292. // Input : -
  293. //-----------------------------------------------------------------------------
  294. void CKeyBoardEditorPage::UpdateCurrentMappings()
  295. {
  296. int c = m_Save.Count();
  297. for ( int i = 0 ; i < c; ++i )
  298. {
  299. PanelKeyBindingMap *m = m_Save[ i ]->map;
  300. Assert( m );
  301. m_Save[ i ]->current = m->boundkeys;
  302. }
  303. }
  304. //-----------------------------------------------------------------------------
  305. // Purpose:
  306. // Input : -
  307. //-----------------------------------------------------------------------------
  308. void CKeyBoardEditorPage::RestoreMappings()
  309. {
  310. int c = m_Save.Count();
  311. for ( int i = 0; i < c; ++i )
  312. {
  313. SaveMapping_t *sm = m_Save[ i ];
  314. sm->current = sm->original;
  315. }
  316. }
  317. void CKeyBoardEditorPage::ApplyMappings()
  318. {
  319. int c = m_Save.Count();
  320. for ( int i = 0; i < c; ++i )
  321. {
  322. SaveMapping_t *sm = m_Save[ i ];
  323. sm->map->boundkeys = sm->current;
  324. }
  325. }
  326. //-----------------------------------------------------------------------------
  327. // Purpose: User clicked on item: remember where last active row/column was
  328. //-----------------------------------------------------------------------------
  329. void CKeyBoardEditorPage::ItemSelected()
  330. {
  331. int c = m_pList->GetSelectedItemsCount();
  332. if ( c > 0 )
  333. {
  334. m_pList->SetItemOfInterest( m_pList->GetSelectedItem( 0 ) );
  335. }
  336. }
  337. void CKeyBoardEditorPage::BindKey( KeyCode code )
  338. {
  339. bool shift = (input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT));
  340. bool ctrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
  341. bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
  342. int modifiers = 0;
  343. if ( shift )
  344. {
  345. modifiers |= MODIFIER_SHIFT;
  346. }
  347. if ( ctrl )
  348. {
  349. modifiers |= MODIFIER_CONTROL;
  350. }
  351. if ( alt )
  352. {
  353. modifiers |= MODIFIER_ALT;
  354. }
  355. int r = m_pList->GetItemOfInterest();
  356. // Retrieve clicked row and column
  357. m_pList->EndCaptureMode(dc_arrow);
  358. // Find item for this row
  359. KeyValues *item = m_pList->GetItem(r);
  360. if ( item )
  361. {
  362. BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( item->GetPtr( "Item", 0 ) );
  363. if ( kbMap )
  364. {
  365. KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
  366. if ( binding && Q_stricmp( kbMap->bindingname, binding->bindingname ) )
  367. {
  368. // Key is already rebound!!!
  369. Warning( "Can't bind to '%S', key is already bound to '%s'\n",
  370. Panel::KeyCodeToDisplayString( code ), binding->bindingname );
  371. return;
  372. }
  373. kbMap->keycode = code;
  374. kbMap->modifiers = modifiers;
  375. PopulateList();
  376. }
  377. KeyBindingMap_t *bindingMap = reinterpret_cast< KeyBindingMap_t * >( item->GetPtr( "Unbound", 0 ) );
  378. if ( bindingMap )
  379. {
  380. KeyBindingMap_t *binding = m_pPanel->LookupBindingByKeyCode( code, modifiers );
  381. if ( binding && Q_stricmp( bindingMap->bindingname, binding->bindingname ) )
  382. {
  383. // Key is already rebound!!!
  384. Warning( "Can't bind to '%S', key is already bound to '%s'\n",
  385. Panel::KeyCodeToDisplayString( code ), binding->bindingname );
  386. return;
  387. }
  388. // Need to add to current entries
  389. m_pPanel->AddKeyBinding( bindingMap->bindingname, code, modifiers );
  390. UpdateCurrentMappings();
  391. PopulateList();
  392. }
  393. }
  394. }
  395. void CKeyBoardEditorPage::OnPageHide()
  396. {
  397. if ( m_pList->IsCapturing() )
  398. {
  399. // Cancel capturing
  400. m_pList->EndCaptureMode(dc_arrow);
  401. }
  402. }
  403. //-----------------------------------------------------------------------------
  404. // Purpose: binds double-clicking or hitting enter in the keybind list to changing the key
  405. //-----------------------------------------------------------------------------
  406. void CKeyBoardEditorPage::OnKeyCodeTyped(vgui::KeyCode code)
  407. {
  408. switch ( code )
  409. {
  410. case KEY_ENTER:
  411. {
  412. if ( !m_pList->IsCapturing() )
  413. {
  414. OnCommand( "ChangeKey" );
  415. }
  416. else
  417. {
  418. BindKey( code );
  419. }
  420. }
  421. break;
  422. case KEY_LSHIFT:
  423. case KEY_RSHIFT:
  424. case KEY_LALT:
  425. case KEY_RALT:
  426. case KEY_LCONTROL:
  427. case KEY_RCONTROL:
  428. {
  429. // Swallow these
  430. break;
  431. }
  432. break;
  433. default:
  434. {
  435. if ( m_pList->IsCapturing() )
  436. {
  437. BindKey( code );
  438. }
  439. else
  440. {
  441. BaseClass::OnKeyCodeTyped(code);
  442. }
  443. }
  444. }
  445. }
  446. void CKeyBoardEditorPage::OnCommand( char const *cmd )
  447. {
  448. if ( !m_pList->IsCapturing() && !Q_stricmp( cmd, "ChangeKey" ) )
  449. {
  450. m_pList->StartCaptureMode(dc_blank);
  451. }
  452. else
  453. {
  454. BaseClass::OnCommand( cmd );
  455. }
  456. }
  457. void CKeyBoardEditorPage::OnSaveChanges()
  458. {
  459. ApplyMappings();
  460. }
  461. void CKeyBoardEditorPage::OnRevert()
  462. {
  463. RestoreMappings();
  464. PopulateList();
  465. }
  466. void CKeyBoardEditorPage::OnUseDefaults()
  467. {
  468. m_pPanel->RevertKeyBindingsToDefault();
  469. UpdateCurrentMappings();
  470. PopulateList();
  471. }
  472. void CKeyBoardEditorPage::GetMappingList( Panel *panel, CUtlVector< PanelKeyBindingMap * >& maps )
  473. {
  474. PanelKeyBindingMap *map = panel->GetKBMap();
  475. while ( map )
  476. {
  477. maps.AddToTail( map );
  478. map = map->baseMap;
  479. }
  480. }
  481. static bool BindingLessFunc( KeyValues * const & lhs, KeyValues * const &rhs )
  482. {
  483. KeyValues *p1, *p2;
  484. p1 = const_cast< KeyValues * >( lhs );
  485. p2 = const_cast< KeyValues * >( rhs );
  486. return ( Q_stricmp( p1->GetString( "Action" ), p2->GetString( "Action" ) ) < 0 ) ? true : false;
  487. }
  488. void CKeyBoardEditorPage::AnsiText( char const *token, char *out, size_t buflen )
  489. {
  490. out[ 0 ] = 0;
  491. wchar_t *str = g_pVGuiLocalize->Find( token );
  492. if ( !str )
  493. {
  494. Q_strncpy( out, token, buflen );
  495. }
  496. else
  497. {
  498. g_pVGuiLocalize->ConvertUnicodeToANSI( str, out, buflen );
  499. }
  500. }
  501. void CKeyBoardEditorPage::PopulateList()
  502. {
  503. m_pList->DeleteAllItems();
  504. int i, j;
  505. CUtlRBTree< KeyValues *, int > sorted( 0, 0, BindingLessFunc );
  506. // add header item
  507. int c = m_Save.Count();
  508. for ( i = 0; i < c; ++i )
  509. {
  510. SaveMapping_t* sm = m_Save[ i ];
  511. PanelKeyBindingMap *m = sm->map;
  512. Assert( m );
  513. int bindings = sm->current.Count();
  514. for ( j = 0; j < bindings; ++j )
  515. {
  516. BoundKey_t *kbMap = &sm->current[ j ];
  517. Assert( kbMap );
  518. // Create a new: blank item
  519. KeyValues *item = new KeyValues( "Item" );
  520. // Fill in data
  521. char loc[ 128 ];
  522. Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
  523. char ansi[ 256 ];
  524. AnsiText( loc, ansi, sizeof( ansi ) );
  525. item->SetString( "Action", ansi );
  526. item->SetWString( "Binding", Panel::KeyCodeModifiersToDisplayString( (KeyCode)kbMap->keycode, kbMap->modifiers ) );
  527. // Find the binding
  528. KeyBindingMap_t *bindingMap = m_pPanel->LookupBinding( kbMap->bindingname );
  529. if ( bindingMap &&
  530. bindingMap->helpstring )
  531. {
  532. AnsiText( bindingMap->helpstring, ansi, sizeof( ansi ) );
  533. item->SetString( "Description", ansi);
  534. }
  535. item->SetPtr( "Item", kbMap );
  536. sorted.Insert( item );
  537. }
  538. // Now try and find any "unbound" keys...
  539. int mappings = m->entries.Count();
  540. for ( j = 0; j < mappings; ++j )
  541. {
  542. KeyBindingMap_t *kbMap = &m->entries[ j ];
  543. // See if it's bound
  544. CUtlVector< BoundKey_t * > list;
  545. m_pPanel->LookupBoundKeys( kbMap->bindingname, list );
  546. if ( list.Count() > 0 )
  547. continue;
  548. // Not bound, add a placeholder entry
  549. // Create a new: blank item
  550. KeyValues *item = new KeyValues( "Item" );
  551. // fill in data
  552. char loc[ 128 ];
  553. Q_snprintf( loc, sizeof( loc ), "#%s", kbMap->bindingname );
  554. char ansi[ 256 ];
  555. AnsiText( loc, ansi, sizeof( ansi ) );
  556. item->SetString( "Action", ansi );
  557. item->SetWString( "Binding", L"" );
  558. if ( kbMap->helpstring )
  559. {
  560. AnsiText( kbMap->helpstring, ansi, sizeof( ansi ) );
  561. item->SetString( "Description", ansi );
  562. }
  563. item->SetPtr( "Unbound", kbMap );
  564. sorted.Insert( item );
  565. }
  566. }
  567. for ( j = sorted.FirstInorder() ; j != sorted.InvalidIndex(); j = sorted.NextInorder( j ) )
  568. {
  569. KeyValues *item = sorted[ j ];
  570. // Add to list
  571. m_pList->AddItem( item, 0, false, false );
  572. item->deleteThis();
  573. }
  574. sorted.RemoveAll();
  575. }
  576. void CKeyBoardEditorPage::OnClearBinding( int item )
  577. {
  578. // Find item for this row
  579. KeyValues *kv = m_pList->GetItem(item );
  580. if ( !kv )
  581. {
  582. return;
  583. }
  584. BoundKey_t *kbMap = reinterpret_cast< BoundKey_t * >( kv->GetPtr( "Item", 0 ) );
  585. if ( !kbMap )
  586. {
  587. return;
  588. }
  589. kbMap->keycode = KEY_NONE;
  590. kbMap->modifiers = 0;
  591. PopulateList();
  592. }
  593. CKeyBoardEditorSheet::CKeyBoardEditorSheet( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
  594. : BaseClass( parent, "KeyBoardEditorSheet" ),
  595. m_bSaveToExternalFile( false ),
  596. m_Handle( handle ),
  597. m_SaveFileName( UTL_INVAL_SYMBOL ),
  598. m_SaveFilePathID( UTL_INVAL_SYMBOL )
  599. {
  600. m_hPanel = panelToEdit;
  601. SetSmallTabs( true );
  602. // Create this sheet and add the subcontrols
  603. CKeyBoardEditorPage *active = NULL;
  604. int subCount = Panel::GetPanelsWithKeyBindingsCount( handle );
  605. for ( int i = 0; i < subCount; ++i )
  606. {
  607. Panel *p = Panel::GetPanelWithKeyBindings( handle, i );
  608. if ( !p )
  609. continue;
  610. // Don't display panels with no keymappings
  611. if ( p->GetKeyMappingCount() == 0 )
  612. continue;
  613. CKeyBoardEditorPage *newPage = new CKeyBoardEditorPage( this, p, handle );
  614. AddPage( newPage, p->GetName() );
  615. if ( p == panelToEdit )
  616. {
  617. active = newPage;
  618. }
  619. }
  620. if ( active )
  621. {
  622. SetActivePage( active );
  623. }
  624. LoadControlSettings( "resource/KeyBoardEditorSheet.res" );
  625. }
  626. void CKeyBoardEditorSheet::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
  627. {
  628. Assert( filename );
  629. m_bSaveToExternalFile = true;
  630. m_SaveFileName = filename;
  631. if ( pathID != NULL )
  632. {
  633. m_SaveFilePathID = pathID;
  634. }
  635. else
  636. {
  637. m_SaveFilePathID = UTL_INVAL_SYMBOL;
  638. }
  639. }
  640. void CKeyBoardEditorSheet::OnSaveChanges()
  641. {
  642. int c = GetNumPages();
  643. for ( int i = 0 ; i < c; ++i )
  644. {
  645. CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
  646. page->OnSaveChanges();
  647. }
  648. if ( m_bSaveToExternalFile )
  649. {
  650. m_hPanel->SaveKeyBindingsToFile( m_Handle, m_SaveFileName.String(), m_SaveFilePathID.IsValid() ? m_SaveFilePathID.String() : NULL );
  651. }
  652. else
  653. {
  654. m_hPanel->SaveKeyBindings( m_Handle );
  655. }
  656. }
  657. void CKeyBoardEditorSheet::OnRevert()
  658. {
  659. int c = GetNumPages();
  660. for ( int i = 0 ; i < c; ++i )
  661. {
  662. CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
  663. page->OnRevert();
  664. }
  665. }
  666. void CKeyBoardEditorSheet::OnUseDefaults()
  667. {
  668. int c = GetNumPages();
  669. for ( int i = 0 ; i < c; ++i )
  670. {
  671. CKeyBoardEditorPage *page = static_cast< CKeyBoardEditorPage * >( GetPage( i ) );
  672. page->OnUseDefaults();
  673. }
  674. }
  675. CKeyBoardEditorDialog::CKeyBoardEditorDialog( Panel *parent, Panel *panelToEdit, KeyBindingContextHandle_t handle )
  676. : BaseClass( parent, "KeyBoardEditorDialog" )
  677. {
  678. m_pSave = new Button( this, "Save", "#KBEditorSave", this, "save" );
  679. m_pCancel = new Button( this, "Cancel", "#KBEditorCancel", this, "cancel" );
  680. m_pRevert = new Button( this, "Revert", "#KBEditorRevert", this, "revert" );
  681. m_pUseDefaults = new Button( this, "Defaults", "#KBEditorUseDefaults", this, "defaults" );
  682. m_pKBEditor = new CKeyBoardEditorSheet( this, panelToEdit, handle );
  683. LoadControlSettings( "resource/KeyBoardEditorDialog.res" );
  684. SetTitle( "#KBEditorTitle", true );
  685. SetSmallCaption( true );
  686. SetMinimumSize( 640, 200 );
  687. SetMinimizeButtonVisible( false );
  688. SetMaximizeButtonVisible( false );
  689. SetSizeable( true );
  690. SetMoveable( true );
  691. SetMenuButtonVisible( false );
  692. SetVisible( true );
  693. MoveToCenterOfScreen();
  694. }
  695. void CKeyBoardEditorDialog::OnCommand( char const *cmd )
  696. {
  697. if ( !Q_stricmp( cmd, "save" ) )
  698. {
  699. m_pKBEditor->OnSaveChanges();
  700. MarkForDeletion();
  701. }
  702. else if ( !Q_stricmp( cmd, "cancel" ) ||
  703. !Q_stricmp( cmd, "Close" ) )
  704. {
  705. m_pKBEditor->OnRevert();
  706. MarkForDeletion();
  707. }
  708. else if ( !Q_stricmp( cmd, "revert" ) )
  709. {
  710. m_pKBEditor->OnRevert();
  711. }
  712. else if ( !Q_stricmp( cmd, "defaults" ) )
  713. {
  714. m_pKBEditor->OnUseDefaults();
  715. }
  716. else
  717. {
  718. BaseClass::OnCommand( cmd );
  719. }
  720. }
  721. void CKeyBoardEditorDialog::SetKeybindingsSaveFile( char const *filename, char const *pathID /*= 0*/ )
  722. {
  723. m_pKBEditor->SetKeybindingsSaveFile( filename, pathID );
  724. }