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
This commit is contained in:
Jeff Young 2022-04-12 18:13:15 +01:00
parent a33e23e25a
commit 576f3dc2fd
2 changed files with 33 additions and 12 deletions

View File

@ -39,25 +39,46 @@ EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) :
EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
{ {
EDA_ITEM* topLeftConnectedItem = nullptr;
VECTOR2I topLeftConnectedPos;
EDA_ITEM* topLeftItem = nullptr; EDA_ITEM* topLeftItem = nullptr;
VECTOR2I topLeftPos; 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 // in the selection
for( EDA_ITEM* item : m_items ) for( EDA_ITEM* item : m_items )
{ {
VECTOR2I pos = item->GetPosition(); SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
LIB_PIN* lib_pin = dynamic_cast<LIB_PIN*>( item );
if( ( topLeftItem == nullptr ) // Prefer connection points (which should remain on grid)
|| ( pos.x < topLeftPos.x )
|| ( topLeftPos.x == pos.x && pos.y < topLeftPos.y ) ) if( ( sch_item && sch_item->IsConnectable() ) || lib_pin )
{ processItem( item, &topLeftConnectedItem, &topLeftConnectedPos );
topLeftItem = item;
topLeftPos = pos; processItem( item, &topLeftItem, &topLeftPos );
}
} }
return topLeftItem; if( topLeftConnectedItem )
return topLeftConnectedItem;
else
return topLeftItem;
} }

View File

@ -204,9 +204,9 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
m_anchorPos = m_cursor; 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 ); m_anchorPos = VECTOR2I( itemPos.x, -itemPos.y );
getViewControls()->WarpCursor( m_anchorPos, true, true ); getViewControls()->WarpCursor( m_anchorPos, true, true );