Second tool hotkey accepts action (ie: acts as click).

Fixes https://gitlab.com/kicad/code/kicad/issues/11729
This commit is contained in:
Jeff Young 2022-06-09 16:53:24 +01:00
parent 35bde4710c
commit bce1fd337b
6 changed files with 98 additions and 23 deletions

View File

@ -214,6 +214,11 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = symbol
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_frame->GetInfoBar()->Dismiss(); m_frame->GetInfoBar()->Dismiss();
@ -228,7 +233,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( symbol && evt->IsMoveTool() ) if( symbol && evt->IsMoveTool() )
{ {
@ -255,7 +260,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
{ {
if( !symbol ) if( !symbol )
{ {
@ -466,6 +471,11 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
setCursor(); setCursor();
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = image
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_frame->GetInfoBar()->Dismiss(); m_frame->GetInfoBar()->Dismiss();
@ -486,7 +496,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( image && evt->IsMoveTool() ) if( image && evt->IsMoveTool() )
{ {
@ -513,7 +523,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
{ {
if( !image ) if( !image )
{ {
@ -1146,6 +1156,11 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
cursorPos = grid.BestSnapAnchor( cursorPos, snapLayer, item ); cursorPos = grid.BestSnapAnchor( cursorPos, snapLayer, item );
controls->ForceCursorPosition( true, cursorPos ); controls->ForceCursorPosition( true, cursorPos );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = item
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_frame->GetInfoBar()->Dismiss(); m_frame->GetInfoBar()->Dismiss();
@ -1160,7 +1175,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( item && evt->IsMoveTool() ) if( item && evt->IsMoveTool() )
{ {
@ -1190,7 +1205,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
{ {
// First click creates... // First click creates...
if( !item ) if( !item )
@ -1457,6 +1472,11 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = item
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
if( item ) if( item )
@ -1469,7 +1489,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( item && evt->IsMoveTool() ) if( item && evt->IsMoveTool() )
{ {
@ -1531,6 +1551,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
} }
else if( item && ( evt->IsClick( BUT_LEFT ) else if( item && ( evt->IsClick( BUT_LEFT )
|| evt->IsDblClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &EE_ACTIONS::finishDrawing ) ) ) || evt->IsAction( &EE_ACTIONS::finishDrawing ) ) )
{ {
if( evt->IsDblClick( BUT_LEFT ) if( evt->IsDblClick( BUT_LEFT )
@ -1656,6 +1677,11 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = sheet
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_frame->GetInfoBar()->Dismiss(); m_frame->GetInfoBar()->Dismiss();
@ -1670,7 +1696,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( sheet && evt->IsMoveTool() ) if( sheet && evt->IsMoveTool() )
{ {
@ -1739,6 +1765,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
} }
else if( sheet && ( evt->IsClick( BUT_LEFT ) else if( sheet && ( evt->IsClick( BUT_LEFT )
|| evt->IsDblClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &EE_ACTIONS::finishSheet ) ) ) || evt->IsAction( &EE_ACTIONS::finishSheet ) ) )
{ {
m_view->ClearPreview(); m_view->ClearPreview();

View File

@ -630,7 +630,12 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
LINE_MODE currentMode = (LINE_MODE) m_frame->eeconfig()->m_Drawing.line_mode; LINE_MODE currentMode = (LINE_MODE) m_frame->eeconfig()->m_Drawing.line_mode;
bool twoSegments = currentMode != LINE_MODE::LINE_MODE_FREE; bool twoSegments = currentMode != LINE_MODE::LINE_MODE_FREE;
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = ( segment || m_busUnfold.in_progress )
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( aTool ) == 0;
setCursor(); setCursor();
grid.SetMask( GRID_HELPER::ALL ); grid.SetMask( GRID_HELPER::ALL );
@ -656,8 +661,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
if( currentMode != lastMode ) if( currentMode != lastMode )
{ {
// Need to delete extra segment if we have one // Need to delete extra segment if we have one
if( currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() >= 2 if( segment && currentMode == LINE_MODE::LINE_MODE_FREE && m_wires.size() >= 2 )
&& segment != nullptr )
{ {
m_wires.pop_back(); m_wires.pop_back();
m_selectionTool->RemoveItemFromSel( segment ); m_selectionTool->RemoveItemFromSel( segment );
@ -667,7 +671,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
segment->SetEndPoint( cursorPos ); segment->SetEndPoint( cursorPos );
} }
// Add a segment so we can move orthogonally/45 // Add a segment so we can move orthogonally/45
else if( lastMode == LINE_MODE::LINE_MODE_FREE && segment ) else if( segment && lastMode == LINE_MODE::LINE_MODE_FREE )
{ {
segment->SetEndPoint( cursorPos ); segment->SetEndPoint( cursorPos );
@ -683,7 +687,6 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
lastMode = currentMode; lastMode = currentMode;
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle cancel: // Handle cancel:
// //
@ -701,7 +704,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( segment || m_busUnfold.in_progress ) if( segment || m_busUnfold.in_progress )
{ {
@ -744,7 +747,9 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( const std::string& aTool, int aType,
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle click: // Handle click:
// //
else if( evt->IsClick( BUT_LEFT ) || ( segment && evt->IsDblClick( BUT_LEFT ) ) ) else if( evt->IsClick( BUT_LEFT )
|| ( segment && evt->IsDblClick( BUT_LEFT ) )
|| isSyntheticClick )
{ {
// First click when unfolding places the label and wire-to-bus entry // First click when unfolding places the label and wire-to-bus entry
if( m_busUnfold.in_progress && !m_busUnfold.label_placed ) if( m_busUnfold.in_progress && !m_busUnfold.label_placed )

View File

@ -123,6 +123,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::restartMove ); m_toolMgr->RunAction( EE_ACTIONS::restartMove );
} }
} }
else
{
// The tool hotkey is interpreted as a click when already dragging/moving
m_toolMgr->RunAction( ACTIONS::cursorClick );
}
return 0; return 0;
} }
@ -387,7 +392,9 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
splitMoves.emplace_back( VECTOR2I( delta.x + m_moveOffset.x, 0 ) ); splitMoves.emplace_back( VECTOR2I( delta.x + m_moveOffset.x, 0 ) );
} }
else else
{
splitMoves.emplace_back( VECTOR2I( delta.x, 0 ) ); splitMoves.emplace_back( VECTOR2I( delta.x, 0 ) );
}
if( alg::signbit( m_moveOffset.y ) != alg::signbit( ( m_moveOffset + delta ).y ) ) if( alg::signbit( m_moveOffset.y ) != alg::signbit( ( m_moveOffset + delta ).y ) )
{ {
@ -395,7 +402,9 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
splitMoves.emplace_back( VECTOR2I( 0, delta.y + m_moveOffset.y ) ); splitMoves.emplace_back( VECTOR2I( 0, delta.y + m_moveOffset.y ) );
} }
else else
{
splitMoves.emplace_back( VECTOR2I( 0, delta.y ) ); splitMoves.emplace_back( VECTOR2I( 0, delta.y ) );
}
m_moveOffset += delta; m_moveOffset += delta;

View File

@ -50,7 +50,9 @@ SYMBOL_EDITOR_DRAWING_TOOLS::SYMBOL_EDITOR_DRAWING_TOOLS() :
m_lastFillColor( COLOR4D::UNSPECIFIED ), m_lastFillColor( COLOR4D::UNSPECIFIED ),
m_lastStroke( 0, PLOT_DASH_TYPE::DEFAULT, COLOR4D::UNSPECIFIED ), m_lastStroke( 0, PLOT_DASH_TYPE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_drawSpecificConvert( true ), m_drawSpecificConvert( true ),
m_drawSpecificUnit( false ) m_drawSpecificUnit( false ),
m_inDrawShape( false ),
m_inTwoClickPlace( false )
{ {
} }
@ -78,6 +80,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>(); auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool<SYMBOL_EDITOR_PIN_TOOL>() : nullptr; auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool<SYMBOL_EDITOR_PIN_TOOL>() : nullptr;
if( m_inTwoClickPlace )
return 0;
REENTRANCY_GUARD guard( &m_inTwoClickPlace );
KIGFX::VIEW_CONTROLS* controls = getViewControls(); KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr ); EE_GRID_HELPER grid( m_toolMgr );
VECTOR2I cursorPos; VECTOR2I cursorPos;
@ -137,6 +144,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
cursorPos = grid.Align( controls->GetMousePosition() ); cursorPos = grid.Align( controls->GetMousePosition() );
controls->ForceCursorPosition( true, cursorPos ); controls->ForceCursorPosition( true, cursorPos );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = item
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
m_frame->GetInfoBar()->Dismiss(); m_frame->GetInfoBar()->Dismiss();
@ -151,7 +163,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( item && evt->IsMoveTool() ) if( item && evt->IsMoveTool() )
{ {
@ -181,7 +193,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) || isSyntheticClick )
{ {
LIB_SYMBOL* symbol = m_frame->GetCurSymbol(); LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
@ -318,6 +330,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
LIB_SHAPE* item = nullptr; LIB_SHAPE* item = nullptr;
bool isTextBox = aEvent.IsAction( &EE_ACTIONS::drawSymbolTextBox ); bool isTextBox = aEvent.IsAction( &EE_ACTIONS::drawSymbolTextBox );
if( m_inDrawShape )
return 0;
REENTRANCY_GUARD guard( &m_inDrawShape );
// We might be running as the same shape in another co-routine. Make sure that one // We might be running as the same shape in another co-routine. Make sure that one
// gets whacked. // gets whacked.
m_toolMgr->DeactivateTool(); m_toolMgr->DeactivateTool();
@ -358,6 +375,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
// The tool hotkey is interpreted as a click when drawing
bool isSyntheticClick = item
&& evt->IsActivate() && evt->HasPosition()
&& evt->GetCommandStr().get().compare( tool ) == 0;
if( evt->IsCancelInteractive() ) if( evt->IsCancelInteractive() )
{ {
if( item ) if( item )
@ -370,7 +392,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
break; break;
} }
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() && !isSyntheticClick )
{ {
if( item ) if( item )
cleanup(); cleanup();
@ -434,7 +456,9 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
m_selectionTool->AddItemToSel( item ); m_selectionTool->AddItemToSel( item );
} }
else if( item && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) else if( item && ( evt->IsClick( BUT_LEFT )
|| evt->IsDblClick( BUT_LEFT )
|| isSyntheticClick
|| evt->IsAction( &EE_ACTIONS::finishDrawing ) ) ) || evt->IsAction( &EE_ACTIONS::finishDrawing ) ) )
{ {
if( symbol != m_frame->GetCurSymbol() ) if( symbol != m_frame->GetCurSymbol() )

View File

@ -74,6 +74,10 @@ private:
STROKE_PARAMS m_lastStroke; STROKE_PARAMS m_lastStroke;
bool m_drawSpecificConvert; bool m_drawSpecificConvert;
bool m_drawSpecificUnit; bool m_drawSpecificUnit;
///< Re-entrancy guards
bool m_inDrawShape;
bool m_inTwoClickPlace;
}; };
#endif /* SYMBOL_EDITOR_DRAWING_TOOLS_H */ #endif /* SYMBOL_EDITOR_DRAWING_TOOLS_H */

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -25,7 +25,6 @@
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/ee_selection_tool.h> #include <tools/ee_selection_tool.h>
#include <ee_actions.h> #include <ee_actions.h>
#include <bitmaps.h>
#include <eda_item.h> #include <eda_item.h>
#include <wx/log.h> #include <wx/log.h>
#include "symbol_editor_move_tool.h" #include "symbol_editor_move_tool.h"
@ -103,9 +102,16 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
: m_selectionTool->RequestSelection(); : m_selectionTool->RequestSelection();
bool unselect = selection.IsHover(); bool unselect = selection.IsHover();
if( !m_frame->IsSymbolEditable() || selection.Empty() || m_moveInProgress ) if( !m_frame->IsSymbolEditable() || selection.Empty() )
return 0; return 0;
if( m_moveInProgress )
{
// The tool hotkey is interpreted as a click when already moving
m_toolMgr->RunAction( ACTIONS::cursorClick );
return 0;
}
std::string tool = aEvent.GetCommandStr().get(); std::string tool = aEvent.GetCommandStr().get();
m_frame->PushTool( tool ); m_frame->PushTool( tool );