From 960c92634fe7e325e61162445da8af542a3a0299 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Mon, 24 Oct 2022 18:46:15 -0400 Subject: [PATCH] Improve logic of Position Relative tool Fixes https://gitlab.com/kicad/code/kicad/-/issues/12672 (cherry picked from commit 2d2912c23d8d0007e839ef1d4979ea36b998de35) --- pcbnew/tools/position_relative_tool.cpp | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pcbnew/tools/position_relative_tool.cpp b/pcbnew/tools/position_relative_tool.cpp index 4a031d3800..ed6243ae97 100644 --- a/pcbnew/tools/position_relative_tool.cpp +++ b/pcbnew/tools/position_relative_tool.cpp @@ -37,6 +37,7 @@ using namespace std::placeholders; #include #include #include +#include POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() : @@ -82,29 +83,24 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent ) m_selection = selection; - PCB_TYPE_COLLECTOR collector; - collector.Collect( static_cast( m_selection.GetTopLeftItem() ), { PCB_PAD_T } ); + // We prefer footprints, then pads, then anything else here. + EDA_ITEM* preferredItem = m_selection.GetTopLeftItem( true ); - if( collector.GetCount() == 0 ) + if( !preferredItem && m_selection.HasType( PCB_PAD_T ) ) { - for( FOOTPRINT* footprint : editFrame->GetBoard()->Footprints() ) - { - for( PAD* pad : footprint->Pads() ) - { - if( pad->IsSelected() ) - collector.Append( pad ); + PCB_SELECTION padsOnly = m_selection; + std::deque& items = padsOnly.Items(); + items.erase( std::remove_if( items.begin(), items.end(), + []( const EDA_ITEM* aItem ) + { + return aItem->Type() != PCB_PAD_T; + } ), items.end() ); - if( collector.GetCount() > 0 ) - break; - } - - if( collector.GetCount() > 0 ) - break; - } + preferredItem = padsOnly.GetTopLeftItem(); } - if( collector.GetCount() > 0 ) - m_selectionAnchor = collector[0]->GetPosition(); + if( preferredItem ) + m_selectionAnchor = preferredItem->GetPosition(); else m_selectionAnchor = m_selection.GetTopLeftItem()->GetPosition(); @@ -134,8 +130,12 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( const VECTOR2I& aPosAncho for( EDA_ITEM* item : m_selection ) { // Don't move a pad by itself unless editing the footprint - if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB_EDITOR ) ) + if( item->Type() == PCB_PAD_T + && !frame()->GetPcbNewSettings()->m_AllowFreePads + && frame()->IsType( FRAME_PCB_EDITOR ) ) + { item = item->GetParent(); + } m_commit->Modify( item );