ADDED: Multi-layer object snapping

Default hotkey Shift+S toggles on/off

Fixes https://gitlab.com/kicad/code/kicad/-/issues/6266
This commit is contained in:
Jon Evans 2023-08-17 09:25:26 -04:00
parent 981089bbd3
commit 1efd75ca79
7 changed files with 100 additions and 5 deletions

View File

@ -89,6 +89,7 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
m_MagneticItems.pads = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; m_MagneticItems.pads = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL;
m_MagneticItems.tracks = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL; m_MagneticItems.tracks = MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL;
m_MagneticItems.graphics = false; m_MagneticItems.graphics = false;
m_MagneticItems.allLayers = false;
m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager", m_params.emplace_back( new PARAM<bool>( "aui.show_layer_manager",
&m_AuiPanels.show_layer_manager, true ) ); &m_AuiPanels.show_layer_manager, true ) );
@ -161,6 +162,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
reinterpret_cast<int*>( &m_MagneticItems.tracks ), reinterpret_cast<int*>( &m_MagneticItems.tracks ),
static_cast<int>( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ) ) ); static_cast<int>( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ) ) );
m_params.emplace_back( new PARAM<bool>( "editing.magnetic_all_layers",
&m_MagneticItems.allLayers, false ) );
m_params.emplace_back( new PARAM<bool>( "editing.polar_coords", m_params.emplace_back( new PARAM<bool>( "editing.polar_coords",
&m_PolarCoords, false ) ); &m_PolarCoords, false ) );

View File

@ -63,11 +63,13 @@ struct MAGNETIC_SETTINGS
MAGNETIC_OPTIONS pads; MAGNETIC_OPTIONS pads;
MAGNETIC_OPTIONS tracks; MAGNETIC_OPTIONS tracks;
bool graphics; bool graphics;
bool allLayers;
MAGNETIC_SETTINGS() : MAGNETIC_SETTINGS() :
pads( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ), pads( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ),
tracks( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ), tracks( MAGNETIC_OPTIONS::CAPTURE_CURSOR_IN_TRACK_TOOL ),
graphics( false ) graphics( false ),
allLayers( false )
{ } { }
}; };

View File

@ -255,6 +255,26 @@ TOOL_ACTION PCB_ACTIONS::arcPosture( "pcbnew.InteractiveDrawing.arcPosture",
'/', LEGACY_HK_NAME( "Switch Track Posture" ), '/', LEGACY_HK_NAME( "Switch Track Posture" ),
_( "Switch Arc Posture" ), _( "Switch the arc 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", TOOL_ACTION PCB_ACTIONS::deleteLastPoint( "pcbnew.InteractiveDrawing.deleteLastPoint",
AS_CONTEXT, AS_CONTEXT,
WXK_BACK, "", WXK_BACK, "",
@ -1889,3 +1909,7 @@ TOOL_ACTION PCB_ACTIONS::ddAppendBoard( "pcbnew.Control.DdAppendBoard",
TOOL_ACTION PCB_ACTIONS::ddImportFootprint( "pcbnew.Control.ddImportFootprint", AS_GLOBAL ); TOOL_ACTION PCB_ACTIONS::ddImportFootprint( "pcbnew.Control.ddImportFootprint", AS_GLOBAL );
const TOOL_EVENT PCB_EVENTS::SnappingModeChangedByKeyEvent( TC_MESSAGE, TA_ACTION,
"common.Interactive.snappingModeChangedByKey" );

View File

@ -217,6 +217,11 @@ public:
/// Switch posture when drawing arc /// Switch posture when drawing arc
static TOOL_ACTION arcPosture; static TOOL_ACTION arcPosture;
/// Snapping controls
static TOOL_ACTION magneticSnapActiveLayer;
static TOOL_ACTION magneticSnapAllLayers;
static TOOL_ACTION magneticSnapToggle;
// Push and Shove Router Tool // Push and Shove Router Tool
/// Activation of the Push and Shove router /// Activation of the Push and Shove router
@ -547,6 +552,15 @@ public:
/// Drag and drop /// Drag and drop
static TOOL_ACTION ddAppendBoard; static TOOL_ACTION ddAppendBoard;
static TOOL_ACTION ddImportFootprint; static TOOL_ACTION ddImportFootprint;
};
class PCB_EVENTS
{
public:
/// Hotkey feedback
const static TOOL_EVENT SnappingModeChangedByKeyEvent;
}; };
#endif #endif

View File

@ -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<int>( m_frame->GetPcbNewSettings()->m_MagneticItems.allLayers ) );
}
return 0;
}
int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent ) int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
{ {
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>(); PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
@ -1645,6 +1686,12 @@ void PCB_CONTROL::setTransitions()
Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() ); Go( &PCB_CONTROL::Undo, ACTIONS::undo.MakeEvent() );
Go( &PCB_CONTROL::Redo, ACTIONS::redo.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 // Miscellaneous
Go( &PCB_CONTROL::DeleteItemCursor, ACTIONS::deleteTool.MakeEvent() ); Go( &PCB_CONTROL::DeleteItemCursor, ACTIONS::deleteTool.MakeEvent() );

View File

@ -91,6 +91,10 @@ public:
int Undo( const TOOL_EVENT& aEvent ); int Undo( const TOOL_EVENT& aEvent );
int Redo( 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 // Miscellaneous
int DeleteItemCursor( const TOOL_EVENT& aEvent ); int DeleteItemCursor( const TOOL_EVENT& aEvent );
int Paste( const TOOL_EVENT& aEvent ); int Paste( const TOOL_EVENT& aEvent );

View File

@ -870,7 +870,7 @@ PCB_GRID_HELPER::ANCHOR* PCB_GRID_HELPER::nearestAnchor( const VECTOR2I& aPos, i
{ {
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( a.item ); BOARD_ITEM* item = static_cast<BOARD_ITEM*>( a.item );
if( ( aMatchLayers & item->GetLayerSet() ) == 0 ) if( !m_magneticSettings->allLayers && ( ( aMatchLayers & item->GetLayerSet() ) == 0 ) )
continue; continue;
if( ( aFlags & a.flags ) != aFlags ) if( ( aFlags & a.flags ) != aFlags )