Allow move tool to run on top of other tools.

Fixes: lp:1784480
* https://bugs.launchpad.net/kicad/+bug/1784480
This commit is contained in:
Jeff Young 2019-07-01 22:01:33 +01:00
parent ad26ece8d4
commit 9effd24f3a
39 changed files with 844 additions and 472 deletions

View File

@ -366,7 +366,7 @@ void EDA_DRAW_FRAME::AddStandardSubMenus( TOOL_MENU& aToolMenu )
void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg ) void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg )
{ {
SetStatusText( msg, 5 ); SetStatusText( msg, 6 );
} }
@ -461,7 +461,7 @@ void EDA_DRAW_FRAME::PopTool()
} }
} }
else else
DisplayToolMsg( ACTIONS::selectionTool.GetName() ); DisplayToolMsg( ACTIONS::selectionTool.GetLabel() );
} }

View File

@ -54,7 +54,7 @@ static const std::string flag2string( int aFlag, const FlagString* aExps )
void TOOL_EVENT::init() void TOOL_EVENT::init()
{ {
// By default only MESSAGEs and Cancels are passed to multiple recipients // By default only MESSAGEs and Cancels are passed to multiple recipients
m_passEvent = m_category == TC_MESSAGE || TOOL_EVT_UTILS::IsCancelInteractive( *this ); m_passEvent = m_category == TC_MESSAGE || IsCancelInteractive();
m_hasPosition = ( m_category == TC_MOUSE || m_category == TC_COMMAND ); m_hasPosition = ( m_category == TC_MOUSE || m_category == TC_COMMAND );
} }
@ -183,35 +183,42 @@ bool TOOL_EVENT::IsDblClick( int aButtonMask ) const
} }
bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt ) bool TOOL_EVENT::IsCancelInteractive()
{ {
if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get() == ACTIONS::cancelInteractive.GetName() ) if( GetCommandStr() && GetCommandStr().get() == ACTIONS::cancelInteractive.GetName() )
return true; return true;
if( aEvt.GetCommandId() && aEvt.GetCommandId().get() == ACTIONS::cancelInteractive.GetId() ) if( GetCommandId() && GetCommandId().get() == ACTIONS::cancelInteractive.GetId() )
return true; return true;
return aEvt.IsCancel(); return IsCancel();
} }
bool TOOL_EVT_UTILS::IsSelectionEvent( const TOOL_EVENT& aEvt ) bool TOOL_EVENT::IsSelectionEvent()
{ {
return aEvt.Matches( EVENTS::ClearedEvent ) return Matches( EVENTS::ClearedEvent )
|| aEvt.Matches( EVENTS::UnselectedEvent ) || Matches( EVENTS::UnselectedEvent )
|| aEvt.Matches( EVENTS::SelectedEvent ); || Matches( EVENTS::SelectedEvent );
} }
bool TOOL_EVT_UTILS::IsPointEditor( const TOOL_EVENT& aEvt ) bool TOOL_EVENT::IsPointEditor()
{ {
if( aEvt.GetCommandStr() && aEvt.GetCommandStr().get().find( "PointEditor" ) >= 0 ) if( GetCommandStr() && GetCommandStr().get().find( "PointEditor" ) != wxNOT_FOUND )
return true; return true;
if( aEvt.GetCommandId() && aEvt.GetCommandId() == ACTIONS::activatePointEditor.GetId() ) if( GetCommandId() && GetCommandId() == ACTIONS::activatePointEditor.GetId() )
return true; return true;
return false; return false;
} }
bool TOOL_EVENT::IsMoveTool()
{
if( GetCommandStr() && GetCommandStr().get().find( "InteractiveMove" ) != wxNOT_FOUND )
return true;
return false;
}

View File

@ -52,7 +52,7 @@ int ZOOM_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
break; break;
else if( evt->IsDrag( BUT_LEFT ) || evt->IsDrag( BUT_RIGHT ) ) else if( evt->IsDrag( BUT_LEFT ) || evt->IsDrag( BUT_RIGHT ) )
@ -84,7 +84,7 @@ bool ZOOM_TOOL::selectRegion()
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
cancelled = true; cancelled = true;
break; break;

View File

@ -128,23 +128,40 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
const VECTOR2I cursorPos = controls.GetCursorPosition(); const VECTOR2I cursorPos = controls.GetCursorPosition();
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto clearRuler = [&] () {
{
if( originSet )
{
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
controls.SetAutoPan( false ); controls.SetAutoPan( false );
controls.CaptureCursor( false ); controls.CaptureCursor( false );
originSet = false; originSet = false;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( originSet )
clearRuler();
else
{
m_frame->PopTool();
break; break;
} }
}
if( evt->IsActivate() ) else if( evt->IsActivate() )
{
if( originSet )
clearRuler();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
m_frame->PopTool();
break;
}
}
// click or drag starts // click or drag starts
else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) ) else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
@ -199,7 +216,6 @@ int CVPCB_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
view.Remove( &ruler ); view.Remove( &ruler );
controls.ApplySettings( previous_settings ); controls.ApplySettings( previous_settings );
m_frame->PopTool();
return 0; return 0;
} }

View File

