From 2f23aa9556ac59349fd4b6739e20312812b5e58c Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Thu, 27 Jun 2019 12:47:24 +0100 Subject: [PATCH] Implement a more robust tool stacking architecture. We were running into various corner conditions where a tool's event loop would exit while the tool was still active, or the tool would get popped while we were still in the event loop. (A lot of these had to do with the POINT_EDITOR's, but not all of them.) The new architecture: 1) tools always do a Push()/Pop() 2) everyone is responsible for their own pops; no more stack-clearing on a cancel 3) CancelInteractive events go to all tools to facilitate (2) --- common/eda_draw_frame.cpp | 16 ---- common/tool/common_tools.cpp | 17 ++++ common/tool/tool_event.cpp | 29 +++++- common/tool/tool_manager.cpp | 2 +- common/tool/zoom_tool.cpp | 7 +- cvpcb/tools/cvpcb_selection_tool.cpp | 8 +- eeschema/tools/ee_point_editor.cpp | 8 -- eeschema/tools/ee_selection_tool.cpp | 11 --- eeschema/tools/ee_selection_tool.h | 5 - eeschema/tools/lib_drawing_tools.cpp | 34 +++---- eeschema/tools/lib_edit_tool.cpp | 6 +- eeschema/tools/sch_drawing_tools.cpp | 61 ++++-------- eeschema/tools/sch_edit_tool.cpp | 3 - eeschema/tools/sch_editor_control.cpp | 1 + eeschema/tools/sch_line_wire_bus_tool.cpp | 9 +- gerbview/tools/gerbview_selection_tool.cpp | 10 +- include/eda_draw_frame.h | 6 -- include/tool/common_tools.h | 2 + include/tool/tool_event.h | 35 ++++--- pagelayout_editor/tools/pl_drawing_tools.cpp | 24 ++--- pagelayout_editor/tools/pl_edit_tool.cpp | 9 +- pagelayout_editor/tools/pl_point_editor.cpp | 4 - pagelayout_editor/tools/pl_selection_tool.cpp | 2 +- pcbnew/router/length_tuner_tool.cpp | 3 +- pcbnew/router/router_tool.cpp | 8 +- pcbnew/tools/drawing_tool.cpp | 94 +++++++++---------- pcbnew/tools/edit_tool.cpp | 7 +- pcbnew/tools/footprint_editor_tools.cpp | 3 +- pcbnew/tools/microwave_tool.cpp | 8 +- pcbnew/tools/pad_tool.cpp | 24 +++-- pcbnew/tools/pcb_editor_control.cpp | 40 +++----- pcbnew/tools/pcb_tool_base.cpp | 16 +--- pcbnew/tools/pcbnew_control.cpp | 10 +- pcbnew/tools/point_editor.cpp | 4 - pcbnew/tools/selection_tool.cpp | 18 +--- pcbnew/tools/selection_tool.h | 2 - pcbnew/tools/zone_create_helper.cpp | 6 +- 37 files changed, 227 insertions(+), 325 deletions(-) diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index 121f4670f3..e32450587e 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -424,15 +424,6 @@ void EDA_DRAW_FRAME::OnSize( wxSizeEvent& SizeEv ) } -void EDA_DRAW_FRAME::SetTool( const std::string& actionName ) -{ - if( !m_toolStack.empty() ) - m_toolStack.pop_back(); - - PushTool( actionName ); -} - - void EDA_DRAW_FRAME::PushTool( const std::string& actionName ) { m_toolStack.push_back( actionName ); @@ -474,13 +465,6 @@ void EDA_DRAW_FRAME::PopTool() } -void EDA_DRAW_FRAME::ClearToolStack() -{ - m_toolStack.clear(); - DisplayToolMsg( ACTIONS::selectionTool.GetName() ); -} - - bool EDA_DRAW_FRAME::IsCurrentTool( const TOOL_ACTION& aAction ) { if( m_toolStack.empty() ) diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp index 9c1ec3de61..98196cb983 100644 --- a/common/tool/common_tools.cpp +++ b/common/tool/common_tools.cpp @@ -43,6 +43,21 @@ void COMMON_TOOLS::Reset( RESET_REASON aReason ) } +int COMMON_TOOLS::SelectionTool( const TOOL_EVENT& aEvent ) +{ + // Since selection tools are run permanently underneath the toolStack, this is really + // just a cancel of whatever other tools might be running. + + m_toolMgr->ProcessEvent( TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ) ); + + // Shouldn't be necessary, but as the Irish would say: "just to be sure to be sure" + while( !m_frame->ToolStackIsEmpty() ) + m_frame->PopTool(); + + return 0; +} + + // Cursor control int COMMON_TOOLS::CursorControl( const TOOL_EVENT& aEvent ) { @@ -511,6 +526,8 @@ int COMMON_TOOLS::SwitchCanvas( const TOOL_EVENT& aEvent ) void COMMON_TOOLS::setTransitions() { + Go( &COMMON_TOOLS::SelectionTool, ACTIONS::selectionTool.MakeEvent() ); + // Cursor control Go( &COMMON_TOOLS::CursorControl, ACTIONS::cursorUp.MakeEvent() ); Go( &COMMON_TOOLS::CursorControl, ACTIONS::cursorDown.MakeEvent() ); diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 762b214410..7ad3d3741f 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -51,6 +51,15 @@ static const std::string flag2string( int aFlag, const FlagString* aExps ) } +void TOOL_EVENT::init() +{ + // By default only MESSAGEs and Cancels are passed to multiple recipients + m_passEvent = m_category == TC_MESSAGE || TOOL_EVT_UTILS::IsCancelInteractive( *this ); + + m_hasPosition = ( m_category == TC_MOUSE || m_category == TC_COMMAND ); +} + + bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const { return Matches( aAction->MakeEvent() ); @@ -176,7 +185,13 @@ bool TOOL_EVENT::IsDblClick( int aButtonMask ) const bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt ) { - return aEvt.IsAction( &ACTIONS::cancelInteractive ) || aEvt.IsCancel(); + if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get() == ACTIONS::cancelInteractive.GetName() ) + return true; + + if( aEvt.GetCommandId() && aEvt.GetCommandId().get() == ACTIONS::cancelInteractive.GetId() ) + return true; + + return aEvt.IsCancel(); } @@ -188,3 +203,15 @@ bool TOOL_EVT_UTILS::IsSelectionEvent( const TOOL_EVENT& aEvt ) } +bool TOOL_EVT_UTILS::IsPointEditor( const TOOL_EVENT& aEvt ) +{ + if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get().find( "PointEditor" ) >= 0 ) + return true; + + if( aEvt.GetCommandId() && aEvt.GetCommandId() == ACTIONS::activatePointEditor.GetId() ) + return true; + + return false; +} + + diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 194556cb9d..93fd69e994 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -763,7 +763,7 @@ TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState ) if( tool->GetType() == INTERACTIVE ) static_cast<TOOL_INTERACTIVE*>( tool )->resetTransitions(); - return it; + return --it; } diff --git a/common/tool/zoom_tool.cpp b/common/tool/zoom_tool.cpp index 2d7737864a..4b4557da7f 100644 --- a/common/tool/zoom_tool.cpp +++ b/common/tool/zoom_tool.cpp @@ -51,12 +51,7 @@ int ZOOM_TOOL::Main( const TOOL_EVENT& aEvent ) while( auto evt = Wait() ) { if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) - { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_frame->ClearToolStack(); - break; - } else if( evt->IsDrag( BUT_LEFT ) || evt->IsDrag( BUT_RIGHT ) ) { @@ -87,7 +82,7 @@ bool ZOOM_TOOL::selectRegion() while( auto evt = Wait() ) { - if( evt->IsCancel() || evt->IsActivate() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { cancelled = true; break; diff --git a/cvpcb/tools/cvpcb_selection_tool.cpp b/cvpcb/tools/cvpcb_selection_tool.cpp index f97380a3e7..34356d8c0c 100644 --- a/cvpcb/tools/cvpcb_selection_tool.cpp +++ b/cvpcb/tools/cvpcb_selection_tool.cpp @@ -105,7 +105,7 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) auto& controls = *getViewControls(); auto previous_settings = controls.GetSettings(); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr; @@ -124,7 +124,7 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) { const VECTOR2I cursorPos = controls.GetCursorPosition(); - if( evt->IsCancel() || evt->IsActivate() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { if( originSet ) { @@ -135,7 +135,6 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - m_frame->ClearToolStack(); break; } @@ -195,9 +194,8 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) view.SetVisible( &ruler, false ); view.Remove( &ruler ); - controls.ApplySettings( previous_settings ); - + m_frame->PopTool(); return 0; } diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp index 467fbadd36..81aac1cc51 100644 --- a/eeschema/tools/ee_point_editor.cpp +++ b/eeschema/tools/ee_point_editor.cpp @@ -282,10 +282,6 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent ) controls->ShowCursor( true ); m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame ); - - if( !m_editPoints ) - return 0; - view->Add( m_editPoints.get() ); setEditedPoint( nullptr ); bool inDrag = false; @@ -331,10 +327,6 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent ) modified = false; } - // ESC should clear selection along with edit points - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - break; } diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 25dd419c9d..083b48987c 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -260,15 +260,6 @@ int EE_SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent ) } -int EE_SELECTION_TOOL::SelectionTool( const TOOL_EVENT& aEvent ) -{ - // Since the selection tool is always running underneath the toolStack, all we need to - // do is clear the stack. - m_frame->ClearToolStack(); - return 0; -} - - int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { const KICAD_T movableItems[] = @@ -409,7 +400,6 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { ClearSelection(); - m_toolMgr->RunAction( EE_ACTIONS::clearHighlight, true ); } else if( evt->Action() == TA_UNDO_REDO_PRE ) @@ -1299,7 +1289,6 @@ void EE_SELECTION_TOOL::setTransitions() Go( &EE_SELECTION_TOOL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() ); Go( &EE_SELECTION_TOOL::Main, EE_ACTIONS::selectionActivate.MakeEvent() ); - Go( &EE_SELECTION_TOOL::SelectionTool, ACTIONS::selectionTool.MakeEvent() ); Go( &EE_SELECTION_TOOL::SelectNode, EE_ACTIONS::selectNode.MakeEvent() ); Go( &EE_SELECTION_TOOL::SelectConnection, EE_ACTIONS::selectConnection.MakeEvent() ); Go( &EE_SELECTION_TOOL::ClearSelection, EE_ACTIONS::clearSelection.MakeEvent() ); diff --git a/eeschema/tools/ee_selection_tool.h b/eeschema/tools/ee_selection_tool.h index f08fa31cba..e3739819c4 100644 --- a/eeschema/tools/ee_selection_tool.h +++ b/eeschema/tools/ee_selection_tool.h @@ -74,11 +74,6 @@ public: */ int Main( const TOOL_EVENT& aEvent ); - /* - * Main() is always running, so this just clears the frame's tool stack. - */ - int SelectionTool( const TOOL_EVENT& aEvent ); - /** * Function GetSelection() * diff --git a/eeschema/tools/lib_drawing_tools.cpp b/eeschema/tools/lib_drawing_tools.cpp index 2b6fc69835..e4b7a4caad 100644 --- a/eeschema/tools/lib_drawing_tools.cpp +++ b/eeschema/tools/lib_drawing_tools.cpp @@ -76,7 +76,7 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -97,13 +97,9 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) delete item; item = nullptr; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -210,6 +206,7 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + m_frame->PopTool(); return 0; } @@ -225,7 +222,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); LIB_PART* part = m_frame->GetCurPart(); @@ -242,24 +239,20 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { - m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - m_view->ClearPreview(); - if( item ) { + m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); + m_view->ClearPreview(); delete item; item = nullptr; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } - if( evt->IsActivate() ) + // Continue on if it's just the point editor; otherwise give way to new tool + if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) break; } @@ -341,6 +334,7 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + m_frame->PopTool(); return 0; } @@ -350,7 +344,7 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent ) getViewControls()->ShowCursor( true ); getViewControls()->SetSnapping( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Main loop: keep receiving events @@ -386,7 +380,7 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent ) } } - m_frame->ClearToolStack(); + m_frame->PopTool(); return 0; } diff --git a/eeschema/tools/lib_edit_tool.cpp b/eeschema/tools/lib_edit_tool.cpp index 7829b04656..e8ae85d1fb 100644 --- a/eeschema/tools/lib_edit_tool.cpp +++ b/eeschema/tools/lib_edit_tool.cpp @@ -282,7 +282,7 @@ int LIB_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); EE_PICKER_TOOL* picker = m_toolMgr->GetTool<EE_PICKER_TOOL>(); @@ -327,14 +327,12 @@ int LIB_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { if( m_pickerItem ) m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem ); - - if( aFinalState == EE_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); } ); picker->Activate(); Wait(); + m_frame->PopTool(); return 0; } diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index 8b3a335027..27a76fc39f 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -99,7 +99,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) m_selectionTool->AddItemToSel( component ); } - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -125,13 +125,9 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) delete component; component = nullptr; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -212,6 +208,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( component != nullptr ); } + m_frame->PopTool(); return 0; } @@ -220,13 +217,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) { SCH_BITMAP* image = aEvent.Parameter<SCH_BITMAP*>(); bool immediateMode = image; - - if( immediateMode ) - m_frame->PushTool( aEvent.GetCommandStr().get() ); - else - m_frame->SetTool( aEvent.GetCommandStr().get() ); - - VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); @@ -239,6 +230,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) m_view->AddToPreview( image->Clone() ); } + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -264,13 +256,9 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) if( immediateMode ) break; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -348,9 +336,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( image != nullptr ); } - if( immediateMode ) - m_frame->PopTool(); - + m_frame->PopTool(); return 0; } @@ -383,7 +369,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) getViewControls()->ShowCursor( true ); getViewControls()->SetSnapping( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -397,9 +383,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_frame->ClearToolStack(); - break; } else if( evt->IsClick( BUT_LEFT ) ) @@ -445,6 +428,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent ) } } + m_frame->PopTool(); return 0; } @@ -458,7 +442,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -479,13 +463,9 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) delete item; item = nullptr; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -616,6 +596,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + m_frame->PopTool(); return 0; } @@ -627,8 +608,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); - + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -650,13 +630,9 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) delete sheet; sheet = nullptr; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -717,6 +693,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( sheet != nullptr); } + m_frame->PopTool(); return 0; } diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 55cab74fa9..772b5d87bb 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -999,9 +999,6 @@ int SCH_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { if( m_pickerItem ) m_toolMgr->GetTool<EE_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem ); - - if( aFinalState == EE_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); } ); picker->Activate(); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 17fe3475a6..bf7fd4bc6c 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -1170,6 +1170,7 @@ void SCH_EDITOR_CONTROL::setTransitions() Go( &SCH_EDITOR_CONTROL::HighlightNetCursor, EE_ACTIONS::highlightNetCursor.MakeEvent() ); Go( &SCH_EDITOR_CONTROL::UpdateNetHighlighting, EVENTS::SelectedItemsModified ); Go( &SCH_EDITOR_CONTROL::UpdateNetHighlighting, EE_ACTIONS::updateNetHighlighting.MakeEvent() ); + Go( &SCH_EDITOR_CONTROL::ClearHighlight, ACTIONS::cancelInteractive.MakeEvent() ); Go( &SCH_EDITOR_CONTROL::Undo, ACTIONS::undo.MakeEvent() ); Go( &SCH_EDITOR_CONTROL::Redo, ACTIONS::redo.MakeEvent() ); diff --git a/eeschema/tools/sch_line_wire_bus_tool.cpp b/eeschema/tools/sch_line_wire_bus_tool.cpp index 848eaac073..74521c7eaa 100644 --- a/eeschema/tools/sch_line_wire_bus_tool.cpp +++ b/eeschema/tools/sch_line_wire_bus_tool.cpp @@ -257,14 +257,18 @@ int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent ) if( aEvent.HasPosition() ) getViewControls()->WarpCursor( getViewControls()->GetCursorPosition(), true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); if( aEvent.HasPosition() ) { VECTOR2D cursorPos = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ); segment = startSegments( layer, cursorPos ); } - return doDrawSegments( layer, segment ); + + doDrawSegments( layer, segment ); + + m_frame->PopTool(); + return 0; } @@ -477,7 +481,6 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - m_frame->ClearToolStack(); break; } diff --git a/gerbview/tools/gerbview_selection_tool.cpp b/gerbview/tools/gerbview_selection_tool.cpp index 0b66fe7cad..fcead36210 100644 --- a/gerbview/tools/gerbview_selection_tool.cpp +++ b/gerbview/tools/gerbview_selection_tool.cpp @@ -352,7 +352,7 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple() while( TOOL_EVENT* evt = Wait() ) { - if( evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { cancelled = true; break; @@ -754,7 +754,7 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) auto& controls = *getViewControls(); auto previous_settings = controls.GetSettings(); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPtMgr; @@ -773,7 +773,7 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) { const VECTOR2I cursorPos = controls.GetCursorPosition(); - if( evt->IsCancel() || evt->IsActivate() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { if( originSet ) { @@ -784,7 +784,6 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - m_frame->ClearToolStack(); break; } @@ -844,9 +843,8 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) view.SetVisible( &ruler, false ); view.Remove( &ruler ); - controls.ApplySettings( previous_settings ); - + m_frame->PopTool(); return 0; } diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h index 7b7bfc0d63..d157c03c1d 100644 --- a/include/eda_draw_frame.h +++ b/include/eda_draw_frame.h @@ -307,14 +307,8 @@ public: * a single TOOL_BASE derived class to implement several user "tools", such as rectangle * and circle, or wire and bus. So each user-level tool is actually a TOOL_ACTION. */ - virtual void SetTool( const std::string& actionName ); virtual void PushTool( const std::string& actionName ); virtual void PopTool(); - /** - * The selection tool runs underneath the tool stack, so clearing the stack is equivalent - * to selecting the selection tool. - */ - virtual void ClearToolStack(); bool ToolStackIsEmpty() { return m_toolStack.empty(); } diff --git a/include/tool/common_tools.h b/include/tool/common_tools.h index a6217d096e..a7593ad5db 100644 --- a/include/tool/common_tools.h +++ b/include/tool/common_tools.h @@ -48,6 +48,8 @@ public: /// @copydoc TOOL_BASE::Reset() void Reset( RESET_REASON aReason ) override; + int SelectionTool( const TOOL_EVENT& aEvent ); + // View controls int ZoomRedraw( const TOOL_EVENT& aEvent ); int ZoomInOut( const TOOL_EVENT& aEvent ); diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index d886e0953c..b3b8ac05f9 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -185,10 +185,7 @@ public: m_modifiers( 0 ), m_param( aParameter ) { - m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND ); - - // By default only MESSAGEs are passed to multiple recipients - m_passEvent = ( aCategory == TC_MESSAGE ); + init(); } TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam, @@ -219,10 +216,7 @@ public: m_modifiers = aExtraParam & MD_MODIFIER_MASK; } - // By default only MESSAGEs are passed to multiple recipients - m_passEvent = ( aCategory == TC_MESSAGE ); - - m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND ); + init(); } TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, @@ -239,10 +233,7 @@ public: if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE ) m_commandStr = aExtraParam; - // By default only MESSAGEs are passed to multiple recipients - m_passEvent = ( aCategory == TC_MESSAGE ); - - m_hasPosition = ( aCategory == TC_MOUSE || aCategory == TC_COMMAND ); + init(); } ///> Returns the category (eg. mouse/keyboard/action) of an event.. @@ -431,6 +422,8 @@ public: private: friend class TOOL_DISPATCHER; + void init(); + void setMouseDragOrigin( const VECTOR2D& aP ) { m_mouseDragOrigin = aP; @@ -648,18 +641,17 @@ inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent, /** * Namespace TOOL_EVT_UTILS * - * Utility functions for dealing with various tool events. These are - * free functions, so they interface with any classes exclusively via - * the public interfaces, so they don't need to be subsumed into the - * "helped" classes. + * Utility functions for dealing with various tool events. These are free functions, so they + * interface with any classes exclusively via the public interfaces, so they don't need to be + * subsumed into the "helped" classes. */ namespace TOOL_EVT_UTILS { /** * Function IsCancelInteractive() * - * Indicates the event should restart/end an ongoing interactive tool's - * event loop (eg esc key, click cancel, start different tool) + * Indicates the event should restart/end an ongoing interactive tool's event loop (eg esc + * key, click cancel, start different tool). */ bool IsCancelInteractive( const TOOL_EVENT& aEvt ); @@ -670,6 +662,13 @@ namespace TOOL_EVT_UTILS */ bool IsSelectionEvent( const TOOL_EVENT& aEvt ); + /** + * Function IsPointEditor + * + * Indicates if the event is from one of the point editors. Usually used to allow the + * point editor to activate itself without de-activating the current drawing tool. + */ + bool IsPointEditor( const TOOL_EVENT& aEvt ); } diff --git a/pagelayout_editor/tools/pl_drawing_tools.cpp b/pagelayout_editor/tools/pl_drawing_tools.cpp index 5d71cf7456..1600a830de 100644 --- a/pagelayout_editor/tools/pl_drawing_tools.cpp +++ b/pagelayout_editor/tools/pl_drawing_tools.cpp @@ -80,7 +80,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -103,13 +103,9 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent ) // There's nothing to roll-back, but we still need to pop the undo stack m_frame->RollbackFromUndo(); } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -166,6 +162,7 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + m_frame->PopTool(); return 0; } @@ -182,7 +179,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true ); getViewControls()->ShowCursor( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Prime the pump @@ -203,16 +200,12 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) item = nullptr; m_frame->RollbackFromUndo(); } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } - if( evt->IsActivate() ) + if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) break; } @@ -264,6 +257,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent ) getViewControls()->CaptureCursor( item != nullptr ); } + m_frame->PopTool(); return 0; } diff --git a/pagelayout_editor/tools/pl_edit_tool.cpp b/pagelayout_editor/tools/pl_edit_tool.cpp index 21c46d2950..ce4f4564b1 100644 --- a/pagelayout_editor/tools/pl_edit_tool.cpp +++ b/pagelayout_editor/tools/pl_edit_tool.cpp @@ -290,10 +290,11 @@ bool PL_EDIT_TOOL::updateModificationPoint( PL_SELECTION& aSelection ) int PL_EDIT_TOOL::ImportWorksheetContent( const TOOL_EVENT& aEvent ) { + m_toolMgr->RunAction( ACTIONS::cancelInteractive, true ); + wxCommandEvent evt( wxEVT_NULL, ID_APPEND_DESCR_FILE ); m_frame->Files_io( evt ); - m_frame->ClearToolStack(); return 0; } @@ -354,7 +355,7 @@ static bool deleteItem( PL_EDITOR_FRAME* aFrame, const VECTOR2D& aPosition ) int PL_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); PL_PICKER_TOOL* picker = m_toolMgr->GetTool<PL_PICKER_TOOL>(); @@ -409,14 +410,12 @@ int PL_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { if( m_pickerItem ) m_toolMgr->GetTool<PL_SELECTION_TOOL>()->UnbrightenItem( m_pickerItem ); - - if( aFinalState == PL_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); } ); picker->Activate(); Wait(); + m_frame->PopTool(); return 0; } diff --git a/pagelayout_editor/tools/pl_point_editor.cpp b/pagelayout_editor/tools/pl_point_editor.cpp index 2b1799e9f4..96ebd4e3ff 100644 --- a/pagelayout_editor/tools/pl_point_editor.cpp +++ b/pagelayout_editor/tools/pl_point_editor.cpp @@ -217,10 +217,6 @@ int PL_POINT_EDITOR::Main( const TOOL_EVENT& aEvent ) modified = false; } - // ESC should clear selection along with edit points - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true ); - break; } diff --git a/pagelayout_editor/tools/pl_selection_tool.cpp b/pagelayout_editor/tools/pl_selection_tool.cpp index 5b98a237a2..af0436f613 100644 --- a/pagelayout_editor/tools/pl_selection_tool.cpp +++ b/pagelayout_editor/tools/pl_selection_tool.cpp @@ -177,7 +177,7 @@ int PL_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) } } - else if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsCancel() ) + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { ClearSelection(); } diff --git a/pcbnew/router/length_tuner_tool.cpp b/pcbnew/router/length_tuner_tool.cpp index 2f9d44dd87..53ed9629c6 100644 --- a/pcbnew/router/length_tuner_tool.cpp +++ b/pcbnew/router/length_tuner_tool.cpp @@ -261,7 +261,7 @@ int LENGTH_TUNER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) // Deselect all items m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - frame()->SetTool( aEvent.GetCommandStr().get() ); + frame()->PushTool( aEvent.GetCommandStr().get() ); Activate(); m_router->SetMode( aEvent.Parameter<PNS::ROUTER_MODE>() ); @@ -302,6 +302,7 @@ int LENGTH_TUNER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) m_savedSettings = m_router->Settings(); m_savedSizes = m_router->Sizes(); + frame()->PopTool(); return 0; } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 869c394472..3fd160e827 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -861,7 +861,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) // Deselect all items m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - frame->SetTool( aEvent.GetCommandStr().get() ); + frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); m_router->SetMode( mode ); @@ -883,9 +883,6 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) { if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - frame->ClearToolStack(); - break; // Finish } else if( evt->Action() == TA_UNDO_REDO_PRE ) @@ -944,6 +941,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent ) m_savedSettings = m_router->Settings(); m_savedSizes = m_router->Sizes(); + frame->PopTool(); return 0; } @@ -1131,7 +1129,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent ) while( TOOL_EVENT* evt = Wait() ) { - if( evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { break; } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index e3bdab23f8..c4593e5e06 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -148,7 +148,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent ) if( aEvent.HasPosition() ) startingPoint = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); while( drawSegment( S_SEGMENT, line, startingPoint ) ) @@ -174,6 +174,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent ) line->SetFlags( IS_NEW ); } + m_frame->PopTool(); return 0; } @@ -194,7 +195,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) if( aEvent.HasPosition() ) startingPoint = getViewControls()->GetCursorPosition( !aEvent.Modifier( MD_ALT ) ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); while( drawSegment( S_CIRCLE, circle, startingPoint ) ) @@ -209,6 +210,8 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) commit.Add( circle ); commit.Push( _( "Draw a circle" ) ); + + m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, circle ); } circle = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT; @@ -216,6 +219,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) startingPoint = NULLOPT; } + m_frame->PopTool(); return 0; } @@ -233,7 +237,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) arc->SetFlags( IS_NEW ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); while( drawArc( arc, immediateMode ) ) @@ -248,6 +252,8 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) commit.Add( arc ); commit.Push( _( "Draw an arc" ) ); + + m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, arc ); } arc = m_editModules ? new EDGE_MODULE( module ) : new DRAWSEGMENT; @@ -255,6 +261,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) immediateMode = false; } + m_frame->PopTool(); return 0; } @@ -268,14 +275,13 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); BOARD_COMMIT commit( m_frame ); - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); // do not capture or auto-pan until we start placing some text SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); bool reselect = false; @@ -308,13 +314,9 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) m_controls->CaptureCursor( false ); m_controls->ShowCursor( true ); } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -415,6 +417,8 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) commit.Add( text ); commit.Push( _( "Place a text" ) ); + m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, text ); + m_controls->CaptureCursor( false ); m_controls->SetAutoPan( false ); m_controls->ShowCursor( true ); @@ -438,6 +442,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) } frame()->SetMsgPanel( board() ); + m_frame->PopTool(); return 0; } @@ -465,13 +470,12 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) m_view->Add( &preview ); - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DIMENSION ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); enum DIMENSION_STEPS @@ -509,13 +513,9 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) delete dimension; step = SET_ORIGIN; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) @@ -548,6 +548,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) { case SET_ORIGIN: { + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + PCB_LAYER_ID layer = getDrawingLayer(); const BOARD_DESIGN_SETTINGS& boardSettings = m_board->GetDesignSettings(); @@ -597,6 +599,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) commit.Add( dimension ); commit.Push( _( "Draw a dimension" ) ); + + m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, dimension ); } } break; @@ -650,6 +654,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) m_view->Remove( &preview ); frame()->SetMsgPanel( board() ); + m_frame->PopTool(); return 0; } @@ -676,7 +681,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) return 0; } - m_frame->ClearToolStack(); + m_toolMgr->RunAction( ACTIONS::cancelInteractive, true ); // Add a VIEW_GROUP that serves as a preview for the new item PCBNEW_SELECTION preview; @@ -855,7 +860,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D PCBNEW_SELECTION preview; m_view->Add( &preview ); - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); bool direction45 = false; // 45 degrees only mode @@ -877,7 +881,10 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D m_controls->ForceCursorPosition( true, cursorPos ); // 45 degree angle constraint enabled with an option and toggled with Ctrl - const bool limit45 = ( frame()->Settings().m_Use45DegreeGraphicSegments != !!( evt->Modifier( MD_CTRL ) ) ); + bool limit45 = frame()->Settings().m_Use45DegreeGraphicSegments; + + if( evt->Modifier( MD_CTRL ) ) + limit45 = !limit45; if( direction45 != limit45 && started && aShape == S_SEGMENT ) { @@ -913,10 +920,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D if( !isLocalOriginSet ) m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 ); } - else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - } break; } @@ -936,6 +939,8 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D { if( !started ) { + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + if( aStartingPoint ) { cursorPos = aStartingPoint.get(); @@ -978,17 +983,15 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D // we finish the segment as they are likely closing a path if( snapItem && aGraphic->GetLength() > 0.0 ) { - DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( mod ) : new DRAWSEGMENT; - l->SetFlags( IS_NEW ); - - *l = *aGraphic; - commit.Add( l ); + commit.Add( aGraphic ); + commit.Push( _( "Draw a line segment" ) ); + m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, aGraphic ); + } + else + { + delete aGraphic; } - if( !commit.Empty() ) - commit.Push( _( "Draw a line" ) ); - - delete aGraphic; aGraphic = nullptr; } @@ -1071,8 +1074,6 @@ static void updateArcFromConstructionMgr( const KIGFX::PREVIEW::ARC_GEOM_MANAGER bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode ) { - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - m_lineWidth = getSegmentWidth( getDrawingLayer() ); // Arc geometric construction manager @@ -1112,6 +1113,8 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode ) { if( !firstPoint ) { + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); @@ -1148,10 +1151,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode ) delete aGraphic; aGraphic = nullptr; } - else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - } break; } @@ -1268,10 +1267,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) ZONE_CONTAINER* sourceZone = nullptr; if( !getSourceZoneForAction( zoneMode, sourceZone ) ) - { - m_frame->ClearToolStack(); return 0; - } ZONE_CREATE_HELPER::PARAMS params; @@ -1292,7 +1288,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) // hands the calculated points over to the zone creator tool POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // register for events m_controls->ShowCursor( true ); @@ -1333,12 +1329,11 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - m_frame->ClearToolStack(); break; } // pre-empted by another tool, give up - if( evt->IsActivate() ) + if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) break; } else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) ) @@ -1419,8 +1414,8 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent ) } } // end while - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_controls->ForceCursorPosition( false ); + m_frame->PopTool(); return 0; } @@ -1702,11 +1697,12 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent ) VIA_PLACER placer( frame() ); SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::VIA ); - frame()->SetTool( aEvent.GetCommandStr().get() ); + frame()->PushTool( aEvent.GetCommandStr().get() ); doInteractiveItemPlacement( &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP ); + frame()->PopTool(); return 0; } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5ae9641165..f8a89571de 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -411,7 +411,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false ); } - else if( evt->IsCancel() || evt->IsActivate() ) + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { restore_state = true; // Canceling the tool means that items have to be restored break; // Finish @@ -1107,7 +1107,7 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) auto& view = *getView(); auto& controls = *getViewControls(); - frame()->SetTool( aEvent.GetCommandStr().get() ); + frame()->PushTool( aEvent.GetCommandStr().get() ); Activate(); EDA_UNITS_T units = frame()->GetUserUnits(); @@ -1146,7 +1146,6 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - frame()->ClearToolStack(); break; } @@ -1204,7 +1203,7 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent ) view.SetVisible( &ruler, false ); view.Remove( &ruler ); - + frame()->PopTool(); return 0; } diff --git a/pcbnew/tools/footprint_editor_tools.cpp b/pcbnew/tools/footprint_editor_tools.cpp index 6308022512..5f5c66a311 100644 --- a/pcbnew/tools/footprint_editor_tools.cpp +++ b/pcbnew/tools/footprint_editor_tools.cpp @@ -313,11 +313,12 @@ int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent ) PAD_PLACER placer; - frame()->SetTool( aEvent.GetCommandStr().get() ); + frame()->PushTool( aEvent.GetCommandStr().get() ); doInteractiveItemPlacement( &placer, _( "Place pad" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP ); + frame()->PopTool(); return 0; } diff --git a/pcbnew/tools/microwave_tool.cpp b/pcbnew/tools/microwave_tool.cpp index ea5e809ba6..a6904423bd 100644 --- a/pcbnew/tools/microwave_tool.cpp +++ b/pcbnew/tools/microwave_tool.cpp @@ -117,11 +117,12 @@ int MICROWAVE_TOOL::addMicrowaveFootprint( const TOOL_EVENT& aEvent ) MICROWAVE_PLACER placer( creator ); - frame.SetTool( aEvent.GetCommandStr().get() ); + frame.PushTool( aEvent.GetCommandStr().get() ); doInteractiveItemPlacement( &placer, _( "Place microwave feature" ), IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES ); + frame.PopTool(); return 0; } @@ -186,7 +187,7 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent ) KIGFX::VIEW_CONTROLS& controls = *getViewControls(); auto& frame = *getEditFrame<PCB_EDIT_FRAME>(); - frame.SetTool( aEvent.GetCommandStr().get() ); + frame.PushTool( aEvent.GetCommandStr().get() ); Activate(); TWO_POINT_GEOMETRY_MANAGER tpGeomMgr; @@ -225,7 +226,6 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent ) } else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - frame.ClearToolStack(); break; } @@ -282,7 +282,7 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent ) controls.CaptureCursor( false ); controls.SetAutoPan( false ); view.Remove( &previewRect ); - + frame.PopTool(); return 0; } diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index 71700bee3d..ea622c8c0b 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -469,21 +469,19 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent ) break; } - // This is a cancel-current-action (ie: <esc>). - // Note that this must go before IsCancelInteractive() as it also checks IsCancel(). - else if( evt->IsCancel() ) - { - // Clear current selection list to avoid selection of deleted items - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - - commit.Revert(); - break; - } - - // Now that cancel-current-action has been handled, check for cancel-tool. else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { - commit.Push( _( "Renumber pads" ) ); + // This is a cancel-current-action (ie: <esc>). + if( evt->IsCancel() ) + { + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + commit.Revert(); + } + else + { + commit.Push( _( "Renumber pads" ) ); + } + break; } diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index 76870b8af4..24c927925f 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -518,7 +518,7 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) controls->ShowCursor( true ); controls->SetSnapping( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); VECTOR2I cursorPos = controls->GetCursorPosition(); @@ -551,13 +551,9 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) commit.Revert(); module = NULL; } - else + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - { - m_frame->ClearToolStack(); - break; - } + break; } if( evt->IsActivate() ) // now finish unconditionally @@ -626,7 +622,6 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) } m_frame->PopTool(); - return 0; } @@ -716,7 +711,7 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); controls->SetSnapping( true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); // Main loop: keep receiving events @@ -728,9 +723,6 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_frame->ClearToolStack(); - break; } @@ -780,9 +772,9 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) } delete target; - - controls->SetSnapping( false ); view->Remove( &preview ); + controls->SetSnapping( false ); + m_frame->PopTool(); return 0; } @@ -966,7 +958,7 @@ void PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* a int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent ) { - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); @@ -982,7 +974,7 @@ int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent ) picker->Activate(); Wait(); - m_frame->ClearToolStack(); + m_frame->PopTool(); return 0; } @@ -1153,7 +1145,7 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent ) highlightNet( getViewControls()->GetMousePosition(), use_selection ); } - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); @@ -1164,16 +1156,11 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent ) return true; } ); - picker->SetFinalizeHandler( [&]( const int& aFinalState ) - { - if( aFinalState == PCBNEW_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); - } ); - picker->SetLayerSet( LSET::AllCuMask() ); picker->Activate(); Wait(); + m_frame->PopTool(); return 0; } @@ -1227,7 +1214,7 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, BOARD* aBoard, bool aShow int PCB_EDITOR_CONTROL::LocalRatsnestTool( const TOOL_EVENT& aEvent ) { - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); auto picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); @@ -1249,14 +1236,12 @@ int PCB_EDITOR_CONTROL::LocalRatsnestTool( const TOOL_EVENT& aEvent ) pad->SetLocalRatsnestVisible( opt->m_ShowGlobalRatsnest ); } } - - if( aCondition == PCBNEW_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); } ); picker->Activate(); Wait(); + m_frame->PopTool(); return 0; } @@ -1404,6 +1389,7 @@ void PCB_EDITOR_CONTROL::setTransitions() Go( &PCB_EDITOR_CONTROL::ClearHighlight, PCB_ACTIONS::clearHighlight.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, PCB_ACTIONS::highlightNetTool.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, PCB_ACTIONS::highlightNetSelection.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ClearHighlight, ACTIONS::cancelInteractive.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::LocalRatsnestTool, PCB_ACTIONS::localRatsnestTool.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HideDynamicRatsnest, PCB_ACTIONS::hideDynamicRatsnest.MakeEvent() ); diff --git a/pcbnew/tools/pcb_tool_base.cpp b/pcbnew/tools/pcb_tool_base.cpp index dce2938924..aa7e849f89 100644 --- a/pcbnew/tools/pcb_tool_base.cpp +++ b/pcbnew/tools/pcb_tool_base.cpp @@ -85,21 +85,15 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer preview.Clear(); - if( aOptions & IPO_SINGLE_CLICK ) - { - frame()->ClearToolStack(); - break; - } - controls()->SetAutoPan( false ); controls()->CaptureCursor( false ); controls()->ShowCursor( true ); - } - else - { - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - frame()->ClearToolStack(); + if( aOptions & IPO_SINGLE_CLICK ) + break; + } + else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) + { break; } diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 1395e7752c..395fcd8ba0 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -456,7 +456,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent ) } else { - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); @@ -471,7 +471,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent ) picker->Activate(); Wait(); - m_frame->ClearToolStack(); + m_frame->PopTool(); } return 0; @@ -514,7 +514,7 @@ int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - m_frame->SetTool( aEvent.GetCommandStr().get() ); + m_frame->PushTool( aEvent.GetCommandStr().get() ); Activate(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); @@ -575,14 +575,12 @@ int PCBNEW_CONTROL::DeleteItemCursor( const TOOL_EVENT& aEvent ) { if( m_pickerItem ) m_toolMgr->GetTool<SELECTION_TOOL>()->UnbrightenItem( m_pickerItem ); - - if( aFinalState == PCBNEW_PICKER_TOOL::EVT_CANCEL ) - m_frame->ClearToolStack(); } ); picker->Activate(); Wait(); + m_frame->PopTool(); return 0; } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 98e13efda0..d40ea09fb5 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -387,10 +387,6 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) if( inDrag ) // Restore the last change commit.Revert(); - // ESC should clear selection along with edit points - if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) - m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - break; } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 98e2832c96..042b5d73c9 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -185,15 +185,6 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) } -int SELECTION_TOOL::SelectionTool( const TOOL_EVENT& aEvent ) -{ - // Since the selection tool is always running underneath the toolStack, all we need to - // do is clear the stack. - m_frame->ClearToolStack(); - return 0; -} - - int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { // Main loop: keep receiving events @@ -291,17 +282,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) } } - else if( evt->Action() == TA_UNDO_REDO_PRE ) + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE) { clearSelection(); } - else if( evt->IsCancel() ) - { - clearSelection(); - m_toolMgr->RunAction( PCB_ACTIONS::clearHighlight, true ); - } - else evt->SetPassEvent(); } @@ -2219,7 +2204,6 @@ void SELECTION_TOOL::setTransitions() Go( &SELECTION_TOOL::UpdateMenu, ACTIONS::updateMenu.MakeEvent() ); Go( &SELECTION_TOOL::Main, PCB_ACTIONS::selectionActivate.MakeEvent() ); - Go( &SELECTION_TOOL::SelectionTool, ACTIONS::selectionTool.MakeEvent() ); Go( &SELECTION_TOOL::CursorSelection, PCB_ACTIONS::selectionCursor.MakeEvent() ); Go( &SELECTION_TOOL::ClearSelection, PCB_ACTIONS::selectionClear.MakeEvent() ); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 19006f4d45..fe987d9b97 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -79,8 +79,6 @@ public: */ int Main( const TOOL_EVENT& aEvent ); - int SelectionTool( const TOOL_EVENT& aEvent ); - /** * Function GetSelection() * diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp index e9b5afc0cc..1fc024cb1d 100644 --- a/pcbnew/tools/zone_create_helper.cpp +++ b/pcbnew/tools/zone_create_helper.cpp @@ -183,8 +183,9 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone ) filler.Fill( { aZone.get() } ); } - bCommit.Add( aZone.release() ); + bCommit.Add( aZone.get() ); bCommit.Push( _( "Add a zone" ) ); + m_tool.GetManager()->RunAction( PCB_ACTIONS::selectItem, true, aZone.release() ); break; } @@ -202,6 +203,7 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone ) poly->SetLayer( m_tool.getDrawingLayer() ); poly->SetPolyShape ( *aZone->Outline() ); bCommit.Add( poly ); + m_tool.GetManager()->RunAction( PCB_ACTIONS::selectItem, true, poly ); } else { @@ -235,6 +237,8 @@ bool ZONE_CREATE_HELPER::OnFirstPoint( POLYGON_GEOM_MANAGER& aMgr ) // of the preview if( !m_zone ) { + m_tool.GetManager()->RunAction( PCB_ACTIONS::selectionClear, true ); + if( m_params.m_sourceZone ) m_zone = createZoneFromExisting( *m_params.m_sourceZone ); else