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)
This commit is contained in:
Jeff Young 2019-06-27 12:47:24 +01:00
parent e175eb25b8
commit 2f23aa9556
37 changed files with 227 additions and 325 deletions

View File

@ -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() )

View File

@ -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() );

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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() );

View File

@ -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()
*

View File

@ -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,14 +97,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -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;
}
}
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;
}

View File

@ -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;
}

View File

@ -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,14 +125,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -212,6 +208,7 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( component != nullptr );
}
m_frame->PopTool();
return 0;
}
@ -220,12 +217,6 @@ 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();
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, 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,14 +256,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -348,9 +336,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( image != nullptr );
}
if( immediateMode )
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,14 +463,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -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,14 +630,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -717,6 +693,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( sheet != nullptr);
}
m_frame->PopTool();
return 0;
}

View File

@ -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();

View File

@ -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() );

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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(); }

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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,14 +103,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -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;
}
}
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,14 +314,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -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,14 +513,10 @@ 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;
}
}
if( evt->IsActivate() )
break;
@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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() )
{
// 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;
}

View File

@ -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,14 +551,10 @@ 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;
}
}
if( evt->IsActivate() ) // now finish unconditionally
break;
@ -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() );

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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() );

View File

@ -79,8 +79,6 @@ public:
*/
int Main( const TOOL_EVENT& aEvent );
int SelectionTool( const TOOL_EVENT& aEvent );
/**
* Function GetSelection()
*

View File

@ -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