Add a filter box to hotkey dialog and filter using it

This uses a simple case-insensitive partial match, which is
a good start for the relatively limited number of hotkeys
generally present.
This commit is contained in:
John Beard 2018-08-01 10:15:05 +01:00 committed by Wayne Stambaugh
parent 4f0166e064
commit 9f38b70491
7 changed files with 212 additions and 10 deletions

View File

@ -35,6 +35,8 @@ PANEL_HOTKEYS_EDITOR::PANEL_HOTKEYS_EDITOR( EDA_BASE_FRAME* aFrame, wxWindow* aW
m_nickname( aNickname ),
m_hotkeyStore( aShowHotkeys )
{
m_filterSearch->SetDescriptiveText( _("Type filter text") );
m_hotkeyListCtrl = new WIDGET_HOTKEY_LIST( m_panelHotkeys, m_hotkeyStore );
m_hotkeyListCtrl->InstallOnPanel( m_panelHotkeys );
}
@ -79,3 +81,9 @@ void PANEL_HOTKEYS_EDITOR::OnImport( wxCommandEvent& aEvent )
{
m_frame->ImportHotkeyConfigFromFile( m_hotkeys, m_nickname );
}
void PANEL_HOTKEYS_EDITOR::OnFilterSearch( wxCommandEvent& aEvent )
{
const auto searchStr = aEvent.GetString();
m_hotkeyListCtrl->ApplyFilterString( searchStr );
}

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2018)
// C++ code generated with wxFormBuilder (version Jun 18 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -16,6 +16,13 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow
wxBoxSizer* bMargins;
bMargins = new wxBoxSizer( wxVERTICAL );
m_filterSearch = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
#ifndef __WXMAC__
m_filterSearch->ShowSearchButton( false );
#endif
m_filterSearch->ShowCancelButton( true );
bMargins->Add( m_filterSearch, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
m_panelHotkeys = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_panelHotkeys->SetMinSize( wxSize( -1,350 ) );
@ -50,6 +57,7 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow
this->Layout();
// Connect Events
m_filterSearch->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnFilterSearch ), NULL, this );
m_resetButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::ResetClicked ), NULL, this );
m_defaultButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::DefaultsClicked ), NULL, this );
btnImport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnImport ), NULL, this );
@ -59,6 +67,7 @@ PANEL_HOTKEYS_EDITOR_BASE::PANEL_HOTKEYS_EDITOR_BASE( wxWindow* parent, wxWindow
PANEL_HOTKEYS_EDITOR_BASE::~PANEL_HOTKEYS_EDITOR_BASE()
{
// Disconnect Events
m_filterSearch->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnFilterSearch ), NULL, this );
m_resetButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::ResetClicked ), NULL, this );
m_defaultButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::DefaultsClicked ), NULL, this );
btnImport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_HOTKEYS_EDITOR_BASE::OnImport ), NULL, this );

View File

@ -93,6 +93,98 @@
<property name="name">bMargins</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxSearchCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="cancel_button">1</property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_filterSearch</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="search_button">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCancelButton"></event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSearchButton"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText">OnFilterSearch</event>
<event name="OnTextEnter"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
@ -216,6 +308,7 @@
<property name="hidden">0</property>
<property name="id">wxID_RESET</property>
<property name="label">Reset Hotkeys</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -304,6 +397,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Set to Defaults</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -402,6 +496,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Import...</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -490,6 +585,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Export...</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2018)
// C++ code generated with wxFormBuilder (version Jun 18 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -11,12 +11,13 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/panel.h>
#include <wx/string.h>
#include <wx/srchctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/sizer.h>
@ -32,6 +33,7 @@ class PANEL_HOTKEYS_EDITOR_BASE : public wxPanel
protected:
wxBoxSizer* m_mainSizer;
wxSearchCtrl* m_filterSearch;
wxPanel* m_panelHotkeys;
wxButton* m_resetButton;
wxButton* m_defaultButton;
@ -39,6 +41,7 @@ class PANEL_HOTKEYS_EDITOR_BASE : public wxPanel
wxButton* btnExport;
// Virtual event handlers, overide them in your derived class
virtual void OnFilterSearch( wxCommandEvent& event ) { event.Skip(); }
virtual void ResetClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void DefaultsClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnImport( wxCommandEvent& event ) { event.Skip(); }

