From 1efd75ca799ea844b4df46e1e3d98c585fe989d8 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Thu, 17 Aug 2023 09:25:26 -0400 Subject: [PATCH] ADDED: Multi-layer object snapping Default hotkey Shift+S toggles on/off Fixes https://gitlab.com/kicad/code/kicad/-/issues/6266 --- pcbnew/pcbnew_settings.cpp | 10 +++++-- pcbnew/pcbnew_settings.h | 4 ++- pcbnew/tools/pcb_actions.cpp | 24 ++++++++++++++++ pcbnew/tools/pcb_actions.h | 14 ++++++++++ pcbnew/tools/pcb_control.cpp | 47 ++++++++++++++++++++++++++++++++ pcbnew/tools/pcb_control.h | 4 +++ pcbnew/tools/pcb_grid_helper.cpp | 2 +- 7 files changed, 100 insertions(+), 5 deletions(-) diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp index 33b92b5f88..a6d241d774 100644 --- a/pcbnew/pcbnew_settings.cpp +++ b/pcbnew/pcbnew_settings.cpp @@ -86,9 +86,10 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() m_FootprintViewerLibListWidth( 200 ), m_FootprintViewerFPListWidth( 300 ) { - m_MagneticItems.pads = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; - m_MagneticItems.tracks = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; - m_MagneticItems.graphics = false; + m_MagneticItems.pads = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; + m_MagneticItems.tracks = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; + m_MagneticItems.graphics = false; + m_MagneticItems.allLayers = false; m_params.emplace_back( new PARAM( "aui.show_layer_manager", &m_AuiPanels.show_layer_manager, true ) ); @@ -161,6 +162,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() reinterpret_cast( &m_MagneticItems.tracks ), static_cast( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ) ) ); + m_params.emplace_back( new PARAM( "editing.magnetic_all_layers", + &m_MagneticItems.allLayers, false ) ); + m_params.emplace_back( new PARAM( "editing.polar_coords", &m_PolarCoords, false ) ); diff --git a/pcbnew/pcbnew_settings.h b/pcbnew/pcbnew_settings.h index de7a0a50b6..669dac1a27 100644 --- a/pcbnew/pcbnew_settings.h +++ b/pcbnew/pcbnew_settings.h @@ -63,11 +63,13 @@ struct MAGNETIC_SETTINGS MAGNETIC_OPTIONS pads; MAGNETIC_OPTIONS tracks; bool graphics; + bool allLayers; MAGNETIC_SETTINGS() : pads( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ), tracks( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ), - graphics( false ) + graphics( false ), + allLayers( false ) { } }; diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 4a25ae7454..55e7dc54ea 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -255,6 +255,26 @@ TOOL_ACTION PCB_ACTIONS::arcPosture( "pcbnew.InteractiveDrawing.arcPosture", '/', LEGACY_HK_NAME( "Switch Track Posture" ), _( "Switch Arc Posture" ), _( "Switch the arc posture" ) ); + +TOOL_ACTION PCB_ACTIONS::magneticSnapActiveLayer( TOOL_ACTION_ARGS() + .Name( "common.Control.magneticSnapActiveLayer" ) + .Scope( AS_GLOBAL ) + .MenuText( _( "Snap to objects on the active layer only" ) ) + .Tooltip( _( "Enables snapping to objects on the active layer only" ) ) ); + +TOOL_ACTION PCB_ACTIONS::magneticSnapAllLayers( TOOL_ACTION_ARGS() + .Name( "common.Control.magneticSnapAllLayers" ) + .Scope( AS_GLOBAL ) + .MenuText( _( "Snap to objects on all layers" ) ) + .Tooltip( _( "Enables snapping to objects on all visible layers" ) ) ); + +TOOL_ACTION PCB_ACTIONS::magneticSnapToggle( TOOL_ACTION_ARGS() + .Name( "common.Control.magneticSnapToggle" ) + .Scope( AS_GLOBAL ) + .DefaultHotkey( MD_SHIFT + 'S' ) + .MenuText( _( "Toggle snapping between active and all layers" ) ) + .Tooltip( _( "Toggles between snapping on all visible layers and only the active area" ) ) ); + TOOL_ACTION PCB_ACTIONS::deleteLastPoint( "pcbnew.InteractiveDrawing.deleteLastPoint", AS_CONTEXT, WXK_BACK, "", @@ -1889,3 +1909,7 @@ TOOL_ACTION PCB_ACTIONS::ddAppendBoard( "pcbnew.Control.DdAppendBoard", TOOL_ACTION PCB_ACTIONS::ddImportFootprint( "pcbnew.Control.ddImportFootprint", AS_GLOBAL ); + + +const TOOL_EVENT PCB_EVENTS::SnappingModeChangedByKeyEvent( TC_MESSAGE, TA_ACTION, + "common.Interactive.snappingModeChangedByKey" ); diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 36119350e7..48ea453cf5 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -217,6 +217,11 @@ public: /// Switch posture when drawing arc static TOOL_ACTION arcPosture; + /// Snapping controls + static TOOL_ACTION magneticSnapActiveLayer; + static TOOL_ACTION magneticSnapAllLayers; + static TOOL_ACTION magneticSnapToggle; + // Push and Shove Router Tool /// Activation of the Push and Shove router @@ -547,6 +552,15 @@ public: /// Drag and drop static TOOL_ACTION ddAppendBoard; static TOOL_ACTION ddImportFootprint; + + +}; + +class PCB_EVENTS +{ +public: + /// Hotkey feedback + const static TOOL_EVENT SnappingModeChangedByKeyEvent; }; #endif diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index a71a0dfd28..5b9398eaf9 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -1340,6 +1340,47 @@ int PCB_CONTROL::Redo( const TOOL_EVENT& aEvent ) } +int PCB_CONTROL::SnapMode( const TOOL_EVENT& aEvent ) +{ + bool& snapMode = m_frame->GetPcbNewSettings()->m_MagneticItems.allLayers; + + if( aEvent.IsAction( &PCB_ACTIONS::magneticSnapActiveLayer ) ) + snapMode = false; + else if( aEvent.IsAction( &PCB_ACTIONS::magneticSnapAllLayers ) ) + snapMode = true; + else + snapMode = !snapMode; + + m_toolMgr->PostEvent( PCB_EVENTS::SnappingModeChangedByKeyEvent ); + + return 0; +} + + +int PCB_CONTROL::SnapModeFeedback( const TOOL_EVENT& aEvent ) +{ + if( !Pgm().GetCommonSettings()->m_Input.hotkey_feedback ) + return 0; + + wxArrayString labels; + labels.Add( _( "Active Layer" ) ); + labels.Add( _( "All Layers" ) ); + + if( !m_frame->GetHotkeyPopup() ) + m_frame->CreateHotkeyPopup(); + + HOTKEY_CYCLE_POPUP* popup = m_frame->GetHotkeyPopup(); + + if( popup ) + { + popup->Popup( _( "Object Snapping" ), labels, + static_cast( m_frame->GetPcbNewSettings()->m_MagneticItems.allLayers ) ); + } + + return 0; +} + + int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent ) { PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); @@ -1645,6 +1686,12 @@ void PCB_CONTROL::setTransitions() Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() ); Go( &PCB_CONTROL::Redo, ACTIONS::redo.MakeEvent() ); + // Snapping control + Go( &PCB_CONTROL::SnapMode, PCB_ACTIONS::magneticSnapActiveLayer.MakeEvent() ); + Go( &PCB_CONTROL::SnapMode, PCB_ACTIONS::magneticSnapAllLayers.MakeEvent() ); + Go( &PCB_CONTROL::SnapMode, PCB_ACTIONS::magneticSnapToggle.MakeEvent() ); + Go( &PCB_CONTROL::SnapModeFeedback, PCB_EVENTS::SnappingModeChangedByKeyEvent ); + // Miscellaneous Go( &PCB_CONTROL::DeleteItemCursor, ACTIONS::deleteTool.MakeEvent() ); diff --git a/pcbnew/tools/pcb_control.h b/pcbnew/tools/pcb_control.h index df26c1b54e..5481985ee1 100644 --- a/pcbnew/tools/pcb_control.h +++ b/pcbnew/tools/pcb_control.h @@ -91,6 +91,10 @@ public: int Undo( const TOOL_EVENT& aEvent ); int Redo( const TOOL_EVENT& aEvent ); + // Snapping control + int SnapMode( const TOOL_EVENT& aEvent ); + int SnapModeFeedback( const TOOL_EVENT& aEvent ); + // Miscellaneous int DeleteItemCursor( const TOOL_EVENT& aEvent ); int Paste( const TOOL_EVENT& aEvent ); diff --git a/pcbnew/tools/pcb_grid_helper.cpp b/pcbnew/tools/pcb_grid_helper.cpp index 9ffcb48aa6..d4c3ec9f49 100644 --- a/pcbnew/tools/pcb_grid_helper.cpp +++ b/pcbnew/tools/pcb_grid_helper.cpp @@ -870,7 +870,7 @@ PCB_GRID_HELPER::ANCHOR* PCB_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, i { BOARD_ITEM* item = static_cast( a.item ); - if( ( aMatchLayers & item->GetLayerSet() ) == 0 ) + if( !m_magneticSettings->allLayers && ( ( aMatchLayers & item->GetLayerSet() ) == 0 ) ) continue; if( ( aFlags & a.flags ) != aFlags )