7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-14 15:19:38 +00:00

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

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

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

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

Some files were not shown because too many files have changed in this diff Show More