From 53e705f634193e4598237178a689c5a994dab7f3 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 11 Feb 2018 01:15:16 +0000 Subject: [PATCH] Add Get and Move Footprint to empty-selection-context menu. Also adds Cancel context menu items for Place Footprint, Place Target, Place Drill Origin and Place Grid Origin tools, as well as the standard Zoom and Grid choices. Removes the Paste context menu item from the Place Drill and Place Grid Origin tools. Fixes: lp:1568396 * https://bugs.launchpad.net/kicad/+bug/1568396 --- pcbnew/tools/edit_tool.cpp | 10 ++++-- pcbnew/tools/pcb_editor_control.cpp | 47 +++++++++++++++++++++++++++-- pcbnew/tools/pcb_editor_control.h | 4 +++ pcbnew/tools/picker_tool.cpp | 28 ++++++++++++++++- pcbnew/tools/picker_tool.h | 3 ++ pcbnew/tools/selection_tool.cpp | 5 +-- 6 files changed, 89 insertions(+), 8 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 6278911fea..10947d3caf 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -287,6 +287,10 @@ bool EDIT_TOOL::Init() auto singleModuleCondition = SELECTION_CONDITIONS::OnlyType( PCB_MODULE_T ) && SELECTION_CONDITIONS::Count( 1 ); + auto noActiveToolCondition = [ this ] ( const SELECTION& aSelection ) { + return ( frame()->GetToolId() == ID_NO_TOOL_SELECTED ); + }; + // Add context menu entries that are displayed when selection tool is active CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu(); @@ -309,8 +313,10 @@ bool EDIT_TOOL::Init() menu.AddItem( PCB_ACTIONS::copyToClipboard, SELECTION_CONDITIONS::NotEmpty ); menu.AddItem( PCB_ACTIONS::cutToClipboard, SELECTION_CONDITIONS::NotEmpty ); - menu.AddItem( PCB_ACTIONS::pasteFromClipboard ); - menu.AddSeparator(); + // Selection tool handles the context menu for some other tools, such as the Picker. + // Don't add things like Paste when another tool is active. + menu.AddItem( PCB_ACTIONS::pasteFromClipboard, noActiveToolCondition ); + menu.AddSeparator( noActiveToolCondition ); // Mirror only available in modedit menu.AddItem( PCB_ACTIONS::mirror, editingModuleCondition && SELECTION_CONDITIONS::NotEmpty ); diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index a0af906f71..78f05ecf3c 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -226,7 +226,8 @@ public: PCB_EDITOR_CONTROL::PCB_EDITOR_CONTROL() : PCB_TOOL( "pcbnew.EditorControl" ), - m_frame( nullptr ) + m_frame( nullptr ), + m_menu( *this ) { m_placeOrigin.reset( new KIGFX::ORIGIN_VIEWITEM( KIGFX::COLOR4D( 0.8, 0.0, 0.0, 1.0 ), KIGFX::ORIGIN_VIEWITEM::CIRCLE_CROSS ) ); @@ -255,6 +256,31 @@ void PCB_EDITOR_CONTROL::Reset( RESET_REASON aReason ) bool PCB_EDITOR_CONTROL::Init() { + auto activeToolCondition = [ this ] ( const SELECTION& aSel ) { + return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED ); + }; + + auto inactiveStateCondition = [ this ] ( const SELECTION& aSel ) { + return ( m_frame->GetToolId() == ID_NO_TOOL_SELECTED && aSel.Size() == 0 ); + }; + + auto placeModuleCondition = [ this ] ( const SELECTION& aSel ) { + return ( m_frame->GetToolId() == ID_PCB_MODULE_BUTT && aSel.GetSize() == 0 ); + }; + + auto& ctxMenu = m_menu.GetMenu(); + + // "Cancel" goes at the top of the context menu when a tool is active + ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1000 ); + ctxMenu.AddSeparator( activeToolCondition, 1000 ); + + // "Get and Place Footprint" should be available for Place Footprint tool + ctxMenu.AddItem( PCB_ACTIONS::findMove, placeModuleCondition, 1000 ); + ctxMenu.AddSeparator( placeModuleCondition, 1000 ); + + // Finally, add the standard zoom & grid items + m_menu.AddStandardSubMenus( *getEditFrame() ); + auto zoneMenu = std::make_shared(); zoneMenu->SetTool( this ); @@ -270,6 +296,10 @@ bool PCB_EDITOR_CONTROL::Init() auto& toolMenu = selTool->GetToolMenu(); auto& menu = toolMenu.GetMenu(); + // Add "Get and Place Footprint" when Selection tool is in an inactive state + menu.AddItem( PCB_ACTIONS::findMove, inactiveStateCondition ); + menu.AddSeparator( inactiveStateCondition ); + toolMenu.AddSubMenu( zoneMenu ); toolMenu.AddSubMenu( lockMenu ); @@ -413,7 +443,7 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) if( reselect && module ) m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, module ); - if( evt->IsCancel() || evt->IsActivate() ) + if( evt->IsCancel() || TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) { if( module ) { @@ -459,6 +489,11 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) controls->CaptureCursor( placing ); } + else if( evt->IsClick( BUT_RIGHT ) ) + { + m_menu.ShowContextMenu( selTool->GetSelection() ); + } + else if( module && evt->IsMotion() ) { module->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); @@ -541,6 +576,7 @@ int PCB_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode ) int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) { + auto selTool = m_toolMgr->GetTool(); KIGFX::VIEW* view = getView(); KIGFX::VIEW_CONTROLS* controls = getViewControls(); BOARD* board = getModel(); @@ -569,7 +605,7 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) { cursorPos = controls->GetCursorPosition(); - if( evt->IsCancel() || evt->IsActivate() ) + if( evt->IsCancel() || TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) break; else if( evt->IsAction( &PCB_ACTIONS::incWidth ) ) @@ -605,6 +641,11 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent ) preview.Add( target ); } + else if( evt->IsClick( BUT_RIGHT ) ) + { + m_menu.ShowContextMenu( selTool->GetSelection() ); + } + else if( evt->IsMotion() ) { target->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h index 9027de6978..91fb25b05d 100644 --- a/pcbnew/tools/pcb_editor_control.h +++ b/pcbnew/tools/pcb_editor_control.h @@ -26,6 +26,7 @@ #define PCB_EDITOR_CONTROL_H #include +#include namespace KIGFX { class ORIGIN_VIEWITEM; @@ -128,6 +129,9 @@ private: ///> Pointer to the currently used edit frame. PCB_EDIT_FRAME* m_frame; + /// Menu model displayed by the tool. + TOOL_MENU m_menu; + ///> Place & drill origin marker. std::unique_ptr m_placeOrigin; diff --git a/pcbnew/tools/picker_tool.cpp b/pcbnew/tools/picker_tool.cpp index 79b5913030..bf3c2eb97c 100644 --- a/pcbnew/tools/picker_tool.cpp +++ b/pcbnew/tools/picker_tool.cpp @@ -29,6 +29,9 @@ #include #include #include +#include "tool_event_utils.h" +#include "selection_tool.h" + TOOL_ACTION PCB_ACTIONS::pickerTool( "pcbnew.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE ); @@ -40,6 +43,29 @@ PICKER_TOOL::PICKER_TOOL() } +bool PICKER_TOOL::Init() +{ + auto activeToolCondition = [ this ] ( const SELECTION& aSel ) { + return ( frame()->GetToolId() != ID_NO_TOOL_SELECTED ); + }; + + SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + + // We delegate our context menu to the Selection tool, so make sure it has a + // "Cancel" item at the top. + if( selTool ) + { + auto& toolMenu = selTool->GetToolMenu(); + auto& menu = toolMenu.GetMenu(); + + menu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1000 ); + menu.AddSeparator( activeToolCondition, 1000 ); + } + + return true; +} + + int PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) { KIGFX::VIEW_CONTROLS* controls = getViewControls(); @@ -83,7 +109,7 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) setControls(); } - else if( evt->IsCancel() || evt->IsActivate() ) + else if( evt->IsCancel() || TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) break; else diff --git a/pcbnew/tools/picker_tool.h b/pcbnew/tools/picker_tool.h index 9cdc74a740..f92c01b580 100644 --- a/pcbnew/tools/picker_tool.h +++ b/pcbnew/tools/picker_tool.h @@ -40,6 +40,9 @@ public: ///> Mouse event click handler type. typedef std::function CLICK_HANDLER; + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init() override; + ///> @copydoc TOOL_INTERACTIVE::Reset() void Reset( RESET_REASON aReason ) override {} diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index c8ce568c19..33e3d32005 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -117,7 +117,9 @@ TOOL_ACTION PCB_ACTIONS::find( "pcbnew.InteractiveSelection.Find", _( "Find Item..." ),_( "Searches the document for an item" ), find_xpm ); TOOL_ACTION PCB_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove", - AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_GET_AND_MOVE_FOOTPRINT ) ); + AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_GET_AND_MOVE_FOOTPRINT ), + _( "Get and Move Footprint" ), + _( "Selects a footprint by reference and places it under the cursor for moving")); TOOL_ACTION PCB_ACTIONS::filterSelection( "pcbnew.InteractiveSelection.FilterSelection", AS_GLOBAL, 0, @@ -204,7 +206,6 @@ bool SELECTION_TOOL::Init() auto& menu = m_menu.GetMenu(); menu.AddMenu( selectMenu.get(), false, SELECTION_CONDITIONS::NotEmpty ); - // only show separator if there is a Select menu to show above it menu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 1000 ); auto frame = getEditFrame();