Special-case synthetic click after tool selection.

Fixes https://gitlab.com/kicad/code/kicad/issues/11057
This commit is contained in:
Jeff Young 2022-03-07 12:45:24 +00:00
parent a9ebb42ecd
commit 1f745b000d
2 changed files with 82 additions and 32 deletions

View File

@ -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 <tools/sch_drawing_tools.h>
#include <tools/ee_selection_tool.h>
#include <tools/ee_grid_helper.h>
#include <ee_actions.h>
#include <sch_edit_frame.h>
#include <project.h>
@ -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();
}

View File

@ -26,6 +26,7 @@
#include <symbol_edit_frame.h>
#include <tools/symbol_editor_drawing_tools.h>
#include <tools/symbol_editor_pin_tool.h>
#include <tools/ee_grid_helper.h>
#include <lib_text.h>
#include <dialogs/dialog_lib_text_properties.h>
#include <lib_shape.h>
@ -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<KICAD_T>();
auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
auto* pinTool = type == LIB_PIN_T ? m_toolMgr->GetTool<SYMBOL_EDITOR_PIN_TOOL>() : nullptr;
VECTOR2I cursorPos;
EDA_ITEM* item = nullptr;
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSymbolText );
KICAD_T type = aEvent.Parameter<KICAD_T>();
auto* settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
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;
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 <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;
}
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<LIB_ITEM*>( 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;
}