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* 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<SCH_ITEM*>( item );
LIB_PIN* lib_pin = dynamic_cast<LIB_PIN*>( 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;
}

View File

@ -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 );