Special-case synthetic click after tool selection.

Fixes https://gitlab.com/kicad/code/kicad/issues/11057

(cherry picked from commit 1f745b000d)
This commit is contained in:
Jeff Young 2022-03-07 12:45:24 +00:00
parent d34faf30cc
commit dd55ffb75c
2 changed files with 80 additions and 31 deletions

View File

@ -22,9 +22,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "sch_drawing_tools.h" #include <tools/sch_drawing_tools.h>
#include "ee_selection_tool.h" #include <tools/ee_selection_tool.h>
#include "ee_grid_helper.h" #include <tools/ee_grid_helper.h>
#include <ee_actions.h> #include <ee_actions.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <project.h> #include <project.h>
@ -983,6 +983,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
SCH_ITEM* item = nullptr; SCH_ITEM* item = nullptr;
KIGFX::VIEW_CONTROLS* controls = getViewControls(); KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr ); EE_GRID_HELPER grid( m_toolMgr );
bool ignorePrimePosition = false;
if( m_inTwoClickPlace ) if( m_inTwoClickPlace )
return 0; return 0;
@ -1044,10 +1045,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
setCursor(); setCursor();
// Prime the pump if the tool isn't being re-activated // Prime the pump if the tool isn't being re-activated
if( aEvent.HasPosition() || ( !aEvent.IsReactivate() if( aEvent.HasPosition() )
&& ( isText || isGlobalLabel || isHierLabel || isNetLabel ) ) )
{ {
m_toolMgr->RunAction( ACTIONS::cursorClick ); m_toolMgr->PrimeTool( aEvent.Position() );
}
else if( !aEvent.IsReactivate() && ( isText
|| isGlobalLabel
|| isHierLabel
|| isNetLabel ) )
{
m_toolMgr->PrimeTool( { 0, 0 } );
ignorePrimePosition = true;
} }
// Main loop: keep receiving events // Main loop: keep receiving events
@ -1164,11 +1172,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
} }
} }
// Restore cursor after dialog // If we started with a click on a tool button or menu then continue with the
controls->WarpCursor( controls->GetCursorPosition(), true ); // current mouse position. Otherwise warp back to the original click position.
if( evt->IsPrime() && ignorePrimePosition )
cursorPos = grid.Align( controls->GetMousePosition() );
else
controls->WarpCursor( cursorPos, true );
if( item ) if( item )
{ {
item->SetPosition( (wxPoint) cursorPos );
item->SetFlags( IS_NEW | IS_MOVING ); item->SetFlags( IS_NEW | IS_MOVING );
item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
updatePreview(); updatePreview();

View File

@ -26,6 +26,7 @@
#include <symbol_edit_frame.h> #include <symbol_edit_frame.h>
#include <tools/symbol_editor_drawing_tools.h> #include <tools/symbol_editor_drawing_tools.h>
#include <tools/symbol_editor_pin_tool.h> #include <tools/symbol_editor_pin_tool.h>
#include <tools/ee_grid_helper.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <lib_text.h> #include <lib_text.h>
#include <dialogs/dialog_lib_text_properties.h> #include <dialogs/dialog_lib_text_properties.h>
@ -70,8 +71,12 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
KICAD_T type = aEvent.Parameter<KICAD_T>(); KICAD_T type = aEvent.Parameter<KICAD_T>();
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;
KIGFX::VIEW_CONTROLS* controls = getViewControls();
EE_GRID_HELPER grid( m_toolMgr );
VECTOR2I cursorPos; VECTOR2I cursorPos;
EDA_ITEM* item = nullptr; bool ignorePrimePosition = false;
LIB_ITEM* item = nullptr;
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText ); bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
@ -92,20 +97,30 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
Activate(); Activate();
// Must be done after Activate() so that it gets set into the correct context // Must be done after Activate() so that it gets set into the correct context
getViewControls()->ShowCursor( true ); controls->ShowCursor( true );
// Set initial cursor // Set initial cursor
setCursor(); setCursor();
// Prime the pump // Prime the pump
if( aEvent.HasPosition() || ( isText && !aEvent.IsReactivate() ) ) if( aEvent.HasPosition() )
m_toolMgr->RunAction( ACTIONS::cursorClick ); {
m_toolMgr->PrimeTool( aEvent.Position() );
}
else if( !aEvent.IsReactivate() && isText )
{
m_toolMgr->PrimeTool( { 0, 0 } );
ignorePrimePosition = true;
}
// Main loop: keep receiving events // Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
setCursor(); setCursor();
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() ); cursorPos = grid.Align( controls->GetMousePosition() );
controls->ForceCursorPosition( true, cursorPos );
auto cleanup = auto cleanup =
[&] () [&] ()
@ -130,12 +145,26 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
} }
else if( evt->IsActivate() ) else if( evt->IsActivate() )
{ {
if( item ) if( item && evt->IsMoveTool() )
cleanup(); {
// we're already moving our own item; ignore the move tool
if( evt->IsMoveTool() ) evt->SetPassEvent( false );
continue;
}
if( item )
{
m_frame->ShowInfoBarMsg( _( "Press <ESC> to cancel item creation." ) );
evt->SetPassEvent( false );
continue;
}
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{ {
// leave ourselves on the stack so we come back after the move
break; break;
} }
else else
@ -186,11 +215,17 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
wxFAIL_MSG( wxT( "TwoClickPlace(): unknown type" ) ); wxFAIL_MSG( wxT( "TwoClickPlace(): unknown type" ) );
} }
// Restore cursor after dialog // If we started with a click on a tool button or menu then continue with the
getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true ); // current mouse position. Otherwise warp back to the original click position.
if( evt->IsPrime() && ignorePrimePosition )
cursorPos = grid.Align( controls->GetMousePosition() );
else
controls->WarpCursor( cursorPos, true );
if( item ) if( item )
{ {
item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) );
item->SetFlags( IS_NEW | IS_MOVING ); item->SetFlags( IS_NEW | IS_MOVING );
m_view->ClearPreview(); m_view->ClearPreview();
m_view->AddToPreview( item->Clone() ); m_view->AddToPreview( item->Clone() );
@ -200,7 +235,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
setCursor(); setCursor();
} }
getViewControls()->SetCursorPosition( cursorPos, false ); controls->SetCursorPosition( cursorPos, false );
} }
// ... and second click places: // ... and second click places:
else else
@ -237,7 +272,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
} }
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) ) else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{ {
static_cast<LIB_ITEM*>( item )->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) ); item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) );
m_view->ClearPreview(); m_view->ClearPreview();
m_view->AddToPreview( item->Clone() ); m_view->AddToPreview( item->Clone() );
} }
@ -247,12 +282,12 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
} }
// Enable autopanning and cursor capture only when there is an item to be placed // Enable autopanning and cursor capture only when there is an item to be placed
getViewControls()->SetAutoPan( item != nullptr ); controls->SetAutoPan( item != nullptr );
getViewControls()->CaptureCursor( item != nullptr ); controls->CaptureCursor( item != nullptr );
} }
getViewControls()->SetAutoPan( false ); controls->SetAutoPan( false );
getViewControls()->CaptureCursor( false ); controls->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
return 0; return 0;
} }