From 1f745b000d260411061c6e0fa5e32ec05f49e8ed 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 --- eeschema/tools/sch_drawing_tools.cpp | 33 +++++--- .../tools/symbol_editor_drawing_tools.cpp | 81 +++++++++++++------ 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 8f49232b8e..e5b8d9b0b0 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 @@ -1032,6 +1032,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; @@ -1096,10 +1097,18 @@ 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 || isClassLabel || isNetLabel ) ) ) + if( aEvent.HasPosition() ) { - m_toolMgr->RunAction( ACTIONS::cursorClick ); + m_toolMgr->PrimeTool( aEvent.Position() ); + } + else if( !aEvent.IsReactivate() && ( isText + || isGlobalLabel + || isHierLabel + || isClassLabel + || isNetLabel ) ) + { + m_toolMgr->PrimeTool( { 0, 0 } ); + ignorePrimePosition = true; } // Main loop: keep receiving events @@ -1220,11 +1229,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( cursorPos ); + item->SetFlags( IS_NEW | IS_MOVING ); item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); updatePreview(); @@ -1271,7 +1286,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { - item->SetPosition( (wxPoint) cursorPos ); + item->SetPosition( cursorPos ); 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 9f71c209bd..ee77421e38 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 @@ -68,12 +69,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 ); @@ -102,13 +107,20 @@ 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; + } // Set initial cursor setCursor(); @@ -117,8 +129,11 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) 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 ); if( evt->IsCancelInteractive() ) { @@ -134,12 +149,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 @@ -190,11 +219,17 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) wxFAIL_MSG( "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( VECTOR2I( cursorPos.x, -cursorPos.y ) ); + item->SetFlags( IS_NEW | IS_MOVING ); m_view->ClearPreview(); m_view->AddToPreview( item->Clone() ); @@ -204,7 +239,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 @@ -241,7 +276,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) } else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { - static_cast( item )->SetPosition( VECTOR2I( cursorPos.x, -cursorPos.y ) ); + item->SetPosition( VECTOR2I( cursorPos.x, -cursorPos.y ) ); m_view->ClearPreview(); m_view->AddToPreview( item->Clone() ); } @@ -251,12 +286,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; }