From 576f3dc2fd159757e7a4c7429471dfc128bc9228 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 12 Apr 2022 18:13:15 +0100 Subject: [PATCH] Keep pins aligned to grid when possible. This uses the first pin as the anchor point in a mulitple-item selection. Fixes https://gitlab.com/kicad/code/kicad/issues/11151 --- eeschema/tools/ee_selection.cpp | 41 ++++++++++++++++------ eeschema/tools/symbol_editor_move_tool.cpp | 4 +-- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/eeschema/tools/ee_selection.cpp b/eeschema/tools/ee_selection.cpp index d22ad7b2d8..acbff44385 100644 --- a/eeschema/tools/ee_selection.cpp +++ b/eeschema/tools/ee_selection.cpp @@ -39,25 +39,46 @@ EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) : EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const { + EDA_ITEM* topLeftConnectedItem = nullptr; + VECTOR2I topLeftConnectedPos; + EDA_ITEM* topLeftItem = nullptr; VECTOR2I topLeftPos; - // find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item + auto processItem = + []( EDA_ITEM* aItem, EDA_ITEM** aCurrent, VECTOR2I* aCurrentPos ) + { + VECTOR2I pos = aItem->GetPosition(); + + if( ( aCurrent == nullptr ) + || ( pos.x < aCurrentPos->x ) + || ( pos.x == aCurrentPos->x && pos.y < aCurrentPos->y ) ) + { + *aCurrent = aItem; + *aCurrentPos = pos; + } + }; + + // Find the leftmost (smallest x coord) and highest (smallest y with the smallest x) item // in the selection + for( EDA_ITEM* item : m_items ) { - VECTOR2I pos = item->GetPosition(); + SCH_ITEM* sch_item = dynamic_cast( item ); + LIB_PIN* lib_pin = dynamic_cast( item ); - if( ( topLeftItem == nullptr ) - || ( pos.x < topLeftPos.x ) - || ( topLeftPos.x == pos.x && pos.y < topLeftPos.y ) ) - { - topLeftItem = item; - topLeftPos = pos; - } + // Prefer connection points (which should remain on grid) + + if( ( sch_item && sch_item->IsConnectable() ) || lib_pin ) + processItem( item, &topLeftConnectedItem, &topLeftConnectedPos ); + + processItem( item, &topLeftItem, &topLeftPos ); } - return topLeftItem; + if( topLeftConnectedItem ) + return topLeftConnectedItem; + else + return topLeftItem; } diff --git a/eeschema/tools/symbol_editor_move_tool.cpp b/eeschema/tools/symbol_editor_move_tool.cpp index d444cb4724..5c05e1c546 100644 --- a/eeschema/tools/symbol_editor_move_tool.cpp +++ b/eeschema/tools/symbol_editor_move_tool.cpp @@ -204,9 +204,9 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent ) m_anchorPos = m_cursor; } - else if( selection.Size() == 1 && m_frame->GetMoveWarpsCursor() ) + else if( m_frame->GetMoveWarpsCursor() ) { - VECTOR2I itemPos = lib_item->GetPosition(); + VECTOR2I itemPos = selection.GetTopLeftItem()->GetPosition(); m_anchorPos = VECTOR2I( itemPos.x, -itemPos.y ); getViewControls()->WarpCursor( m_anchorPos, true, true );