← Back to team overview

kicad-developers team mailing list archive

[PATCH] Add cancel interactive tool to GAL

 

Hi,

This adds a new action to the common ACTIONS tools: cancelInteractive.

This is an action which can be called to terminate an ongoing
interactive tool, for example a drawing tool. The action is can be
used pretty much everywhere that the generic IsCancel() event can, but
also allows adding an entry to tool menus.

The router tool has the current behaviour with this action - it just
ends and rips up back to the last placed node - same as pressing Esc.
Undoing the whole track is a different issue entirely.

Cheers,

John
From c8d91e1012d039edeb0d862859748f4ee5f4451e Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Tue, 7 Feb 2017 00:00:51 +0800
Subject: [PATCH] Add cancel interactive tool action to GAL

This is used to provide menu entries that allows cancellation of
interactive drawing and routing tools without needing the keyboard.

It is provided in the drawing tools and the router tool.

The cancel event doesn't have any new functionality (e.g. track rip-up
for the PNS router - lp:1448460), this just adds it to the menu, where
it behaves the same as an Escape keypress.
---
 common/tool/actions.cpp           |  6 ++++++
 include/tool/actions.h            |  3 +++
 pcbnew/router/router_tool.cpp     | 14 +++++++++++---
 pcbnew/tools/drawing_tool.cpp     | 24 +++++++++++++++++-------
 pcbnew/tools/tool_event_utils.cpp |  6 ++++++
 pcbnew/tools/tool_event_utils.h   |  9 +++++++++
 6 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/common/tool/actions.cpp b/common/tool/actions.cpp
index ad7cbfb6e..2bd8661d3 100644
--- a/common/tool/actions.cpp
+++ b/common/tool/actions.cpp
@@ -4,6 +4,12 @@
 
 // These members are static in class ACTIONS: Build them here:
 
+// Generic Actions
+TOOL_ACTION ACTIONS::cancelInteractive( "common.Interactive.cancel",
+        AS_GLOBAL, 0,   // ESC key is handled in the dispatcher
+        _( "Cancel" ), _( "Cancel current tool" ),
+        cancel_xpm, AF_NONE );
+
 // View Controls
 TOOL_ACTION ACTIONS::zoomIn( "common.Control.zoomIn",
         AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZOOM_IN ),
diff --git a/include/tool/actions.h b/include/tool/actions.h
index 8747ea1e1..114c7f0a7 100644
--- a/include/tool/actions.h
+++ b/include/tool/actions.h
@@ -44,6 +44,9 @@ public:
 
     virtual ~ACTIONS() {};
 
+    // Generic actions
+    static TOOL_ACTION cancelInteractive;
+
     // View controls
     static TOOL_ACTION zoomIn;
     static TOOL_ACTION zoomOut;
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
index e568f5ab7..024e12e86 100644
--- a/pcbnew/router/router_tool.cpp
+++ b/pcbnew/router/router_tool.cpp
@@ -52,6 +52,7 @@ using namespace std::placeholders;
 #include <tools/edit_tool.h>
 #include <tools/grid_menu.h>
 #include <tools/zoom_menu.h>
+#include <tools/tool_event_utils.h>
 
 #include <ratsnest_data.h>
 
@@ -257,6 +258,11 @@ public:
         m_widthMenu( aBoard ), m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
     {
         SetTitle( _( "Interactive Router" ) );
+
+        Add( ACTIONS::cancelInteractive );
+
+        AppendSeparator();
+
         Add( ACT_NewTrack );
         Add( ACT_EndTrack );
 //        Add( ACT_AutoEndRoute );  // fixme: not implemented yet. Sorry.
@@ -636,7 +642,8 @@ void ROUTER_TOOL::performRouting()
                 still_routing = m_router->FixRoute( m_endSnapPoint, m_endItem );
             break;
         }
-        else if( evt->IsCancel() || evt->IsActivate() || evt->IsUndoRedo() )
+        else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
+                 || evt->IsUndoRedo() )
             break;
     }
 
