From dd55ffb75c929e7521d537ebb69e5b62a484d18e Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 7 Mar 2022 12:45:24 +0000 Subject: [PATCH] Special-case synthetic click after tool selection. Fixes https://gitlab.com/kicad/code/kicad/issues/11057 (cherry picked from commit 1f745b000d260411061c6e0fa5e32ec05f49e8ed) --- eeschema/tools/sch_drawing_tools.cpp | 30 +++++-- .../tools/symbol_editor_drawing_tools.cpp | 81 +++++++++++++------ 2 files changed, 80 insertions(+), 31 deletions(-) diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 741918de1f..2b64ef8008 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -22,9 +22,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "sch_drawing_tools.h" -#include "ee_selection_tool.h" -#include "ee_grid_helper.h" +#include +#include +#include #include #include #include @@ -983,6 +983,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) SCH_ITEM* item = nullptr; KIGFX::VIEW_CONTROLS* controls = getViewControls(); EE_GRID_HELPER grid( m_toolMgr ); + bool ignorePrimePosition = false; if( m_inTwoClickPlace ) return 0; @@ -1044,10 +1045,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) setCursor(); // Prime the pump if the tool isn't being re-activated - if( aEvent.HasPosition() || ( !aEvent.IsReactivate() - && ( isText || isGlobalLabel || isHierLabel || isNetLabel ) ) ) + if( aEvent.HasPosition() ) { - 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 @@ -1164,11 +1172,17 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } } - // Restore cursor after dialog - controls->WarpCursor( controls->GetCursorPosition(), true ); + // If we started with a click on a tool button or menu then continue with the + // 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 ) { + item->SetPosition( (wxPoint) cursorPos ); + item->SetFlags( IS_NEW | IS_MOVING ); item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); updatePreview(); diff --git a/eeschema/tools/symbol_editor_drawing_tools.cpp b/eeschema/tools/symbol_editor_drawing_tools.cpp index db0ec6a7e0..db8476637b 100644 --- a/eeschema/tools/symbol_editor_drawing_tools.cpp +++ b/eeschema/tools/symbol_editor_drawing_tools.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -67,12 +68,16 @@ bool SYMBOL_EDITOR_DRAWING_TOOLS::Init() int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) { - KICAD_T type = aEvent.Parameter(); - auto* settings = Pgm().GetSettingsManager().GetAppSettings(); - auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool() : nullptr; - VECTOR2I cursorPos; - EDA_ITEM* item = nullptr; - bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText ); + KICAD_T type = aEvent.Parameter(); + auto* settings = Pgm().GetSettingsManager().GetAppSettings(); + auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool() : nullptr; + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + EE_GRID_HELPER grid( m_toolMgr ); + VECTOR2I cursorPos; + bool ignorePrimePosition = false; + LIB_ITEM* item = nullptr; + bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); @@ -92,20 +97,30 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) Activate(); // Must be done after Activate() so that it gets set into the correct context - getViewControls()->ShowCursor( true ); + controls->ShowCursor( true ); // Set initial cursor setCursor(); // Prime the pump - if( aEvent.HasPosition() || ( isText && !aEvent.IsReactivate() ) ) - m_toolMgr->RunAction( ACTIONS::cursorClick ); + if( aEvent.HasPosition() ) + { + m_toolMgr->PrimeTool( aEvent.Position() ); + } + else if( !aEvent.IsReactivate() && isText ) + { + m_toolMgr->PrimeTool( { 0, 0 } ); + ignorePrimePosition = true; + } // Main loop: keep receiving events while( TOOL_EVENT* evt = Wait() ) { 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 = [&] () @@ -130,12 +145,26 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } else if( evt->IsActivate() ) { - if( item ) - cleanup(); - - if( evt->IsMoveTool() ) + if( item && evt->IsMoveTool() ) + { + // we're already moving our own item; ignore the move tool + evt->SetPassEvent( false ); + continue; + } + + if( item ) + { + m_frame->ShowInfoBarMsg( _( "Press 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; } else @@ -186,11 +215,17 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) wxFAIL_MSG( wxT( "TwoClickPlace(): unknown type" ) ); } - // Restore cursor after dialog - getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true ); + // If we started with a click on a tool button or menu then continue with the + // 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 ) { + item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) ); + item->SetFlags( IS_NEW | IS_MOVING ); m_view->ClearPreview(); m_view->AddToPreview( item->Clone() ); @@ -200,7 +235,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) setCursor(); } - getViewControls()->SetCursorPosition( cursorPos, false ); + controls->SetCursorPosition( cursorPos, false ); } // ... and second click places: else @@ -237,7 +272,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { - static_cast( item )->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) ); + item->SetPosition( wxPoint( cursorPos.x, -cursorPos.y ) ); m_view->ClearPreview(); 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 - getViewControls()->SetAutoPan( item != nullptr ); - getViewControls()->CaptureCursor( item != nullptr ); + controls->SetAutoPan( item != nullptr ); + controls->CaptureCursor( item != nullptr ); } - getViewControls()->SetAutoPan( false ); - getViewControls()->CaptureCursor( false ); + controls->SetAutoPan( false ); + controls->CaptureCursor( false ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW ); return 0; }