43 m_selectionTool( nullptr ),
44 m_placementMenu( nullptr ),
59 m_frame = getEditFrame<PCB_BASE_FRAME>();
95 std::vector<std::pair<BOARD_ITEM*, BOX2I>> rects;
101 wxCHECK2( boardItem,
continue );
106 rects.emplace_back( std::make_pair( footprint,
111 rects.emplace_back( std::make_pair( boardItem, boardItem->
GetBoundingBox() ) );
119template<
typename T >
121 std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aLocked,
129 if( aLocked.size() >= 1 )
131 for(
const std::pair<BOARD_ITEM*, BOX2I>& item : aLocked )
133 if( item.second.Contains( curPos ) )
134 return aGetValue( item );
137 return aGetValue( aLocked.front() );
140 for(
const std::pair<BOARD_ITEM*, BOX2I>& item : aItems )
142 if( item.second.Contains( curPos ) )
143 return aGetValue( item );
146 return aGetValue( aItems.front() );
150template<
typename T >
152 std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aLockedItems,
159 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
161 BOARD_ITEM* item = aCollector[i];
163 if( item->Type() == PCB_MARKER_T )
164 aCollector.Remove( item );
168 std::vector<BOARD_ITEM*> lockedItems;
169 std::vector<BOARD_ITEM*> itemsToAlign;
174 wxCHECK2( boardItem,
continue );
182 itemsToAlign.push_back( boardItem );
184 lockedItems.push_back( boardItem );
187 itemsToAlign.push_back( boardItem );
192 std::sort( aItemsToAlign.begin(), aItemsToAlign.end(), aCompare );
193 std::sort( aLockedItems.begin(), aLockedItems.end(), aCompare );
195 return aItemsToAlign.size();
201 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
202 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
205 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
207 return ( lhs.second.GetTop() < rhs.second.GetTop() );
215 int targetTop =
selectTarget( itemsToAlign, locked_items,
216 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
218 return aVal.second.GetTop();
222 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
225 int difference = targetTop - i.second.GetTop();
238 commit.
Push(
_(
"Align to Top" ) );
245 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
246 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
249 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs)
251 return ( lhs.second.GetBottom() > rhs.second.GetBottom() );
259 int targetBottom =
selectTarget( itemsToAlign, locked_items,
260 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
262 return aVal.second.GetBottom();
266 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
268 int difference = targetBottom - i.second.GetBottom();
282 commit.
Push(
_(
"Align to Bottom" ) );
300 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
301 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
304 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
306 return ( lhs.second.GetLeft() < rhs.second.GetLeft() );
314 int targetLeft =
selectTarget( itemsToAlign, locked_items,
315 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
317 return aVal.second.GetLeft();
321 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
323 int difference = targetLeft - i.second.GetLeft();
337 commit.
Push(
_(
"Align to Left" ) );
355 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
356 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
359 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
361 return ( lhs.second.GetRight() > rhs.second.GetRight() );
369 int targetRight =
selectTarget( itemsToAlign, locked_items,
370 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
372 return aVal.second.GetRight();
376 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
378 int difference = targetRight - i.second.GetRight();
392 commit.
Push(
_(
"Align to Right" ) );
399 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
400 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
403 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
405 return ( lhs.second.Centre().x < rhs.second.Centre().x );
414 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
416 return aVal.second.Centre().x;
420 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
422 int difference = targetX - i.second.Centre().x;
436 commit.
Push(
_(
"Align to Middle" ) );
443 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToAlign;
444 std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
447 [](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
449 return ( lhs.second.Centre().y < rhs.second.Centre().y );
458 [](
const std::pair<BOARD_ITEM*, BOX2I>& aVal )
460 return aVal.second.Centre().y;
464 for(
const std::pair<BOARD_ITEM*, BOX2I>& i : itemsToAlign )
466 int difference = targetY - i.second.Centre().y;
480 commit.
Push(
_(
"Align to Center" ) );
499 if( selection.
Size() < 3 )
504 std::vector<std::pair<BOARD_ITEM*, BOX2I>> itemsToDistribute =
GetBoundingBoxes( selection );
527 commit.
Push( commitMsg );
533 std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aItems,
541 std::sort( aItems.begin(), aItems.end(),
542 [&](
const std::pair<BOARD_ITEM*, BOX2I>& a,
const std::pair<BOARD_ITEM*, BOX2I>& b )
544 return aIsXAxis ? a.second.GetLeft() < b.second.GetLeft()
545 : a.second.GetTop() < b.second.GetTop();
549 std::vector<std::pair<int, int>> itemSpans;
550 itemSpans.reserve( aItems.size() );
552 for(
const auto& [item, box] : aItems )
554 const int start = aIsXAxis ? box.GetLeft() : box.GetTop();
555 const int end = aIsXAxis ? box.GetRight() : box.GetBottom();
556 itemSpans.emplace_back( start, end );
563 for(
size_t i = 1; i < aItems.size() - 1; ++i )
565 const auto& [item, box] = aItems[i];
566 const int delta = deltas[i];
573 item->Move( deltaVec );
580 std::vector<std::pair<BOARD_ITEM*, BOX2I>>& aItems,
584 aItems.begin(), aItems.end(),
585 [&](
const std::pair<BOARD_ITEM*, BOX2I>& lhs,
const std::pair<BOARD_ITEM*, BOX2I>& rhs )
587 const int lhsPos = aIsXAxis ? lhs.second.Centre().x : lhs.second.Centre().y;
588 const int rhsPos = aIsXAxis ? rhs.second.Centre().x : rhs.second.Centre().y;
589 return lhsPos < rhsPos;
592 std::vector<int> itemCenters;
593 itemCenters.reserve( aItems.size() );
595 for(
const auto& [item, box] : aItems )
597 itemCenters.push_back( aIsXAxis ? box.Centre().x : box.Centre().y );
603 for(
size_t i = 1; i < aItems.size() - 1; ++i )
605 const auto& [item, box] = aItems[i];
606 const int delta = deltas[i];
613 item->Move( deltaVec );
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr) override
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
virtual bool IsLocked() const
BOARD_ITEM_CONTAINER * GetParent() const
int GetCount() const
Return the number of objects in the list.
bool IsType(FRAME_T aType) const
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_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint