cvpcb: Add processing of hotkeys to the main window

* Add a tool loop to handle ESC to close the window and
focus changing keys
* Make changing focus a tool
This commit is contained in:
Ian McInerney 2019-08-09 00:11:59 +02:00 committed by Wayne Stambaugh
parent d428d5fecf
commit 2d27c10c63
9 changed files with 296 additions and 96 deletions

View File

@ -26,6 +26,7 @@
*/
#include <fctsys.h>
#include <trace_helpers.h>
#include <cvpcb.h>
#include <cvpcb_mainframe.h>
@ -111,21 +112,12 @@ void COMPONENTS_LISTBOX::SetSelection( int index, bool State )
void COMPONENTS_LISTBOX::OnChar( wxKeyEvent& event )
{
wxLogTrace( kicadTraceKeyEvent, "COMPONENTS_LISTBOX::OnChar %s", dump( event ) );
int key = event.GetKeyCode();
switch( key )
{
case WXK_TAB:
case WXK_RIGHT:
case WXK_NUMPAD_RIGHT:
GetParent()->ChangeFocus( true );
return;
case WXK_LEFT:
case WXK_NUMPAD_LEFT:
GetParent()->ChangeFocus( false );
return;
case WXK_HOME:
case WXK_END:
case WXK_UP:

View File

@ -40,6 +40,7 @@
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
#include <tool/conditional_menu.h>
#include <tool/tool_dispatcher.h>
#include <tool/tool_manager.h>
#include <widgets/progress_reporter.h>
#include <wx/statline.h>
@ -189,19 +190,10 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_initialized = true;
// Connect Events
m_footprintListBox->Connect( wxEVT_RIGHT_DOWN,
wxMouseEventHandler( CVPCB_MAINFRAME::OnFootprintRightClick ),
NULL, this );
m_compListBox->Connect( wxEVT_RIGHT_DOWN,
wxMouseEventHandler( CVPCB_MAINFRAME::OnComponentRightClick ),
NULL, this );
setupEventHandlers();
// Use Bind for this one to allow the lambda expression
m_saveAndContinue->Bind( wxEVT_COMMAND_BUTTON_CLICKED,
[this]( wxCommandEvent& )
{
this->GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations );
} );
// Start the main processing loop
m_toolManager->InvokeTool( "cvpcb.Control" );
// Ensure the toolbars are sync'd properly so the filtering options display correct
SyncToolbars();
@ -210,10 +202,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
{
// Disconnect Events
m_footprintListBox->Disconnect( wxEVT_RIGHT_DOWN,
wxMouseEventHandler( CVPCB_MAINFRAME::OnFootprintRightClick ),
NULL, this );
// No events to disconnect since they are using lambdas as the handlers
m_auimgr.UnInit();
}
@ -222,8 +211,10 @@ CVPCB_MAINFRAME::~CVPCB_MAINFRAME()
void CVPCB_MAINFRAME::setupTools()
{
// Create the manager
m_actions = new CVPCB_ACTIONS();
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, this );
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, m_actions );
// Register tools
m_toolManager->RegisterTool( new COMMON_CONTROL );
@ -243,6 +234,34 @@ void CVPCB_MAINFRAME::setupTools()
m_footprintContextMenu->Add( CVPCB_ACTIONS::showFootprintViewer );
}
void CVPCB_MAINFRAME::setupEventHandlers()
{
// Connect the handlers to launch the context menus in the listboxes
m_footprintListBox->Bind( wxEVT_RIGHT_DOWN,
[this]( wxMouseEvent& )
{
PopupMenu( m_footprintContextMenu );
} );
m_compListBox->Bind( wxEVT_RIGHT_DOWN,
[this]( wxMouseEvent& )
{
PopupMenu( m_componentContextMenu );
} );
// Connect the handler for the save button
m_saveAndContinue->Bind( wxEVT_COMMAND_BUTTON_CLICKED,
[this]( wxCommandEvent& )
{
this->GetToolManager()->RunAction( CVPCB_ACTIONS::saveAssociations );
} );
// Attach the events to the tool dispatcher
Bind( wxEVT_TOOL, &TOOL_DISPATCHER::DispatchWxCommand, m_toolDispatcher );
Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
}
void CVPCB_MAINFRAME::LoadSettings( wxConfigBase* aCfg )
{
EDA_BASE_FRAME::LoadSettings( aCfg );
@ -297,31 +316,6 @@ void CVPCB_MAINFRAME::OnCloseWindow( wxCloseEvent& Event )
}
void CVPCB_MAINFRAME::ChangeFocus( bool aMoveRight )
{
wxWindow* hasFocus = wxWindow::FindFocus();
if( aMoveRight )
{
if( hasFocus == m_libListBox )
m_compListBox->SetFocus();
else if( hasFocus == m_compListBox )
m_footprintListBox->SetFocus();
else if( hasFocus == m_footprintListBox )
m_libListBox->SetFocus();
}
else
{
if( hasFocus == m_libListBox )
m_footprintListBox->SetFocus();
else if( hasFocus == m_compListBox )
m_libListBox->SetFocus();
else if( hasFocus == m_footprintListBox )
m_compListBox->SetFocus();
}
}
void CVPCB_MAINFRAME::OnOK( wxCommandEvent& aEvent )
{
SaveFootprintAssociation( false );
@ -453,18 +447,6 @@ bool CVPCB_MAINFRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, i
}
void CVPCB_MAINFRAME::OnComponentRightClick( wxMouseEvent& event )
{
PopupMenu( m_componentContextMenu );
}
void CVPCB_MAINFRAME::OnFootprintRightClick( wxMouseEvent& event )
{
PopupMenu( m_footprintContextMenu );
}
void CVPCB_MAINFRAME::OnSelectComponent( wxListEvent& event )
{
if( m_skipComponentSelect )
@ -954,6 +936,54 @@ DISPLAY_FOOTPRINTS_FRAME* CVPCB_MAINFRAME::GetFootprintViewerFrame()
}
CVPCB_MAINFRAME::CONTROL_TYPE CVPCB_MAINFRAME::GetFocusedControl()
{
if( m_libListBox->HasFocus() )
return CVPCB_MAINFRAME::CONTROL_LIBRARY;
else if( m_compListBox->HasFocus() )
return CVPCB_MAINFRAME::CONTROL_COMPONENT;
else if( m_footprintListBox->HasFocus() )
return CVPCB_MAINFRAME::CONTROL_FOOTPRINT;
return CVPCB_MAINFRAME::CONTROL_NONE;
}
wxControl* CVPCB_MAINFRAME::GetFocusedControlObject()
{
if( m_libListBox->HasFocus() )
return m_libListBox;
else if( m_compListBox->HasFocus() )
return m_compListBox;
else if( m_footprintListBox->HasFocus() )
return m_footprintListBox;
return nullptr;
}
void CVPCB_MAINFRAME::SetFocusedControl( CVPCB_MAINFRAME::CONTROL_TYPE aLB )
{
switch( aLB )
{
case CVPCB_MAINFRAME::CONTROL_LIBRARY:
m_libListBox->SetFocus();
break;
case CVPCB_MAINFRAME::CONTROL_COMPONENT:
m_compListBox->SetFocus();
break;
case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
m_footprintListBox->SetFocus();
break;
default:
break;
}
}
wxString CVPCB_MAINFRAME::GetSelectedFootprint()
{
// returns the LIB_ID of the selected footprint in footprint listview

View File

@ -104,6 +104,26 @@ public:
FILTER_TOGGLE ///< Toggle the filter state
};
/**
* The type of the controls present in the application
*/
enum CONTROL_TYPE
{
CONTROL_NONE, ///< No controls have focus
CONTROL_LIBRARY, ///< Library listbox
CONTROL_COMPONENT, ///< Component listbox
CONTROL_FOOTPRINT ///< Footprint listbox
};
/**
* Directions to rotate the focus through the listboxes is
*/
enum FOCUS_DIR
{
CHANGE_FOCUS_RIGHT,
CHANGE_FOCUS_LEFT
};
/**
* Directions to move when selecting items
*/
@ -118,6 +138,27 @@ public:
*/
DISPLAY_FOOTPRINTS_FRAME* GetFootprintViewerFrame();
/**
* Find out which control currently has focus.
*
* @return the contorl that currently has focus
*/
CVPCB_MAINFRAME::CONTROL_TYPE GetFocusedControl();
/**
* Get a pointer to the currently focused control
*
* @return the control that currently has focus
*/
wxControl* GetFocusedControlObject();
/**
* Set the focus to a specific control.
*
* @param aControl the contorl to set focus to
*/
void SetFocusedControl( CVPCB_MAINFRAME::CONTROL_TYPE aControl );
/**
* Function OnSelectComponent
* Called when clicking on a component in component list window
@ -137,12 +178,6 @@ public:
void ReCreateMenuBar() override;
void ShowChangedLanguage() override;
void ChangeFocus( bool aMoveRight );
void OnComponentRightClick( wxMouseEvent& event );
void OnFootprintRightClick( wxMouseEvent& event );
/**
* Called by the automatic association button
* Read *.equ files to try to find corresponding footprint
@ -347,6 +382,11 @@ private:
*/
void setupTools();
/**
* Setup event handlers
*/
void setupEventHandlers();
/**
* read the .equ files and populate the list of equvalents
* @param aList the list to populate
@ -358,6 +398,9 @@ private:
void refreshAfterComponentSearch (COMPONENT* component);
// Tool dispatcher
TOOL_DISPATCHER* m_toolDispatcher;
// Context menus for the list boxes
ACTION_MENU* m_footprintContextMenu;
ACTION_MENU* m_componentContextMenu;

View File

@ -31,6 +31,7 @@
#include <fctsys.h>
#include <footprint_filter.h>
#include <tool/tool_manager.h>
#include <trace_helpers.h>
#include <wx/wupdlock.h>
#include <cvpcb.h>
@ -233,21 +234,12 @@ void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
{
wxLogTrace( kicadTraceKeyEvent, "FOOTPRINTS_LISTBOX::OnChar %s", dump( event ) );
int key = event.GetKeyCode();
switch( key )
{
case WXK_TAB:
case WXK_RIGHT:
case WXK_NUMPAD_RIGHT:
GetParent()->ChangeFocus( true );
return;
case WXK_LEFT:
case WXK_NUMPAD_LEFT:
GetParent()->ChangeFocus( false );
return;
case WXK_HOME:
case WXK_END:
case WXK_UP:

View File

@ -28,6 +28,7 @@
#include <fctsys.h>
#include <macros.h>
#include <trace_helpers.h>
#include <cvpcb.h>
#include <cvpcb_mainframe.h>
@ -144,21 +145,12 @@ END_EVENT_TABLE()
void LIBRARY_LISTBOX::OnChar( wxKeyEvent& event )
{
wxLogTrace( kicadTraceKeyEvent, "LIBRARY_LISTBOX::OnChar %s", dump( event ) );
int key = event.GetKeyCode();
switch( key )
{
case WXK_TAB:
case WXK_RIGHT:
case WXK_NUMPAD_RIGHT:
GetParent()->ChangeFocus( true );
return;
case WXK_LEFT:
case WXK_NUMPAD_LEFT:
GetParent()->ChangeFocus( false );
return;
case WXK_HOME:
case WXK_END:
case WXK_UP:

View File

@ -41,6 +41,12 @@ TOOL_ACTION CVPCB_ACTIONS::selectionActivate( "cvpcb.InteractiveSelection", AS_G
"",
NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
TOOL_ACTION CVPCB_ACTIONS::controlActivate( "cvpcb.Control", AS_GLOBAL,
0, "",
"",
"",
NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
// Action to show the footprint viewer window
TOOL_ACTION CVPCB_ACTIONS::showFootprintViewer( "cvpcb.Control.ShowFootprintViewer", AS_GLOBAL,
@ -64,6 +70,21 @@ TOOL_ACTION CVPCB_ACTIONS::saveAssociations( "cvpcb.Control.SaveAssocations", AS
_( "Save footprint associations in schematic symbol footprint fields" ),
save_xpm );
// Actions to navigate the display
TOOL_ACTION CVPCB_ACTIONS::changeFocusRight( "cvpcb.Control.changeFocusRight", AS_GLOBAL,
WXK_TAB, "",
"",
"",
nullptr, AF_NONE,
(void*) CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT );
TOOL_ACTION CVPCB_ACTIONS::changeFocusLeft( "cvpcb.Control.changeFocusLeft", AS_GLOBAL,
MD_SHIFT + WXK_TAB, "",
"",
"",
nullptr, AF_NONE,
(void*) CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT );
// Actions to navigate the component list
TOOL_ACTION CVPCB_ACTIONS::gotoNextNA( "cvpcb.Control.GotoNextNA", AS_GLOBAL,
0, "",
@ -82,7 +103,7 @@ TOOL_ACTION CVPCB_ACTIONS::gotoPreviousNA( "cvpcb.Control.GotoPreviousNA", AS_GL
// Actions to modify component associations
TOOL_ACTION CVPCB_ACTIONS::associate( "cvpcb.Control.Associate", AS_GLOBAL,
0, "",
WXK_RETURN, "",
_( "Associate footprint" ),
_( "Associate selected footprint with selected components" ),
auto_associe_xpm );

View File

@ -42,9 +42,13 @@ class TOOL_MANAGER;
class CVPCB_ACTIONS : public ACTIONS
{
public:
// Selection Tool
/// Activation of the selection tool
/// Activation actions
static TOOL_ACTION selectionActivate;
static TOOL_ACTION controlActivate;
/// Window control actions
static TOOL_ACTION changeFocusRight;
static TOOL_ACTION changeFocusLeft;
/// Open the footprint viewer
static TOOL_ACTION showFootprintViewer;

View File

@ -25,6 +25,7 @@
#include <kiway_express.h>
#include <lib_id.h>
#include <tool/actions.h>
#include <tool/tool_manager.h>
#include <cvpcb_mainframe.h>
#include <dialogs/dialog_config_equfiles.h>
@ -49,6 +50,113 @@ void CVPCB_CONTROL::Reset( RESET_REASON aReason )
}
int CVPCB_CONTROL::Main( const TOOL_EVENT& aEvent )
{
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
bool handled = false;
// The escape key maps to the cancel event, which is used to close the window
if( evt->IsCancel() )
{
wxCloseEvent dummy;
m_frame->OnCloseWindow( dummy );
handled = true;
}
else if( evt->IsKeyPressed() )
{
switch( evt->KeyCode() )
{
// The right arrow moves focus to the focusable object to the right
case WXK_RIGHT:
m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusRight );
handled = true;
break;
// The left arrow moves focus to the focusable object to the left
case WXK_LEFT:
m_toolMgr->RunAction( CVPCB_ACTIONS::changeFocusLeft );
handled = true;
break;
default:
// Let every other key continue processing to the controls of the window
break;
}
}
if( !handled )
evt->SetPassEvent();
}
// This tool is supposed to be active forever
wxASSERT( false );
return 0;
}
int CVPCB_CONTROL::ChangeFocus( const TOOL_EVENT& aEvent )
{
int tmp = aEvent.Parameter<intptr_t>();
CVPCB_MAINFRAME::FOCUS_DIR dir =
static_cast<CVPCB_MAINFRAME::FOCUS_DIR>( tmp );
switch( dir )
{
case CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT:
switch( m_frame->GetFocusedControl() )
{
case CVPCB_MAINFRAME::CONTROL_LIBRARY:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
break;
case CVPCB_MAINFRAME::CONTROL_COMPONENT:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
break;
case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
break;
case CVPCB_MAINFRAME::CONTROL_NONE:
default:
break;
}
break;
case CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT:
switch( m_frame->GetFocusedControl() )
{
case CVPCB_MAINFRAME::CONTROL_LIBRARY:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_FOOTPRINT );
break;
case CVPCB_MAINFRAME::CONTROL_COMPONENT:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_LIBRARY );
break;
case CVPCB_MAINFRAME::CONTROL_FOOTPRINT:
m_frame->SetFocusedControl( CVPCB_MAINFRAME::CONTROL_COMPONENT );
break;
case CVPCB_MAINFRAME::CONTROL_NONE:
default:
break;
}
break;
default:
break;
}
return 0;
}
int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
{
@ -280,8 +388,11 @@ int CVPCB_CONTROL::UpdateMenu( const TOOL_EVENT& aEvent )
void CVPCB_CONTROL::setTransitions()
{
// Update the menu
// Control actions
Go( &CVPCB_CONTROL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() );
Go( &CVPCB_CONTROL::Main, CVPCB_ACTIONS::controlActivate.MakeEvent() );
Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusRight.MakeEvent() );
Go( &CVPCB_CONTROL::ChangeFocus, CVPCB_ACTIONS::changeFocusLeft.MakeEvent() );
// Run the footprint viewer
Go( &CVPCB_CONTROL::ShowFootprintViewer, CVPCB_ACTIONS::showFootprintViewer.MakeEvent() );

View File

@ -41,6 +41,21 @@ public:
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
/**
* Main processing loop for the CVPCB window. This function will constantly loop and
* to process various actions taken in the window.
*
* @param aEvent is the event generated by the tool framework
*/
int Main( const TOOL_EVENT& aEvent );
/**
* Rotate focus in the CVPCB window
*
* @param aEvent is the event generated by the tool framework
*/
int ChangeFocus( const TOOL_EVENT& aEvent );
/**
* Undo the footprint associations most recently done.
*