Allow toolbar items to cancel tools when pressed

There was a regression in v6 where the zoom to selection toolbar
item wasn't canceling the tool when pressed and the tool was active
(it was in v5). This implements a more generic framework for canceling
tools on button presses.

Fixes https://gitlab.com/kicad/code/kicad/issues/5103
This commit is contained in:
Ian McInerney 2020-09-05 01:48:22 +01:00
parent 7893af2c60
commit f28b60896c
12 changed files with 58 additions and 27 deletions

View File

@ -57,16 +57,19 @@ ACTION_TOOLBAR::~ACTION_TOOLBAR()
}
void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction, bool aIsToggleEntry )
void ACTION_TOOLBAR::Add( const TOOL_ACTION& aAction, bool aIsToggleEntry, bool aIsCancellable )
{
wxASSERT_MSG( !( aIsCancellable && !aIsToggleEntry ), "aIsCancellable requires aIsToggleEntry" );
wxWindow* parent = dynamic_cast<wxWindow*>( m_toolManager->GetToolHolder() );
int toolId = aAction.GetUIId();
AddTool( toolId, wxEmptyString, KiScaledBitmap( aAction.GetIcon(), parent ),
aAction.GetDescription(), aIsToggleEntry ? wxITEM_CHECK : wxITEM_NORMAL );
m_toolKinds[ toolId ] = aIsToggleEntry;
m_toolActions[ toolId ] = &aAction;
m_toolKinds[ toolId ] = aIsToggleEntry;
m_toolActions[ toolId ] = &aAction;
m_toolCancellable[ toolId ] = aIsCancellable;
}
@ -168,29 +171,37 @@ void ACTION_TOOLBAR::Toggle( const TOOL_ACTION& aAction, bool aEnabled, bool aCh
void ACTION_TOOLBAR::onToolEvent( wxAuiToolBarEvent& aEvent )
{
int id = aEvent.GetId();
wxEventType type = aEvent.GetEventType();
OPT_TOOL_EVENT evt;
wxString menuText;
wxEventType type = aEvent.GetEventType();
bool handled = false;
if( type == wxEVT_COMMAND_TOOL_CLICKED && aEvent.GetId() >= TOOL_ACTION::GetBaseUIId() )
if( m_toolManager && type == wxEVT_COMMAND_TOOL_CLICKED && id >= TOOL_ACTION::GetBaseUIId() )
{
const auto it = m_toolActions.find( aEvent.GetId() );
const auto actionIt = m_toolActions.find( id );
if( it != m_toolActions.end() )
evt = it->second->MakeEvent();
// The toolbar item is toggled before the event is sent, so we check for it not being
// toggled to see if it was toggled originally
if( m_toolCancellable[id] && !GetToolToggled( id ) )
{
// Send a cancel event
m_toolManager->CancelTool();
handled = true;
}
else if( actionIt != m_toolActions.end() )
{
// Dispatch a tool event
evt = actionIt->second->MakeEvent();
evt->SetHasPosition( false );
m_toolManager->ProcessEvent( *evt );
handled = true;
}
}
// forward the action/update event to the TOOL_MANAGER
if( evt && m_toolManager )
{
evt->SetHasPosition( false );
m_toolManager->ProcessEvent( *evt );
}
else
{
// Skip the event if we don't handle it
if( !handled )
aEvent.Skip();
}
}

View File

@ -337,6 +337,14 @@ bool TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow, void* aPara
}
void TOOL_MANAGER::CancelTool()
{
TOOL_EVENT evt( TC_COMMAND, TA_CANCEL_TOOL );
processEvent( evt );
}
void TOOL_MANAGER::PrimeTool( const VECTOR2D& aPosition )
{
int modifiers = 0;

View File

@ -273,7 +273,7 @@ void DISPLAY_FOOTPRINTS_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->Add( PCB_ACTIONS::zoomFootprintAutomatically, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->AddScaledSeparator( this );

View File

@ -101,7 +101,7 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( EE_ACTIONS::symbolProperties );

View File

@ -78,7 +78,7 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( EE_ACTIONS::navigateHierarchy );

View File

@ -72,7 +72,7 @@ void GERBVIEW_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );

View File

@ -51,8 +51,13 @@ public:
/**
* Adds a TOOL_ACTION-based button to the toolbar. After selecting the entry,
* a TOOL_EVENT command containing name of the action is sent.
*
* @param aAction is the action to add
* @param aIsToggleEntry makes the toolbar item a toggle entry when true
* @param aIsCancellable when true, cancels the tool if clicked when tool is active
*/
void Add( const TOOL_ACTION& aAction, bool aIsToggleEntry = false );
void Add( const TOOL_ACTION& aAction, bool aIsToggleEntry = false,
bool aIsCancellable = false );
/**
* Adds a large button such as used in the Kicad Manager Frame's launch bar.
@ -99,6 +104,7 @@ public:
void Toggle( const TOOL_ACTION& aAction, bool aEnabled, bool aChecked );
static constexpr bool TOGGLE = true;
static constexpr bool CANCEL = true;
protected:
///> The default tool event handler.
@ -110,6 +116,7 @@ protected:
protected:
TOOL_MANAGER* m_toolManager;
std::map<int, bool> m_toolKinds;
std::map<int, bool> m_toolCancellable;
std::map<int, const TOOL_ACTION*> m_toolActions;
std::map<int, ACTION_MENU*> m_toolMenus;
};

View File

@ -179,6 +179,11 @@ public:
const std::map<std::string, TOOL_ACTION*>& GetActions();
/**
* Send a cancel event to the tool currently at the top of the tool stack.
*/
void CancelTool();
/**
* Function PrimeTool()
* "Primes" a tool by sending a cursor left-click event with the mouse position set

View File

@ -54,7 +54,7 @@ void PL_EDITOR_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( PL_ACTIONS::showInspector );

View File

@ -72,7 +72,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( PCB_ACTIONS::footprintProperties );

View File

@ -61,7 +61,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->Add( PCB_ACTIONS::zoomFootprintAutomatically, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->AddScaledSeparator( this );

View File

@ -256,7 +256,7 @@ void PCB_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->Add( ACTIONS::zoomInCenter );
m_mainToolBar->Add( ACTIONS::zoomOutCenter );
m_mainToolBar->Add( ACTIONS::zoomFitScreen );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE );
m_mainToolBar->Add( ACTIONS::zoomTool, ACTION_TOOLBAR::TOGGLE, ACTION_TOOLBAR::CANCEL );
m_mainToolBar->AddScaledSeparator( this );
m_mainToolBar->Add( ACTIONS::showFootprintEditor );