@ -667,12 +667,12 @@ TOOL_ACTION EE_ACTIONS::finishLine( "eeschema.InteractiveDrawingLineWireBus.fini
// SCH_MOVE_TOOL // SCH_MOVE_TOOL
// //
TOOL_ACTION EE_ACTIONS::move( "eeschema.InteractiveEdit.move", TOOL_ACTION EE_ACTIONS::move( "eeschema.InteractiveMove.move",
AS_GLOBAL, AS_GLOBAL,
'M', LEGACY_HK_NAME( "Move Item" ), 'M', LEGACY_HK_NAME( "Move Item" ),
_( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE ); _( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
TOOL_ACTION EE_ACTIONS::drag( "eeschema.InteractiveEdit.drag", TOOL_ACTION EE_ACTIONS::drag( "eeschema.InteractiveMove.drag",
AS_GLOBAL, AS_GLOBAL,
'G', LEGACY_HK_NAME( "Drag Item" ), 'G', LEGACY_HK_NAME( "Drag Item" ),
_( "Drag" ), _( "Drags the selected item(s)" ), move_xpm, AF_ACTIVATE ); _( "Drag" ), _( "Drags the selected item(s)" ), move_xpm, AF_ACTIVATE );

View File

@ -92,7 +92,7 @@ int EE_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
} }
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( m_cancelHandler ) if( m_cancelHandler )
{ {

View File

@ -295,7 +295,7 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
// Main loop: keep receiving events // Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( !m_editPoints || TOOL_EVT_UTILS::IsSelectionEvent( *evt ) ) if( !m_editPoints || evt->IsSelectionEvent() )
break; break;
if ( !inDrag ) if ( !inDrag )
@ -328,7 +328,7 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
inDrag = false; inDrag = false;
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( inDrag ) // Restore the last change if( inDrag ) // Restore the last change
{ {
@ -336,7 +336,10 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
inDrag = false; inDrag = false;
modified = false; modified = false;
} }
else if( evt->IsCancelInteractive() )
break;
if( evt->IsActivate() && !evt->IsMoveTool() )
break; break;
} }

View File

@ -400,7 +400,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) else if( evt->IsCancelInteractive() )
{ {
ClearSelection(); ClearSelection();
} }
@ -658,7 +658,7 @@ bool EE_SELECTION_TOOL::selectMultiple()
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
cancelled = true; cancelled = true;
break; break;

View File

@ -89,23 +89,39 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( item )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
delete item; delete item;
item = nullptr; item = nullptr;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( item )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( item )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
@ -207,7 +223,6 @@ int LIB_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( item != nullptr ); getViewControls()->CaptureCursor( item != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -242,24 +257,44 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( item )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
delete item; delete item;
item = nullptr; item = nullptr;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( item )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
// Continue on if it's just the point editor; otherwise give way to new tool else if( evt->IsActivate() )
if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) {
if( item )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) && !item ) else if( evt->IsClick( BUT_LEFT ) && !item )
{ {
@ -339,7 +374,6 @@ int LIB_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( item != nullptr ); getViewControls()->CaptureCursor( item != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -357,8 +391,14 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
{ {
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_BULLSEYE ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_BULLSEYE );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() )
{ {
m_frame->PopTool();
break;
}
else if( evt->IsActivate() )
{
m_frame->PopTool();
break; break;
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
@ -387,7 +427,6 @@ int LIB_DRAWING_TOOLS::PlaceAnchor( const TOOL_EVENT& aEvent )
} }
} }
m_frame->PopTool();
return 0; return 0;
} }

View File

@ -197,7 +197,7 @@ int LIB_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle cancel // Handle cancel
// //
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( m_moveInProgress ) if( m_moveInProgress )
restore_state = true; restore_state = true;

View File

@ -118,23 +118,39 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( component ? wxCURSOR_ARROW : wxCURSOR_PENCIL ); m_frame->GetCanvas()->SetCurrentCursor( component ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( component )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
delete component; delete component;
component = nullptr; component = nullptr;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( component )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( component )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
if( !component ) if( !component )
@ -210,7 +226,6 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( component != nullptr ); getViewControls()->CaptureCursor( component != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -247,26 +262,45 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( image ? wxCURSOR_ARROW : wxCURSOR_PENCIL ); m_frame->GetCanvas()->SetCurrentCursor( image ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( image )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
delete image; delete image;
image = nullptr; image = nullptr;
};
if( evt->IsCancelInteractive() )
{
if( image )
cleanup();
else
{
m_frame->PopTool();
break;
}
if( immediateMode ) if( immediateMode )
break;
}
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{ {
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( image )
cleanup();
if( evt->IsActivate() ) if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
if( !image ) if( !image )
@ -315,9 +349,12 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
m_view->ClearPreview(); m_view->ClearPreview();
if( immediateMode ) if( immediateMode )
{
m_frame->PopTool();
break; break;
} }
} }
}
else if( evt->IsClick( BUT_RIGHT ) ) else if( evt->IsClick( BUT_RIGHT ) )
{ {
// Warp after context menu only if dragging... // Warp after context menu only if dragging...
@ -339,7 +376,6 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( image != nullptr ); getViewControls()->CaptureCursor( image != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -403,10 +439,24 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
cursorPos = (wxPoint) getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); cursorPos = (wxPoint) getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() )
{ {
m_frame->PopTool();
break; break;
} }
else if( evt->IsActivate() )
{
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
if( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) ) if( !m_frame->GetScreen()->GetItem( cursorPos, 0, type ) )
@ -442,7 +492,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
delete previewItem; delete previewItem;
m_view->ClearPreview(); m_view->ClearPreview();
m_frame->PopTool();
return 0; return 0;
} }
@ -469,23 +518,43 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( item ? wxCURSOR_ARROW : wxCURSOR_PENCIL ); m_frame->GetCanvas()->SetCurrentCursor( item ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( item )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
delete item; delete item;
item = nullptr; item = nullptr;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( item )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( item )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
// First click creates... // First click creates...
@ -585,7 +654,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
} }
else if( item && TOOL_EVT_UTILS::IsSelectionEvent( *evt ) ) else if( item && evt->IsSelectionEvent() )
{ {
// This happens if our text was replaced out from under us by ConvertTextType() // This happens if our text was replaced out from under us by ConvertTextType()
EE_SELECTION& selection = m_selectionTool->GetSelection(); EE_SELECTION& selection = m_selectionTool->GetSelection();
@ -611,7 +680,6 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( item != nullptr ); getViewControls()->CaptureCursor( item != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -639,24 +707,43 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview(); m_view->ClearPreview();
if( sheet )
{
delete sheet; delete sheet;
sheet = nullptr; sheet = nullptr;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( sheet )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( sheet )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) && !sheet ) else if( evt->IsClick( BUT_LEFT ) && !sheet )
{ {
@ -712,7 +799,6 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( sheet != nullptr); getViewControls()->CaptureCursor( sheet != nullptr);
} }
m_frame->PopTool();
return 0; return 0;
} }

View File

@ -265,10 +265,7 @@ int SCH_LINE_WIRE_BUS_TOOL::DrawSegments( const TOOL_EVENT& aEvent )
segment = startSegments( layer, cursorPos ); segment = startSegments( layer, cursorPos );
} }
doDrawSegments( layer, segment ); return doDrawSegments( layer, segment );
m_frame->PopTool();
return 0;
} }
@ -316,10 +313,12 @@ int SCH_LINE_WIRE_BUS_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
// If we have an unfolded wire to draw, then draw it // If we have an unfolded wire to draw, then draw it
if( segment ) if( segment )
doDrawSegments( LAYER_WIRE, segment ); return doDrawSegments( LAYER_WIRE, segment );
else
{
m_frame->PopTool(); m_frame->PopTool();
return 0; return 0;
}
} }
@ -461,10 +460,7 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle cancel: // Handle cancel:
// //
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( aSegment || m_busUnfold.in_progress )
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
aSegment = nullptr; aSegment = nullptr;
@ -482,15 +478,34 @@ int SCH_LINE_WIRE_BUS_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment )
m_view->ClearPreview(); m_view->ClearPreview();
m_view->ShowPreview( false ); m_view->ShowPreview( false );
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( aSegment || m_busUnfold.in_progress )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( aSegment || m_busUnfold.in_progress )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle finish: // Handle finish:
// //

