95        return static_cast<FOOTPRINT*
>( aItem )->GetBoundingBox( 
false );
 
 
  101template< 
typename T >
 
  103                                         std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aLocked,
 
  111    if( aLocked.size() >= 1 )
 
  113        for( 
const std::pair<BOARD_ITEM*, BOX2I>& item : aLocked )
 
  115            if( item.second.Contains( curPos ) )
 
  116                return aGetValue( item );
 
  119        return aGetValue( aLocked.front() );
 
  122    for( 
const std::pair<BOARD_ITEM*, BOX2I>& item : aItems )
 
  124        if( item.second.Contains( curPos ) )
 
  125            return aGetValue( item );
 
  128    return aGetValue( aItems.front() );
 
 
  132template< 
typename T >
 
  134                                             std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aLockedItems,
 
  141                for( 
int i = aCollector.
GetCount() - 1; i >= 0; --i )
 
  146                        aCollector.
Remove( item );
 
  152    bool                  differentParents = 
false;
 
  154                                       || 
m_frame->GetPcbNewSettings()->m_AllowFreePads;
 
  158        if( !item->IsBOARD_ITEM() )
 
  171            currentParent = parent;
 
  172        else if( parent != currentParent )
 
  173            differentParents = 
true;
 
  177            []( std::vector<std::pair<BOARD_ITEM*, BOX2I>>& list, 
BOARD_ITEM* item, 
FOOTPRINT* parentFp )
 
  179                BOARD_ITEM* listItem = parentFp ? parentFp : item;
 
  181                for( 
const auto& [candidate, bbox] : list )
 
  183                    if( candidate == listItem )
 
  187                list.emplace_back( std::make_pair( listItem, 
getBoundingBox( item ) ) );
 
  192        if( !item->IsBOARD_ITEM() )
 
  197        if( boardItem->
Type() == 
PCB_PAD_T && ( !allowFreePads || ( allPads && differentParents ) ) )
 
  201            if( parentFp && parentFp->
IsLocked() )
 
  202                addToList( aLockedItems, boardItem, parentFp );
 
  204                addToList( aItemsToAlign, boardItem, parentFp );
 
  210            addToList( aLockedItems, boardItem, 
nullptr );
 
  212            addToList( aItemsToAlign, boardItem, 
nullptr );
 
  215    std::sort( aItemsToAlign.begin(), aItemsToAlign.end(), aCompare );
 
  216    std::sort( aLockedItems.begin(), aLockedItems.end(), aCompare );
 
  218    return aItemsToAlign.size();
 
 
  224    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  225    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  228            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  230                return ( lhs.second.GetTop() < rhs.second.GetTop() );
 
  238    int targetTop = 
selectTarget( itemsToAlign, locked_items,
 
  239            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  241                return aVal.second.GetTop();
 
  245    for( 
const auto& [item, bbox] : itemsToAlign )
 
  247        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  250        int difference = targetTop - bbox.GetTop();
 
  253        item->Move( 
VECTOR2I( 0, difference ) );
 
  256    commit.
Push( 
_( 
"Align to Top" ) );
 
 
  263    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  264    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  267            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs)
 
  269                return ( lhs.second.GetBottom() > rhs.second.GetBottom() );
 
  277    int targetBottom = 