@@ -731,7 +738,7 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
     // Main loop: keep receiving events
     while( OPT_TOOL_EVENT evt = Wait() )
     {
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             break; // Finish
         }
@@ -816,7 +823,8 @@ void ROUTER_TOOL::performDragging()
             if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
                 break;
         }
-        else if( evt->IsCancel() || evt->IsActivate() || evt->IsUndoRedo() )
+        else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )
+                 || evt->IsUndoRedo() )
             break;
 
         handleCommonEvents( *evt );
diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp
index 093af47f7..fea754ecd 100644
--- a/pcbnew/tools/drawing_tool.cpp
+++ b/pcbnew/tools/drawing_tool.cpp
@@ -136,6 +136,16 @@ DRAWING_TOOL::~DRAWING_TOOL()
 
 bool DRAWING_TOOL::Init()
 {
+    auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) {
+        return m_mode != MODE::NONE;
+    };
+
+    auto& ctxMenu = m_menu.GetMenu();
+
+    // cancel current toool goes in main context menu at the top if present
+    ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolFunctor, 1000 );
+    ctxMenu.AddSeparator( activeToolFunctor, 1000 );
+
     // Drawing type-specific options will be added by the PCB control tool
     m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
 
@@ -278,7 +288,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
     {
         VECTOR2I cursorPos = m_controls->GetCursorPosition();
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             if( text )
             {
@@ -458,7 +468,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
     {
         VECTOR2I cursorPos = m_controls->GetCursorPosition();
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             if( step != SET_ORIGIN )    // start from the beginning
             {
@@ -714,7 +724,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
 
                 m_view->Update( &preview );
             }
-            else if( evt->IsCancel() || evt->IsActivate() )
+            else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
             {
                 preview.FreeItems();
                 break;
@@ -862,7 +872,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
         {
             m_menu.ShowContextMenu();
         }
-        else if( evt->IsCancel() || evt->IsActivate() )
+        else if( TOOL_EVT_UTILS::IsCancelInteractive( *evt )  )
             break;
     }
 
@@ -944,7 +954,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
             m_view->Update( &preview );
         }
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             preview.Clear();
             m_view->Update( &preview );
@@ -1086,7 +1096,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
     {
         cursorPos = m_controls->GetCursorPosition();
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             preview.Clear();
             delete aGraphic;
@@ -1386,7 +1396,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout, ZONE_MODE aMode )
             m_view->Update( &preview );
         }
 
-        if( evt->IsCancel() || evt->IsActivate() )
+        if( TOOL_EVT_UTILS::IsCancelInteractive( *evt ) )
         {
             if( numPoints > 0 )         // cancel the current zone
             {
diff --git a/pcbnew/tools/tool_event_utils.cpp b/pcbnew/tools/tool_event_utils.cpp
index 7c93a859e..7abe83a98 100644
--- a/pcbnew/tools/tool_event_utils.cpp
+++ b/pcbnew/tools/tool_event_utils.cpp
@@ -27,6 +27,12 @@
 
 #include <pcb_base_edit_frame.h>
 
+bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt )
+{
+    return aEvt.IsAction( &ACTIONS::cancelInteractive )
+            || aEvt.IsActivate()
+            || aEvt.IsCancel();
+}
 
 bool TOOL_EVT_UTILS::IsRotateToolEvt( const TOOL_EVENT& aEvt )
 {
diff --git a/pcbnew/tools/tool_event_utils.h b/pcbnew/tools/tool_event_utils.h
index 308542454..d633d281e 100644
--- a/pcbnew/tools/tool_event_utils.h
+++ b/pcbnew/tools/tool_event_utils.h
@@ -41,6 +41,15 @@ class PCB_BASE_EDIT_FRAME;
 namespace TOOL_EVT_UTILS
 {
     /**
+     * Function IsCancelInteractive()
+     *
+     * @return true if this 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 isRotateToolEvt()
      *
      * @param aEvt event to check
-- 
2.11.0


Follow ups