View File

@ -335,7 +335,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle cancel // Handle cancel
// //
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) else if( evt->IsCancelInteractive() )
{ {
if( m_moveInProgress ) if( m_moveInProgress )
restore_state = true; restore_state = true;

View File

@ -355,7 +355,7 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) if( evt->IsCancelInteractive() )
{ {
cancelled = true; cancelled = true;
break; break;
@ -777,23 +777,40 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
const VECTOR2I cursorPos = controls.GetCursorPosition(); const VECTOR2I cursorPos = controls.GetCursorPosition();
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto clearRuler = [&] () {
{
if( originSet )
{
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
controls.SetAutoPan( false ); controls.SetAutoPan( false );
controls.CaptureCursor( false ); controls.CaptureCursor( false );
originSet = false; originSet = false;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( originSet )
clearRuler();
else
{
m_frame->PopTool();
break; break;
} }
}
if( evt->IsActivate() ) else if( evt->IsActivate() )
{
if( originSet )
clearRuler();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
m_frame->PopTool();
break;
}
}
// click or drag starts // click or drag starts
else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) ) else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
@ -848,7 +865,6 @@ int GERBVIEW_SELECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
view.Remove( &ruler ); view.Remove( &ruler );
controls.ApplySettings( previous_settings ); controls.ApplySettings( previous_settings );
m_frame->PopTool();
return 0; return 0;
} }

View File

@ -375,6 +375,37 @@ public:
*/ */
bool IsAction( const TOOL_ACTION* aAction ) const; bool IsAction( const TOOL_ACTION* aAction ) const;
/**
* Function IsCancelInteractive()
*
* Indicates the event should restart/end an ongoing interactive tool's event loop (eg esc
* key, click cancel, start different tool).
*/
bool IsCancelInteractive();
/**
* Function IsSelectionEvent()
*
* Indicates an selection-changed notification event.
*/
bool IsSelectionEvent();
/**
* 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();
/**
* Function IsMoveTool
*
* Indicates if the event is from one of the move tools. Usually used to allow move to
* be done without de-activating the current drawing tool.
*/
bool IsMoveTool();
/** /**
* Function Parameter() * Function Parameter()
* Returns a non-standard parameter assigned to the event. Its meaning depends on the * Returns a non-standard parameter assigned to the event. Its meaning depends on the
@ -638,38 +669,4 @@ 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.
*/
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).
*/
bool IsCancelInteractive( const TOOL_EVENT& aEvt );
/**
* Function IsSelectionEvent()
*
* Indicates an selection-changed notification event.
*/
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 );
}
#endif #endif

View File

@ -60,7 +60,7 @@ TOOL_ACTION PL_ACTIONS::placeImage( "plEditor.InteractiveDrawing.placeImage",
// PL_EDIT_TOOL // PL_EDIT_TOOL
// //
TOOL_ACTION PL_ACTIONS::move( "plEditor.InteractiveEdit.move", TOOL_ACTION PL_ACTIONS::move( "plEditor.InteractiveMove.move",
AS_GLOBAL, AS_GLOBAL,
'M', LEGACY_HK_NAME( "Move Item" ), 'M', LEGACY_HK_NAME( "Move Item" ),
_( "Move" ), _( "Moves the selected item(s)" ), _( "Move" ), _( "Moves the selected item(s)" ),

View File

@ -93,25 +93,41 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( item ? wxCURSOR_ARROW : wxCURSOR_PENCIL ); m_frame->GetCanvas()->SetCurrentCursor( item ? wxCURSOR_ARROW : wxCURSOR_PENCIL );
cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( item )
{
m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true );
delete item; delete item;
item = nullptr; item = nullptr;
// There's nothing to roll-back, but we still need to pop the undo stack // There's nothing to roll-back, but we still need to pop the undo stack
m_frame->RollbackFromUndo(); m_frame->RollbackFromUndo();
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( item )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( item )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
// First click creates... // First click creates...
@ -163,7 +179,6 @@ int PL_DRAWING_TOOLS::PlaceItem( const TOOL_EVENT& aEvent )
getViewControls()->CaptureCursor( item != nullptr ); getViewControls()->CaptureCursor( item != nullptr );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -196,7 +211,7 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) ); VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( PL_ACTIONS::clearSelection, true );
@ -205,12 +220,12 @@ int PL_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
item = nullptr; item = nullptr;
m_frame->RollbackFromUndo(); m_frame->RollbackFromUndo();
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) else if( evt->IsCancelInteractive() )
{ {
break; break;
} }
if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) if( evt->IsActivate() && !evt->IsPointEditor() && !evt->IsMoveTool() )
break; break;
} }

View File

@ -185,7 +185,7 @@ int PL_EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Handle cancel // Handle cancel
// //
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( m_moveInProgress ) if( m_moveInProgress )
restore_state = true; restore_state = true;

View File

@ -119,7 +119,7 @@ int PL_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
} }
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( m_cancelHandler ) if( m_cancelHandler )
{ {

View File

@ -185,7 +185,7 @@ int PL_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
// Main loop: keep receiving events // Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( !m_editPoints || TOOL_EVT_UTILS::IsSelectionEvent( *evt ) ) if( !m_editPoints || evt->IsSelectionEvent() )
break; break;
if ( !inDrag ) if ( !inDrag )
@ -213,7 +213,7 @@ int PL_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
inDrag = false; inDrag = false;
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( inDrag ) // Restore the last change if( inDrag ) // Restore the last change
{ {
@ -221,7 +221,10 @@ int PL_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
inDrag = false; inDrag = false;
modified = false; modified = false;
} }
else if( evt->IsCancelInteractive() )
break;
if( evt->IsActivate() && !evt->IsMoveTool() )
break; break;
} }

View File

@ -180,7 +180,7 @@ int PL_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
} }
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) else if( evt->IsCancelInteractive() )
{ {
ClearSelection(); ClearSelection();
} }
@ -308,7 +308,7 @@ bool PL_SELECTION_TOOL::selectMultiple()
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
cancelled = true; cancelled = true;
break; break;

View File