View File

@ -226,6 +226,52 @@ public:
};
/**
* Class HOTKEY_FILTER
*
* Class to manage logic for filtering hotkeys based on user input
*/
class HOTKEY_FILTER
{
public:
HOTKEY_FILTER( const wxString& aFilterStr )
{
m_normalised_filter_str = aFilterStr.Upper();
m_valid = m_normalised_filter_str.size() > 0;
}
/**
* Method FilterMatches
*
* Checks if the filter matches the given hotkey
*
* @return true on match (or if filter is disabled)
*/
bool FilterMatches( const EDA_HOTKEY& aHotkey ) const
{
if( !m_valid )
return true;
// Match in the (translated) filter string
const auto normedInfo = wxGetTranslation( aHotkey.m_InfoMsg ).Upper();
if( normedInfo.Contains( m_normalised_filter_str ) )
return true;
const wxString keyName = KeyNameFromKeyCode( aHotkey.m_KeyCode );
if( keyName.Upper().Contains( m_normalised_filter_str ) )
return true;
return false;
}
private:
bool m_valid;
wxString m_normalised_filter_str;
};
WIDGET_HOTKEY_CLIENT_DATA* WIDGET_HOTKEY_LIST::GetHKClientData( wxTreeListItem aItem )
{
if( aItem.IsOk() )
@ -449,6 +495,12 @@ void WIDGET_HOTKEY_LIST::InstallOnPanel( wxPanel* aPanel )
}
void WIDGET_HOTKEY_LIST::ApplyFilterString( const wxString& aFilterStr )
{
updateShownItems( aFilterStr );
}
void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault )
{
Freeze();
@ -470,31 +522,39 @@ void WIDGET_HOTKEY_LIST::ResetAllHotkeys( bool aResetToDefault )
}
bool WIDGET_HOTKEY_LIST::TransferDataToControl()
{
updateShownItems( "" );
return true;
}
void WIDGET_HOTKEY_LIST::updateShownItems( const wxString& aFilterStr )
{
Freeze();
DeleteAllItems();
HOTKEY_FILTER filter( aFilterStr );
for( auto& section: m_hk_store.GetSections() )
{
// Create parent tree item
wxTreeListItem parent = AppendItem( GetRootItem(), section.m_name );
for( auto& hotkey: section.m_hotkeys )
{
if( filter.FilterMatches( hotkey.GetCurrentValue() ) )
{
wxTreeListItem item = AppendItem( parent, wxEmptyString );
SetItemData( item, new WIDGET_HOTKEY_CLIENT_DATA( hotkey ) );
}
}
Expand( parent );
}
UpdateFromClientData();
Thaw();
return true;
}

View File

@ -72,6 +72,14 @@ private:
void OnExport( wxCommandEvent& aEvent ) override;
void OnImport( wxCommandEvent& aEvent ) override;
/**
* Function OnFilterSearch
* Handle a change in the hoteky filter text
*
* @param aEvent: the search event, used to get the search query
*/
void OnFilterSearch( wxCommandEvent& aEvent ) override;
};

View File

@ -67,6 +67,15 @@ class WIDGET_HOTKEY_LIST : public TWO_COLUMN_TREE_LIST
*/
void UpdateFromClientData();
/**
* Method updateShownItems
*
* Update the items shown in the widget based on a given filter string.
*
* @param aFilterStr the string to filter with. Empty means no filter.
*/
void updateShownItems( const wxString& aFilterStr );
protected:
/**
@ -147,6 +156,15 @@ public:
*/
void InstallOnPanel( wxPanel* aPanel );
/**
* Method ApplyFilterString
* Apply a filter string to the hotkey list, selecting which hotkeys
* to show.
*
* @param aFilterStr the string to filter by
*/
void ApplyFilterString( const wxString& aFilterStr );
/**
* Set hotkeys in the control to default or original values.
* @param aResetToDefault if true,.reset to the defaults inherent to the