selectTarget( itemsToAlign, locked_items,
 
  278            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  280                return aVal.second.GetBottom();
 
  284    for( 
const auto& [item, bbox] : itemsToAlign )
 
  286        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  289        int difference = targetBottom - bbox.GetBottom();
 
  292        item->Move( 
VECTOR2I( 0, difference ) );
 
  295    commit.
Push( 
_( 
"Align to Bottom" ) );
 
 
  313    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  314    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  317            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  319                return ( lhs.second.GetLeft() < rhs.second.GetLeft() );
 
  327    int targetLeft = 
selectTarget( itemsToAlign, locked_items,
 
  328            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  330                return aVal.second.GetLeft();
 
  334    for( 
const auto& [item, bbox] : itemsToAlign )
 
  336        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  339        int difference = targetLeft - bbox.GetLeft();
 
  342        item->Move( 
VECTOR2I( difference, 0 ) );
 
  345    commit.
Push( 
_( 
"Align to Left" ) );
 
 
  363    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  364    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  367            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  369                return ( lhs.second.GetRight() > rhs.second.GetRight() );
 
  377    int targetRight = 
selectTarget( itemsToAlign, locked_items,
 
  378            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  380                return aVal.second.GetRight();
 
  384    for( 
const auto& [item, bbox] : itemsToAlign )
 
  386        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  389        int difference = targetRight - bbox.GetRight();
 
  392        item->Move( 
VECTOR2I( difference, 0 ) );
 
  395    commit.
Push( 
_( 
"Align to Right" ) );
 
 
  402    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  403    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  406            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  408                return ( lhs.second.Centre().x < rhs.second.Centre().x );
 
  417            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  419                return aVal.second.Centre().x;
 
  423    for( 
const auto& [item, bbox] : itemsToAlign )
 
  425        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  428        int difference = targetX - bbox.Centre().x;
 
  431        item->Move( 
VECTOR2I( difference, 0 ) );
 
  434    commit.
Push( 
_( 
"Align to Middle" ) );
 
 
  441    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
 
  442    std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
 
  445            []( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  447                return ( lhs.second.Centre().y < rhs.second.Centre().y );
 
  456            []( 
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
 
  458                return aVal.second.Centre().y;
 
  462    for( 
const auto& [item, bbox] : itemsToAlign )
 
  464        if( item->GetParent() && item->GetParent()->IsSelected() )
 
  467        int difference = targetY - bbox.Centre().y;
 
  470        item->Move( 
VECTOR2I( 0, difference ) );
 
  473    commit.
Push( 
_( 
"Align to Center" ) );
 
 
  494    if( selection.
Size() < 3 )
 
  499    std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToDistribute;
 
  503        if( !item->IsBOARD_ITEM() )
 
  507        itemsToDistribute.emplace_back( std::make_pair( boardItem, 
getBoundingBox( boardItem ) ) );
 
  531    commit.
Push( commitMsg );
 
 
  537                                              std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aItems,
 
  545    std::sort( aItems.begin(), aItems.end(),
 
  546               [&]( 
const std::pair<BOARD_ITEM*, BOX2I>& a, 
const std::pair<BOARD_ITEM*, BOX2I>& b )
 
  548                   return aIsXAxis ? a.second.GetLeft() < b.second.GetLeft()
 
  549                                   : a.second.GetTop() < b.second.GetTop();
 
  553    std::vector<std::pair<int, int>> itemSpans;
 
  554    itemSpans.reserve( aItems.size() );
 
  556    for( 
const auto& [item, box] : aItems )
 
  558        const int start = aIsXAxis ? box.GetLeft() : box.GetTop();
 
  559        const int end = aIsXAxis ? box.GetRight() : box.GetBottom();
 
  560        itemSpans.emplace_back( start, 
end );
 
  567    for( 
size_t i = 1; i < aItems.size() - 1; ++i )
 
  569        const auto& [item, box] = aItems[i];
 
  570        const int delta = deltas[i];
 
  577            item->Move( deltaVec );
 
 
  584                                                 std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aItems,
 
  588            aItems.begin(), aItems.end(),
 
  589            [&]( 
const std::pair<BOARD_ITEM*, BOX2I>& lhs, 
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
 
  591                const int lhsPos = aIsXAxis ? lhs.second.Centre().x : lhs.second.Centre().y;
 
  592                const int rhsPos = aIsXAxis ? rhs.second.Centre().x : rhs.second.Centre().y;
 
  593                return lhsPos < rhsPos;
 
  596    std::vector<int> itemCenters;
 
  597    itemCenters.reserve( aItems.size() );
 
  599    for( 
const auto& [item, box] : aItems )
 
  601        itemCenters.push_back( aIsXAxis ? box.Centre().x : box.Centre().y );
 
  607    for( 
size_t i = 1; i < aItems.size() - 1; ++i )
 
  609        const auto& [item, box] = aItems[i];
 
  610        const int delta = deltas[i];
 
  617            item->Move( deltaVec );
 
 
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
 
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE) override
Add a change of the item aItem of type aChangeType to the change list.
 
Abstract interface for BOARD_ITEMs capable of storing other items inside.
 
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
 
bool IsLocked() const override
 
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
 
FOOTPRINT * GetParentFootprint() const
 
int GetCount() const
Return the number of objects in the list.
 
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
 
A base class for most all the KiCad significant classes used in schematics and boards.
 
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
 
KICAD_T Type() const
Returns the type of object.
 
Used when the right click button is pressed, or when the select tool is in effect.
 
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
 
static TOOL_ACTION alignTop
 
static TOOL_ACTION distributeHorizontallyGaps
 
static TOOL_ACTION distributeHorizontallyCenters
 
static TOOL_ACTION alignRight
 
static TOOL_ACTION alignBottom
 
static TOOL_ACTION alignLeft
 
static TOOL_ACTION alignCenterX
 
static TOOL_ACTION distributeVerticallyGaps
 
static TOOL_ACTION distributeVerticallyCenters
 
static TOOL_ACTION alignCenterY
 
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
 
int Size() const
Returns the number of selected parts.
 
std::vector< int > GetDeltasForDistributeByGaps(const std::vector< std::pair< int, int > > &aItemExtents)
Given a list of 'n' item spans (e.g.
 
std::vector< int > GetDeltasForDistributeByPoints(const std::vector< int > &aItemPositions)
 
Class that computes missing connections on a PCB.
 
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
 
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
 
@ PCB_PAD_T
class PAD, a pad in a footprint
 
VECTOR2< int32_t > VECTOR2I