@ -57,7 +57,6 @@ MODULE* PCB_EDIT_FRAME::CreateMuWaveBaseFootprint( const wxString& aValue,
int aTextSize, int aPadCount ) int aTextSize, int aPadCount )
{ {
MODULE* module = CreateNewModule( aValue ); MODULE* module = CreateNewModule( aValue );
AddModuleToBoard( module );
if( aTextSize > 0 ) if( aTextSize > 0 )
{ {

View File

@ -192,7 +192,7 @@ void LENGTH_TUNER_TOOL::performTuning()
{ {
frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
break; break;
else if( evt->IsMotion() ) else if( evt->IsMotion() )
{ {
@ -280,7 +280,7 @@ int LENGTH_TUNER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
{ {
frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
break; // Finish break; // Finish
} }

View File

@ -76,6 +76,8 @@ protected:
GRID_HELPER* m_gridHelper; GRID_HELPER* m_gridHelper;
PNS_KICAD_IFACE* m_iface; PNS_KICAD_IFACE* m_iface;
ROUTER* m_router; ROUTER* m_router;
bool m_cancelled;
}; };
} }

View File

@ -805,11 +805,19 @@ void ROUTER_TOOL::performRouting()
still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem ); still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
break; break;
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() else if( evt->IsCancelInteractive() || evt->IsActivate()
|| evt->IsUndoRedo() || evt->IsUndoRedo()
|| evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) ) || evt->IsAction( &PCB_ACTIONS::routerInlineDrag ) )
{
if( evt->IsCancelInteractive() && !m_router->RoutingInProgress() )
m_cancelled = true;
if( evt->IsActivate() && !evt->IsMoveTool() )
m_cancelled = true;
break; break;
} }
}
finishInteractive(); finishInteractive();
} }
@ -849,9 +857,7 @@ int ROUTER_TOOL::SettingsDialog( const TOOL_EVENT& aEvent )
void ROUTER_TOOL::breakTrack() void ROUTER_TOOL::breakTrack()
{ {
if( m_startItem && m_startItem->OfKind( PNS::ITEM::SEGMENT_T ) ) if( m_startItem && m_startItem->OfKind( PNS::ITEM::SEGMENT_T ) )
{
m_router->BreakSegment( m_startItem, m_startSnapPoint ); m_router->BreakSegment( m_startItem, m_startSnapPoint );
}
} }
@ -871,6 +877,7 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
VIEW_CONTROLS* ctls = getViewControls(); VIEW_CONTROLS* ctls = getViewControls();
ctls->ShowCursor( true ); ctls->ShowCursor( true );
ctls->ForceCursorPosition( false ); ctls->ForceCursorPosition( false );
m_cancelled = false;
m_startSnapPoint = ctls->GetCursorPosition(); m_startSnapPoint = ctls->GetCursorPosition();
std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, mode ) ); std::unique_ptr<ROUTER_TOOL_MENU> ctxMenu( new ROUTER_TOOL_MENU( *frame, mode ) );
@ -885,9 +892,23 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
{ {
frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL ); frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() )
{ {
break; // Finish frame->PopTool();
break;
}
else if( evt->IsActivate() )
{
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
frame->PopTool();
break;
}
} }
else if( evt->Action() == TA_UNDO_REDO_PRE ) else if( evt->Action() == TA_UNDO_REDO_PRE )
{ {
@ -928,15 +949,24 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
updateStartItem( *evt ); updateStartItem( *evt );
if( evt->HasPosition() )
{
if( evt->Modifier( MD_CTRL ) ) if( evt->Modifier( MD_CTRL ) )
performDragging( PNS::DM_ANY ); performDragging( PNS::DM_ANY );
else else
performRouting(); performRouting();
} }
}
else if( evt->IsAction( &ACT_PlaceThroughVia ) ) else if( evt->IsAction( &ACT_PlaceThroughVia ) )
{ {
m_toolMgr->RunAction( PCB_ACTIONS::layerToggle, true ); m_toolMgr->RunAction( PCB_ACTIONS::layerToggle, true );
} }
if( m_cancelled )
{
frame->PopTool();
break;
}
} }
SetContextMenu( nullptr ); SetContextMenu( nullptr );
@ -945,7 +975,6 @@ int ROUTER_TOOL::MainLoop( const TOOL_EVENT& aEvent )
m_savedSettings = m_router->Settings(); m_savedSettings = m_router->Settings();
m_savedSizes = m_router->Sizes(); m_savedSizes = m_router->Sizes();
frame->PopTool();
return 0; return 0;
} }
@ -991,9 +1020,14 @@ void ROUTER_TOOL::performDragging( int aMode )
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) ) if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
break; break;
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() else if( evt->IsCancelInteractive() || evt->IsActivate() || evt->IsUndoRedo() )
|| evt->IsUndoRedo() )
{ {
if( evt->IsCancelInteractive() && !m_startItem )
m_cancelled = true;
if( evt->IsActivate() && !evt->IsMoveTool() )
m_cancelled = true;
break; break;
} }
@ -1135,7 +1169,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
{ {
frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) if( evt->IsCancelInteractive() )
{ {
break; break;
} }

View File

@ -27,14 +27,10 @@
#include "pcb_actions.h" #include "pcb_actions.h"
#include <pcb_edit_frame.h> #include <pcb_edit_frame.h>
#include <class_draw_panel_gal.h>
#include <project.h> #include <project.h>
#include <id.h> #include <id.h>
#include <pcbnew_id.h>
#include <confirm.h> #include <confirm.h>
#include <import_gfx/dialog_import_gfx.h> #include <import_gfx/dialog_import_gfx.h>
#include <view/view_group.h>
#include <view/view_controls.h> #include <view/view_controls.h>
#include <view/view.h> #include <view/view.h>
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
@ -172,7 +168,6 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
line->SetFlags( IS_NEW ); line->SetFlags( IS_NEW );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -214,7 +209,6 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
startingPoint = NULLOPT; startingPoint = NULLOPT;
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -253,7 +247,6 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
immediateMode = false; immediateMode = false;
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -291,28 +284,41 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
if( reselect && text ) if( reselect && text )
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, text ); m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, text );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( text )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
// Delete the old text and have another try
delete text;
text = NULL;
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false ); m_controls->CaptureCursor( false );
m_controls->ShowCursor( true ); m_controls->ShowCursor( true );
} delete text;
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) ) text = NULL;
{ };
break;
}
if( evt->IsActivate() ) if( evt->IsCancelInteractive() )
{
if( text )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( text )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsClick( BUT_RIGHT ) ) else if( evt->IsClick( BUT_RIGHT ) )
{ {
m_menu.ShowContextMenu( selection() ); m_menu.ShowContextMenu( selection() );
@ -433,7 +439,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
} }
frame()->SetMsgPanel( board() ); frame()->SetMsgPanel( board() );
m_frame->PopTool();
return 0; return 0;
} }
@ -495,25 +500,45 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), nullptr ); VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), nullptr );
m_controls->ForceCursorPosition( true, cursorPos ); m_controls->ForceCursorPosition( true, cursorPos );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
preview.Clear();
delete dimension;
dimension = nullptr;
step = SET_ORIGIN;
};
if( evt->IsCancelInteractive() )
{ {
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
if( step != SET_ORIGIN ) // start from the beginning if( step != SET_ORIGIN ) // start from the beginning
cleanup();
else
{ {
preview.Clear(); m_frame->PopTool();
delete dimension;
step = SET_ORIGIN;
}
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break; break;
} }
}
else if( evt->IsActivate() )
{
if( step != SET_ORIGIN )
cleanup();
if( evt->IsActivate() ) if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN ) else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
{ {
m_lineWidth += WIDTH_STEP; m_lineWidth += WIDTH_STEP;
@ -647,7 +672,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_view->Remove( &preview ); m_view->Remove( &preview );
frame()->SetMsgPanel( board() ); frame()->SetMsgPanel( board() );
m_frame->PopTool();
return 0; return 0;
} }
@ -744,7 +768,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
else if( evt->Category() == TC_COMMAND ) else if( evt->Category() == TC_COMMAND )
{ {
// TODO it should be handled by EDIT_TOOL, so add items and select? // TODO it should be handled by EDIT_TOOL, so add items and select?
if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) ) if( evt->IsCancelInteractive() )
{ {
const auto rotationPoint = (wxPoint) cursorPos; const auto rotationPoint = (wxPoint) cursorPos;
const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *m_frame, *evt ); const auto rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *m_frame, *evt );
@ -761,9 +785,11 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
m_view->Update( &preview ); m_view->Update( &preview );
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
preview.FreeItems(); preview.FreeItems();
m_frame->PopTool();
break; break;
} }
} }
@ -784,7 +810,6 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
preview.Clear(); preview.Clear();
m_view->Remove( &preview ); m_view->Remove( &preview );
m_frame->PopTool();
return 0; return 0;
} }
@ -825,17 +850,20 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
// Usually, we do not need to change twice the anchor position, // Usually, we do not need to change twice the anchor position,
// so deselect the active tool // so deselect the active tool
m_frame->PopTool();
break; break;
} }
else if( evt->IsClick( BUT_RIGHT ) ) else if( evt->IsClick( BUT_RIGHT ) )
{ {
m_menu.ShowContextMenu( selection() ); m_menu.ShowContextMenu( selection() );
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{
m_frame->PopTool();
break; break;
} }
}
m_frame->PopTool();
return 0; return 0;
} }
@ -858,6 +886,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
bool direction45 = false; // 45 degrees only mode bool direction45 = false; // 45 degrees only mode
bool started = false; bool started = false;
bool cancelled = false;
bool isLocalOriginSet = ( m_frame->GetScreen()->m_LocalOrigin != VECTOR2D( 0, 0 ) ); bool isLocalOriginSet = ( m_frame->GetScreen()->m_LocalOrigin != VECTOR2D( 0, 0 ) );
VECTOR2I cursorPos = m_controls->GetMousePosition(); VECTOR2I cursorPos = m_controls->GetMousePosition();
@ -905,10 +934,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
frame()->SetMsgPanel( aGraphic ); frame()->SetMsgPanel( aGraphic );
} }
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( started )
{
preview.Clear(); preview.Clear();
m_view->Update( &preview ); m_view->Update( &preview );
delete aGraphic; delete aGraphic;
@ -916,10 +942,41 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
if( !isLocalOriginSet ) if( !isLocalOriginSet )
m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 ); m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 );
} };
if( evt->IsCancelInteractive() )
{
if( started )
cleanup();
else
{
m_frame->PopTool();
cancelled = true;
break; break;
} }
}
else if( evt->IsActivate() )
{
if( started )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
cancelled = true;
break;
}
else
{
m_frame->PopTool();
cancelled = true;
break;
}
}
else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) ) else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
{ {
m_lineWidth = getSegmentWidth( getDrawingLayer() ); m_lineWidth = getSegmentWidth( getDrawingLayer() );
@ -966,7 +1023,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
else else
{ {
auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() ); auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() );
auto mod = dyn_cast<MODULE*>( m_frame->GetModel() );
if( aGraphic->GetEnd() == aGraphic->GetStart() if( aGraphic->GetEnd() == aGraphic->GetStart()
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) || ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT )
@ -1047,7 +1103,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, OPT<VECTOR2D
m_controls->CaptureCursor( false ); m_controls->CaptureCursor( false );
m_controls->ForceCursorPosition( false ); m_controls->ForceCursorPosition( false );
return started; return cancelled;
} }
@ -1089,6 +1145,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
m_controls->SetSnapping( true ); m_controls->SetSnapping( true );
bool firstPoint = false; bool firstPoint = false;
bool cancelled = false;
// Prime the pump // Prime the pump
if( aImmediateMode ) if( aImmediateMode )
@ -1107,7 +1164,46 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), aGraphic ); VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), aGraphic );
m_controls->ForceCursorPosition( true, cursorPos ); m_controls->ForceCursorPosition( true, cursorPos );
if( evt->IsClick( BUT_LEFT ) ) auto cleanup = [&] () {
preview.Clear();
delete aGraphic;
aGraphic = nullptr;
};
if( evt->IsCancelInteractive() )
{
if( firstPoint )
cleanup();
else
{
m_frame->PopTool();
cancelled = true;
break;
}
}
else if( evt->IsActivate() )
{
if( firstPoint )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
cancelled = true;
break;
}
else
{
m_frame->PopTool();
cancelled = true;
break;
}
}
else if( evt->IsClick( BUT_LEFT ) )
{ {
if( !firstPoint ) if( !firstPoint )
{ {
@ -1141,17 +1237,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
// update, but don't step the manager state // update, but don't step the manager state
arcManager.AddPoint( cursorPos, false ); arcManager.AddPoint( cursorPos, false );
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
{
if( firstPoint )
{
preview.Clear();
delete aGraphic;
aGraphic = nullptr;
}
break;
}
else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) ) else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
{ {
m_lineWidth = getSegmentWidth( getDrawingLayer() ); m_lineWidth = getSegmentWidth( getDrawingLayer() );
@ -1208,7 +1293,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic, bool aImmediateMode )
m_controls->CaptureCursor( false ); m_controls->CaptureCursor( false );
m_controls->ForceCursorPosition( false ); m_controls->ForceCursorPosition( false );
return !arcManager.IsReset(); return cancelled;
} }
@ -1313,26 +1398,43 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), layers ); VECTOR2I cursorPos = grid.BestSnapAnchor( m_controls->GetMousePosition(), layers );
m_controls->ForceCursorPosition( true, cursorPos ); m_controls->ForceCursorPosition( true, cursorPos );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( polyGeomMgr.IsPolygonInProgress() )
{
polyGeomMgr.Reset(); polyGeomMgr.Reset();
// start again
started = false; started = false;
m_controls->SetAutoPan( false ); m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false ); m_controls->CaptureCursor( false );
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
// pre-empted by another tool, give up if( evt->IsCancelInteractive())
if( evt->IsActivate() && !TOOL_EVT_UTILS::IsPointEditor( *evt ) ) {
if( polyGeomMgr.IsPolygonInProgress() )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
else if( evt->IsActivate() )
{
if( polyGeomMgr.IsPolygonInProgress() )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool();
break;
}
}
else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) ) else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
{ {
if( zoneMode == ZONE_MODE::GRAPHIC_POLYGON ) if( zoneMode == ZONE_MODE::GRAPHIC_POLYGON )
@ -1374,7 +1476,6 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
m_controls->CaptureCursor( true ); m_controls->CaptureCursor( true );
} }
} }
} }
else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) ) else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
{ {
@ -1412,7 +1513,6 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
} // end while } // end while
m_controls->ForceCursorPosition( false ); m_controls->ForceCursorPosition( false );
m_frame->PopTool();
return 0; return 0;
} }
@ -1696,10 +1796,8 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::VIA ); SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::VIA );
frame()->PushTool( aEvent.GetCommandStr().get() ); frame()->PushTool( aEvent.GetCommandStr().get() );
doInteractiveItemPlacement( &placer, _( "Place via" ), doInteractiveItemPlacement( &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK );
IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP );
frame()->PopTool();
return 0; return 0;
} }

View File

@ -412,7 +412,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false ); m_toolMgr->RunAction( PCB_ACTIONS::updateLocalRatsnest, false );
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
restore_state = true; // Canceling the tool means that items have to be restored restore_state = true; // Canceling the tool means that items have to be restored
break; // Finish break; // Finish
@ -1135,23 +1135,40 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr ); const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
controls.ForceCursorPosition(true, cursorPos ); controls.ForceCursorPosition(true, cursorPos );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto clearRuler = [&] () {
{
if( originSet )
{
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
controls.SetAutoPan( false ); controls.SetAutoPan( false );
controls.CaptureCursor( false ); controls.CaptureCursor( false );
originSet = false; originSet = false;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( originSet )
clearRuler();
else
{
frame()->PopTool();
break; break;
} }
}
if( evt->IsActivate() ) else if( evt->IsActivate() )
{
if( originSet )
clearRuler();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
frame()->PopTool();
break;
}
}
// click or drag starts // click or drag starts
else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) ) else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
@ -1203,7 +1220,6 @@ int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
view.SetVisible( &ruler, false ); view.SetVisible( &ruler, false );
view.Remove( &ruler ); view.Remove( &ruler );
frame()->PopTool();
return 0; return 0;
} }

View File

@ -36,6 +36,12 @@ class BOARD_COMMIT;
class BOARD_ITEM; class BOARD_ITEM;
class CONNECTIVITY_DATA; class CONNECTIVITY_DATA;
namespace KIGFX {
namespace PREVIEW {
class RULER_ITEM;
}
}
/** /**
* Function EditToolSelectionFilter * Function EditToolSelectionFilter
* *
@ -196,6 +202,8 @@ private:
///> of edit reference point). ///> of edit reference point).
VECTOR2I m_cursor; VECTOR2I m_cursor;
KIGFX::PREVIEW::RULER_ITEM* m_ruler;
///> Returns the right modification point (e.g. for rotation), depending on the number of ///> Returns the right modification point (e.g. for rotation), depending on the number of
///> selected items. ///> selected items.
bool updateModificationPoint( PCBNEW_SELECTION& aSelection ); bool updateModificationPoint( PCBNEW_SELECTION& aSelection );

View File

@ -318,7 +318,6 @@ int MODULE_EDITOR_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
doInteractiveItemPlacement( &placer, _( "Place pad" ), doInteractiveItemPlacement( &placer, _( "Place pad" ),
IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP ); IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP );
frame()->PopTool();
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2017-2019 Kicad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -38,7 +38,6 @@
#include <microwave/microwave_inductor.h> #include <microwave/microwave_inductor.h>
#include "pcb_actions.h" #include "pcb_actions.h"
#include "selection_tool.h" #include "selection_tool.h"
#include "tool_event_utils.h"
MICROWAVE_TOOL::MICROWAVE_TOOL() : MICROWAVE_TOOL::MICROWAVE_TOOL() :
@ -58,71 +57,44 @@ void MICROWAVE_TOOL::Reset( RESET_REASON aReason )
int MICROWAVE_TOOL::addMicrowaveFootprint( const TOOL_EVENT& aEvent ) int MICROWAVE_TOOL::addMicrowaveFootprint( const TOOL_EVENT& aEvent )
{ {
auto& frame = *getEditFrame<PCB_EDIT_FRAME>(); PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
std::function<std::unique_ptr<MODULE>()> creator;
switch( aEvent.Parameter<intptr_t>() )
{
case MWAVE_TOOL_SIMPLE_ID::GAP:
creator = [&frame] () {
return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 0 ) );
};
break;
case MWAVE_TOOL_SIMPLE_ID::STUB:
creator = [&frame] () {
return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 1 ) );
};
break;
case MWAVE_TOOL_SIMPLE_ID::STUB_ARC:
creator = [&frame] () {
return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 2 ) );
};
break;
case MWAVE_TOOL_SIMPLE_ID::FUNCTION_SHAPE:
creator = [&frame] () {
return std::unique_ptr<MODULE>( frame.Create_MuWavePolygonShape() );
};
break;
default:
break;
};
struct MICROWAVE_PLACER : public INTERACTIVE_PLACER_BASE struct MICROWAVE_PLACER : public INTERACTIVE_PLACER_BASE
{ {
const std::function<std::unique_ptr<MODULE>()>& m_creator; MICROWAVE_PLACER( PCB_EDIT_FRAME* aFrame, int aType ) :
m_frame( aFrame ),
MICROWAVE_PLACER( const std::function<std::unique_ptr<MODULE>()>& aCreator ) : m_itemType( aType )
m_creator( aCreator ) {}; { };
std::unique_ptr<BOARD_ITEM> CreateItem() override std::unique_ptr<BOARD_ITEM> CreateItem() override
{ {
auto module = m_creator(); switch( m_itemType )
// Module has been added in the legacy backend,
// so we have to remove it before committing the change
// @todo LEGACY
if( module )
{ {
m_board->Remove( module.get() ); case MWAVE_TOOL_SIMPLE_ID::GAP:
return std::unique_ptr<MODULE>( m_frame->Create_MuWaveComponent( 0 ) );
case MWAVE_TOOL_SIMPLE_ID::STUB:
return std::unique_ptr<MODULE>( m_frame->Create_MuWaveComponent( 1 ) );
case MWAVE_TOOL_SIMPLE_ID::STUB_ARC:
return std::unique_ptr<MODULE>( m_frame->Create_MuWaveComponent( 2 ) );
case MWAVE_TOOL_SIMPLE_ID::FUNCTION_SHAPE:
return std::unique_ptr<MODULE>( m_frame->Create_MuWavePolygonShape() );
default:
return std::unique_ptr<MODULE>();
};
} }
return std::unique_ptr<BOARD_ITEM>( module.release() ); private:
} PCB_EDIT_FRAME* m_frame;
int m_itemType;
}; };
MICROWAVE_PLACER placer( creator ); MICROWAVE_PLACER placer( frame, aEvent.Parameter<intptr_t>() );
frame.PushTool( aEvent.GetCommandStr().get() ); frame->PushTool( aEvent.GetCommandStr().get() );
doInteractiveItemPlacement( &placer, _( "Place microwave feature" ), doInteractiveItemPlacement( &placer, _( "Place microwave feature" ),
IPO_REPEAT | IPO_SINGLE_CLICK | IPO_ROTATE | IPO_FLIP | IPO_PROPERTIES ); IPO_REPEAT | IPO_ROTATE | IPO_FLIP );
frame.PopTool();
return 0; return 0;
} }
@ -212,31 +184,44 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
frame.GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL ); frame.GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
VECTOR2I cursorPos = controls.GetCursorPosition(); VECTOR2I cursorPos = controls.GetCursorPosition();
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( originSet )
{
// had an in-progress area, so start again but don't
// cancel the tool
originSet = false; originSet = false;
controls.CaptureCursor( false ); controls.CaptureCursor( false );
controls.SetAutoPan( false ); controls.SetAutoPan( false );
view.SetVisible( &previewRect, false ); view.SetVisible( &previewRect, false );
view.Update( &previewRect, KIGFX::GEOMETRY ); view.Update( &previewRect, KIGFX::GEOMETRY );
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( originSet )
cleanup();
else
{
frame.PopTool();
break; break;
} }
}
if( evt->IsActivate() ) else if( evt->IsActivate() )
{
if( originSet )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
frame.PopTool();
break;
}
}
// A click or drag starts // A click or drag starts
else if( !originSet && else if( !originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) ) )
( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) ) )
{ {
tpGeomMgr.SetOrigin( cursorPos ); tpGeomMgr.SetOrigin( cursorPos );
tpGeomMgr.SetEnd( cursorPos ); tpGeomMgr.SetEnd( cursorPos );
@ -283,7 +268,6 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
controls.CaptureCursor( false ); controls.CaptureCursor( false );
controls.SetAutoPan( false ); controls.SetAutoPan( false );
view.Remove( &previewRect ); view.Remove( &previewRect );
frame.PopTool();
return 0; return 0;
} }

View File

@ -366,7 +366,24 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
{ {
frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_BULLSEYE ); frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_BULLSEYE );
if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) if( evt->IsCancelInteractive() )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
commit.Revert();
frame()->PopTool();
break;
}
else if( evt->IsActivate() )
{
commit.Push( _( "Renumber pads" ) );
frame()->PopTool();
break;
}
else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
{ {
selectedPads.clear(); selectedPads.clear();
VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); VECTOR2I cursorPos = getViewControls()->GetCursorPosition();
@ -471,22 +488,6 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
break; break;
} }
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;
}
else if( evt->IsClick( BUT_RIGHT ) ) else if( evt->IsClick( BUT_RIGHT ) )
{ {
m_menu.ShowContextMenu( selection() ); m_menu.ShowContextMenu( selection() );
@ -505,7 +506,6 @@ int PAD_TOOL::EnumeratePads( const TOOL_EVENT& aEvent )
} }
statusPopup.Hide(); statusPopup.Hide();
frame()->PopTool();
return 0; return 0;
} }

View File

@ -185,7 +185,7 @@ TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
_( "Edit Activate" ), "", _( "Edit Activate" ), "",
move_xpm, AF_ACTIVATE ); move_xpm, AF_ACTIVATE );
TOOL_ACTION PCB_ACTIONS::move( "pcbnew.InteractiveEdit.move", TOOL_ACTION PCB_ACTIONS::move( "pcbnew.InteractiveMove.move",
AS_GLOBAL, AS_GLOBAL,
'M', LEGACY_HK_NAME( "Move Item" ), 'M', LEGACY_HK_NAME( "Move Item" ),
_( "Move" ), _( "Moves the selected item(s)" ), _( "Move" ), _( "Moves the selected item(s)" ),

View File

@ -542,22 +542,39 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
if( reselect && module ) if( reselect && module )
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, module ); m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, module );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) auto cleanup = [&] () {
{
if( module )
{
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
commit.Revert(); commit.Revert();
module = NULL; module = NULL;
} };
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
if( evt->IsCancelInteractive() )
{ {
if( module )
cleanup();
else
{
m_frame->PopTool();
break; break;
} }
}
if( evt->IsActivate() ) // now finish unconditionally else if( evt->IsActivate() )
{
if( module )
cleanup();
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break; break;
} }
else
{
frame()->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
@ -620,7 +637,6 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
controls->CaptureCursor( !!module ); controls->CaptureCursor( !!module );
} }
m_frame->PopTool();
return 0; return 0;
} }
@ -719,11 +735,26 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW ); frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
cursorPos = controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); cursorPos = controls->GetCursorPosition( !evt->Modifier( MD_ALT ) );
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() )
{ {
frame()->PopTool();
break; break;
} }
else if( evt->IsActivate() )
{
if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
frame()->PopTool();
break;
}
}
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) ) else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
{ {
target->SetWidth( target->GetWidth() + WIDTH_STEP ); target->SetWidth( target->GetWidth() + WIDTH_STEP );
@ -772,7 +803,6 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
delete target; delete target;
view->Remove( &preview ); view->Remove( &preview );
controls->SetSnapping( false ); controls->SetSnapping( false );
m_frame->PopTool();
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -57,65 +57,13 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer
aPlacer->m_frame = frame(); aPlacer->m_frame = frame();
aPlacer->m_modifiers = 0; aPlacer->m_modifiers = 0;
if( aOptions & IPO_SINGLE_CLICK && !( aOptions & IPO_PROPERTIES ) ) auto makeNewItem = [&] ( VECTOR2I aPosition )
{ {
VECTOR2I cursorPos = controls()->GetCursorPosition();
newItem = aPlacer->CreateItem(); newItem = aPlacer->CreateItem();
if( newItem ) if( newItem )
{ {
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); newItem->SetPosition( (wxPoint) aPosition );
preview.Add( newItem.get() );
}
}
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
VECTOR2I cursorPos = controls()->GetCursorPosition();
aPlacer->m_modifiers = evt->Modifier();
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() )
{
if( newItem )
{
// Delete the old item and have another try
newItem = nullptr;
preview.Clear();
controls()->SetAutoPan( false );
controls()->CaptureCursor( false );
controls()->ShowCursor( true );
if( aOptions & IPO_SINGLE_CLICK )
break;
}
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
{
break;
}
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !newItem )
{
// create the item if possible
newItem = aPlacer->CreateItem();
// no item created, so wait for another click
if( !newItem )
continue;
controls()->CaptureCursor( true );
controls()->SetAutoPan( true );
newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
preview.Add( newItem.get() ); preview.Add( newItem.get() );
if( newItem->Type() == PCB_MODULE_T ) if( newItem->Type() == PCB_MODULE_T )
@ -126,6 +74,77 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer
module->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) ); module->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
} }
} }
};
if( aOptions & IPO_SINGLE_CLICK )
makeNewItem( controls()->GetCursorPosition() );
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
VECTOR2I cursorPos = controls()->GetCursorPosition();
aPlacer->m_modifiers = evt->Modifier();
auto cleanup = [&] ()
{
newItem = nullptr;
preview.Clear();
view()->Update( &preview );
controls()->SetAutoPan( false );
controls()->CaptureCursor( false );
controls()->ShowCursor( true );
};
if( evt->IsCancelInteractive() )
{
if( aOptions & IPO_SINGLE_CLICK )
{
cleanup();
frame()->PopTool();
break;
}
else if( newItem )
cleanup();
else
{
frame()->PopTool();
break;
}
}
else if( evt->IsActivate() )
{
if( newItem )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
frame()->PopTool();
break;
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !newItem )
{
// create the item if possible
makeNewItem( cursorPos );
// no item created, so wait for another click
if( !newItem )
continue;
controls()->CaptureCursor( true );
controls()->SetAutoPan( true );
}
else else
{ {
auto oldFlags = newItem->GetFlags(); auto oldFlags = newItem->GetFlags();
@ -137,14 +156,7 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer
continue; continue;
} }
preview.Remove( newItem.get() ); preview.Clear();
if( newItem->Type() == PCB_MODULE_T )
{
auto module = dyn_cast<MODULE*>( newItem.get() );
module->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Remove, &preview, _1 ) );
}
newItem.release(); newItem.release();
commit.Push( aCommitMessage ); commit.Push( aCommitMessage );
@ -155,18 +167,8 @@ void PCB_TOOL_BASE::doInteractiveItemPlacement( INTERACTIVE_PLACER_BASE* aPlacer
if( !( aOptions & IPO_REPEAT ) ) if( !( aOptions & IPO_REPEAT ) )
break; break;
if( aOptions & IPO_SINGLE_CLICK && !( aOptions & IPO_PROPERTIES ) ) if( aOptions & IPO_SINGLE_CLICK )
{ makeNewItem( controls()->GetCursorPosition() );
VECTOR2I pos = controls()->GetCursorPosition();
newItem = aPlacer->CreateItem();
if( newItem )
{
newItem->SetPosition( wxPoint( pos.x, pos.y ) );
preview.Add( newItem.get() );
}
}
} }
} }
else if( evt->IsClick( BUT_RIGHT ) ) else if( evt->IsClick( BUT_RIGHT ) )

View File

@ -109,9 +109,8 @@ protected:
enum INTERACTIVE_PLACEMENT_OPTIONS { enum INTERACTIVE_PLACEMENT_OPTIONS {
IPO_ROTATE = 1, IPO_ROTATE = 1,
IPO_FLIP = 2, IPO_FLIP = 2,
IPO_PROPERTIES = 4, IPO_SINGLE_CLICK = 4,
IPO_SINGLE_CLICK = 8, IPO_REPEAT = 8
IPO_REPEAT = 16
}; };

View File

@ -100,7 +100,7 @@ int PCBNEW_PICKER_TOOL::Main( const TOOL_EVENT& aEvent )
} }
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( m_cancelHandler ) if( m_cancelHandler )
{ {

View File

@ -338,7 +338,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
grid.SetUseGrid( !evt->Modifier( MD_ALT ) ); grid.SetUseGrid( !evt->Modifier( MD_ALT ) );
controls->SetSnapping( !evt->Modifier( MD_ALT ) ); controls->SetSnapping( !evt->Modifier( MD_ALT ) );
if( !m_editPoints || TOOL_EVT_UTILS::IsSelectionEvent( *evt ) ) if( !m_editPoints || evt->IsSelectionEvent() )
break; break;
if ( !inDrag ) if ( !inDrag )
@ -387,11 +387,14 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
m_refill = true; m_refill = true;
} }
else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) else if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
if( inDrag ) // Restore the last change if( inDrag ) // Restore the last change
commit.Revert(); commit.Revert();
else if( evt->IsCancelInteractive() )
break;
if( evt->IsActivate() && !evt->IsMoveTool() )
break; break;
} }

View File

@ -515,7 +515,7 @@ bool SELECTION_TOOL::selectMultiple()
while( TOOL_EVENT* evt = Wait() ) while( TOOL_EVENT* evt = Wait() )
{ {
if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) if( evt->IsCancelInteractive() || evt->IsActivate() )
{ {
cancelled = true; cancelled = true;
break; break;

View File

@ -296,7 +296,8 @@ static void CheckInvalidsMatchExpected( BOARD& aBoard,
{ {
KI_TEST::CheckUnorderedMatches( aExpInvalids, aMarkers, KI_TEST::CheckUnorderedMatches( aExpInvalids, aMarkers,
[&]( const COURTYARD_INVALID_INFO& aInvalid, [&]( const COURTYARD_INVALID_INFO& aInvalid,
const std::unique_ptr<MARKER_PCB>& aMarker ) { const std::unique_ptr<MARKER_PCB>& aMarker )
{
return InvalidMatchesExpected( aBoard, *aMarker, aInvalid ); return InvalidMatchesExpected( aBoard, *aMarker, aInvalid );
} ); } );
} }