58#include <wx/richmsgdlg.h>
59#include <wx/choicdlg.h>
60#include <unordered_set>
61#include <unordered_map>
65 const wxString& aDialogTitle,
bool& aIncludeConnectedPads )
69 aIncludeConnectedPads =
true;
73 std::unordered_set<PAD*> uniquePads( aPads.begin(), aPads.end() );
76 msg.Printf(
_(
"%zu unselected pad(s) are connected to these nets. How do you want to proceed?" ),
80 details <<
_(
"Connected tracks, vias, and other non-zone copper items will still swap nets"
81 " even if you ignore the unselected pads." )
83 <<
_(
"Unselected pads:" ) <<
'\n';
85 for(
PAD*
pad : uniquePads )
88 details << wxS(
" • " ) << ( fp ? fp->
GetReference() :
_(
"<no reference designator>" ) ) << wxS(
":" )
89 <<
pad->GetNumber() <<
'\n';
93 wxRichMessageDialog dlg( aFrame, msg, aDialogTitle, wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_WARNING );
94 dlg.SetYesNoLabels(
_(
"Ignore Unselected Pads" ),
_(
"Swap All Connected Pads" ) );
95 dlg.SetExtendedMessage( details );
97 int ret = dlg.ShowModal();
99 if( ret == wxID_CANCEL )
102 aIncludeConnectedPads = ( ret == wxID_NO );
110 std::unordered_map<BOARD_CONNECTED_ITEM*, int>& aItemNewNets,
113 auto [it, inserted] = aItemNewNets.emplace( aItem, aNewNet );
115 if( !inserted && it->second != aNewNet )
117 aError =
_(
"Cannot swap nets: connected items would receive conflicting nets." );
127 const std::unordered_map<BOARD_CONNECTED_ITEM*, int>& aItemNewNets,
128 const std::unordered_set<PAD*>& aSwapPads,
bool aIncludeConnectedPads )
133 for(
const auto& [item, newNet] : aItemNewNets )
135 if( item->GetNetCode() == newNet )
138 if( item->Type() ==
PCB_PAD_T && !aIncludeConnectedPads
139 && !aSwapPads.count(
static_cast<PAD*
>( item ) ) )
142 if( item->IsLocked() )
144 aFrame->
ShowInfoBarError(
_(
"Cannot swap nets of locked pads or connected copper unless "
145 "Override Locks is enabled." ) );
170 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
175 aCollector.
Remove( item );
190 commit = &localCommit;
192 std::vector<EDA_ITEM*> sorted =
selection.GetItemsSortedBySelectionOrder();
198 for(
size_t i = 0; i < sorted.size() - 1; i++ )
201 EDA_ITEM* edaItemB = sorted[( i + 1 ) % sorted.size()];
216 std::swap( aLayer, bLayer );
225 std::swap( aPos, bPos );
248 std::swap( aAngle, bAngle );
258 std::swap( aLayer, bLayer );
264 if( !localCommit.
Empty() )
265 localCommit.
Push(
_(
"Swap" ) );
288 std::vector<EDA_ITEM*> orderedPads =
selection.GetItemsSortedBySelectionOrder();
289 std::vector<PAD*> pads;
290 const size_t padsCount = orderedPads.size();
293 pads.push_back(
static_cast<PAD*
>(
static_cast<BOARD_ITEM*
>( it ) ) );
296 std::vector<int> originalNets( padsCount );
297 std::unordered_set<PAD*> selectedPads;
299 for(
size_t i = 0; i < padsCount; ++i )
301 originalNets[i] = pads[i]->GetNetCode();
302 selectedPads.insert( pads[i] );
305 if( std::ranges::all_of( originalNets,
308 return net == originalNets.front();
313 auto newNetForIndex =
316 return originalNets[( i + 1 ) % padsCount];
324 commit = &localCommit;
327 std::shared_ptr<CONNECTIVITY_DATA> connectivity =
board()->GetConnectivity();
330 std::unordered_map<BOARD_CONNECTED_ITEM*, int> itemNewNets;
331 std::vector<PAD*> nonSelectedPadsToChange;
335 for(
size_t i = 0; i < padsCount; ++i )
337 if( !
ScheduleNetSwap( pads[i], newNetForIndex( i ), itemNewNets, error ) )
339 frame()->ShowInfoBarError( error );
344 for(
size_t i = 0; i < padsCount; ++i )
347 int fromNet = originalNets[i];
348 int toNet = newNetForIndex( i );
366 if( ci->GetNetCode() != fromNet )
371 frame()->ShowInfoBarError( error );
377 PAD* otherPad =
static_cast<PAD*
>( ci );
379 if( !selectedPads.count( otherPad ) )
380 nonSelectedPadsToChange.push_back( otherPad );
385 bool includeConnectedPads =
true;
395 for(
size_t i = 0; i < padsCount; ++i )
397 if( pads[i]->GetNetCode() == newNetForIndex( i ) )
400 commit->
Modify( pads[i] );
401 pads[i]->SetNetCode( newNetForIndex( i ) );
405 for(
const auto& itemNewNet : itemNewNets )
408 int newNet = itemNewNet.second;
412 PAD* p =
static_cast<PAD*
>( item );
414 if( selectedPads.count( p ) )
417 if( !includeConnectedPads )
428 if( !localCommit.
Empty() )
429 localCommit.
Push(
_(
"Swap Pad Nets" ) );
450 frame()->ShowInfoBarError(
_(
"Gate swapping must be performed on pads within one multi-gate "
475 else if( fp && targetFp != fp )
482 if( fail || !targetFp || targetFp->
GetUnitInfo().size() < 2 )
492 std::vector<bool> unitHit( units.size(),
false );
493 std::vector<int> unitOrder;
495 std::vector<EDA_ITEM*> orderedPads =
selection.GetItemsSortedBySelectionOrder();
501 const wxString& padNum =
pad->GetNumber();
504 for(
size_t i = 0; i < units.size(); ++i )
506 for(
const auto& p : units[i].m_pins )
510 unitIdx =
static_cast<int>( i );
513 unitOrder.push_back( unitIdx );
526 std::vector<int> activeUnitIdx;
529 if( unitOrder.size() >= 2 )
531 activeUnitIdx = unitOrder;
532 sourceIdx = unitOrder.front();
535 else if( unitOrder.size() == 1 && aEvent.
HasParameter() )
537 sourceIdx = unitOrder.front();
538 wxString targetUnitByName = aEvent.
Parameter<wxString>();
542 for(
size_t i = 0; i < units.size(); ++i )
544 if(
static_cast<int>( i ) == sourceIdx )
547 if( units[i].m_pins.size() == units[sourceIdx].m_pins.size() && units[i].m_unitName == targetUnitByName )
548 targetIdx =
static_cast<int>( i );
557 activeUnitIdx.push_back( sourceIdx );
558 activeUnitIdx.push_back( targetIdx );
567 const size_t pinCount = units[activeUnitIdx.front()].m_pins.size();
569 for(
int idx : activeUnitIdx )
571 if( units[idx].m_pins.size() != pinCount )
573 frame()->ShowInfoBarError(
_(
"Gate swapping must be performed on gates with equal pin counts." ) );
579 const size_t unitCount = activeUnitIdx.size();
580 std::vector<std::vector<PAD*>> unitPads( unitCount );
581 std::vector<std::vector<int>> unitNets( unitCount );
583 for(
size_t ui = 0; ui < unitCount; ++ui )
585 int uidx = activeUnitIdx[ui];
586 const auto& pins = units[uidx].m_pins;
588 for(
size_t pi = 0; pi < pinCount; ++pi )
594 frame()->ShowInfoBarError(
_(
"Gate swapping failed: pad in unit missing from footprint." ) );
598 unitPads[ui].push_back( p );
603 if( std::ranges::all_of( unitNets,
604 [&](
const auto& nets )
606 return nets == unitNets.front();
609 frame()->ShowInfoBarError(
_(
"Gate swapping has no effect: all selected gates have identical nets." ) );
618 commit = &localCommit;
620 std::shared_ptr<CONNECTIVITY_DATA> connectivity =
board()->GetConnectivity();
623 std::unordered_map<BOARD_CONNECTED_ITEM*, int> itemNewNets;
624 std::vector<PAD*> nonSelectedPadsToChange;
628 std::unordered_set<PAD*> swapPads;
630 for(
const auto& v : unitPads )
631 swapPads.insert( v.begin(), v.end() );
633 for(
size_t pi = 0; pi < pinCount; ++pi )
635 for(
size_t ui = 0; ui < unitCount; ++ui )
637 size_t toIdx = ( ui + 1 ) % unitCount;
639 if( !
ScheduleNetSwap( unitPads[ui][pi], unitNets[toIdx][pi], itemNewNets, error ) )
641 frame()->ShowInfoBarError( error );
648 auto scheduleForPad = [&](
PAD*
pad,
int fromNet,
int toNet ) ->
bool
665 if( ci->GetNetCode() != fromNet )
673 PAD* other =
static_cast<PAD*
>( ci );
675 if( !swapPads.count( other ) )
676 nonSelectedPadsToChange.push_back( other );
684 for(
size_t pi = 0; pi < pinCount; ++pi )
686 for(
size_t ui = 0; ui < unitCount; ++ui )
689 size_t toIdx = ( ui + 1 ) % unitCount;
691 PAD* padFrom = unitPads[fromIdx][pi];
692 int fromNet = unitNets[fromIdx][pi];
693 int toNet = unitNets[toIdx][pi];
695 if( !scheduleForPad( padFrom, fromNet, toNet ) )
697 frame()->ShowInfoBarError( error );
703 bool includeConnectedPads =
true;
714 for(
size_t pi = 0; pi < pinCount; ++pi )
717 for(
size_t ui = 0; ui < unitCount; ++ui )
719 size_t toIdx = ( ui + 1 ) % unitCount;
720 PAD*
pad = unitPads[ui][pi];
721 int newNet = unitNets[toIdx][pi];
723 if(
pad->GetNetCode() == newNet )
727 pad->SetNetCode( newNet );
732 for(
const auto&
kv : itemNewNets )
735 int newNet =
kv.second;
739 PAD* p =
static_cast<PAD*
>( item );
741 if( swapPads.count( p ) )
744 if( !includeConnectedPads )
755 if( !localCommit.
Empty() )
756 localCommit.
Push(
_(
"Swap Gate Nets" ) );
782 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
787 aCollector.
Remove( item );
795 std::vector<FOOTPRINT*> footprintsToPack;
798 footprintsToPack.push_back(
static_cast<FOOTPRINT*
>( item ) );
800 if( footprintsToPack.empty() )
803 BOX2I footprintsBbox;
809 footprintsBbox.
Merge( fp->GetBoundingBox(
false ) );
815 commit.
Push(
_(
"Pack Footprints" ) );
855 std::vector<PCB_SHAPE*> constraintShapes;
857 if(
doMoveSelection( aEvent, &localCommit,
false, &constraintShapes ) )
861 localCommit.
Push(
_(
"Move" ) );
866 constraintTool->DiagnoseAfterMove( constraintShapes );
887 typedef std::numeric_limits<int> coord_limits;
889 static const double max = coord_limits::max() - (int)
COORDS_PADDING;
890 static const double min = -max;
893 testBox.
Offset( aBBoxOffset );
902 testBox.
Offset( aMovement );
910 if( testBox.
GetTop() < min )
921 std::vector<PCB_SHAPE*>* aConstraintShapes )
932 std::unique_ptr<STATUS_TEXT_POPUP> statusPopup;
962 controls->ForceCursorPosition(
false );
964 auto displayConstraintsMessage =
972 msg =
_(
"Angle snap lines: 45°" );
976 msg =
_(
"Angle snap lines: 90°" );
987 auto updateStatusPopup =
988 [&](
EDA_ITEM* item,
size_t ii,
size_t count )
990 wxString popuptext =
_(
"Click to place %s (item %zu of %zu)\n"
991 "Press <esc> to cancel all; double-click to finish" );
1003 msg = wxString::Format(
_(
"%s pad %s" ), fp->
GetReference(),
pad->GetNumber() );
1011 statusPopup = std::make_unique<STATUS_TEXT_POPUP>(
frame() );
1013 statusPopup->SetText( wxString::Format( popuptext, msg, ii, count ) );
1016 std::vector<BOARD_ITEM*> sel_items;
1017 std::vector<BOARD_ITEM*> orig_items;
1021 std::unordered_set<EDA_ITEM*> moved_items;
1030 orig_items.push_back( boardItem );
1032 sel_items.push_back( boardItem );
1033 moved_items.insert( boardItem );
1041 sel_items.push_back(
pad );
1051 if( aConstraintShapes )
1056 if( moveWithReference && !
pickReferencePoint(
_(
"Select reference point for move..." ),
"",
"",
1057 pickedReferencePoint ) )
1067 if( moveIndividually )
1074 orig_items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
1077 updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() );
1078 statusPopup->Popup();
1080 canvas()->SetStatusPopup( statusPopup->GetPanel() );
1086 sel_items.push_back( orig_items[ itemIdx ] );
1088 moved_items.clear();
1089 moved_items.insert( orig_items[itemIdx] );
1092 bool restore_state =
false;
1093 VECTOR2I originalPos = originalCursorPos;
1096 bool updateBBox =
true;
1099 std::shared_ptr<BOARD_CONSTRAINT_MOVE_SESSION> constraintMoveSession;
1107 bool enableLocalRatsnest =
true;
1125 singleFp =
static_cast<FOOTPRINT*
>( it );
1135 if( it->Type() ==
PCB_PAD_T && it->GetParentFootprint() != singleFp )
1142 auto selectionHasFp =
1145 return std::any_of( sel_items.begin(), sel_items.end(),
1148 return it->Type() == PCB_FOOTPRINT_T;
1158 bool frameRotate = frameFp || selectionHasFp();
1166 auto applyMoveFrameOrientation =
1177 prevFrameAngle = newAngle;
1179 if(
delta.IsZero() )
1192 item->Rotate( pivot,
delta );
1198 bool eatFirstMouseUp =
true;
1202 const auto buildConstraintMoveSession =
1205 grid.SetFeasibilityCallback( {} );
1206 constraintMoveSession.reset();
1208 if( moveIndividually || !aConstraintShapes || aConstraintShapes->empty()
1209 || !boardHasConstraints )
1214 auto session = std::make_shared<BOARD_CONSTRAINT_MOVE_SESSION>();
1216 if( session->Build(
board, *aConstraintShapes, aReference ) )
1218 constraintMoveSession = session;
1219 grid.SetFeasibilityCallback(
1221 const std::vector<SNAP_CANDIDATE>& aCandidates )
1223 return session->ResolveCandidates( aContext, aCandidates );
1230 AXIS_LOCK axisLock = AXIS_LOCK::NONE;
1231 long lastArrowKeyAction = 0;
1235 std::shared_ptr<DRC_ENGINE> drcEngine = drcTool ? drcTool->
GetDRCEngine() :
nullptr;
1238 std::unique_ptr<DRC_INTERACTIVE_COURTYARD_CLEARANCE> drc_on_move =
nullptr;
1240 if( showCourtyardConflicts )
1243 drc_on_move->Init(
board );
1247 std::unique_ptr<CREEPAGE_OVERLAY> creepage_on_move = std::make_unique<CREEPAGE_OVERLAY>(
board, drcEngine,
1250 auto configureAngleSnap =
1253 std::vector<VECTOR2I> directions;
1269 grid.SetSnapLineDirections( directions );
1271 if( directions.empty() )
1272 grid.ClearSnapLine();
1274 grid.SetSnapLineOrigin( originalPos );
1277 configureAngleSnap( angleSnapMode );
1278 displayConstraintsMessage( angleSnapMode );
1294 eatFirstMouseUp =
false;
1307 bool redraw3D =
false;
1311 if(
controls->GetSettings().m_lastKeyboardCursorPositionValid )
1313 VECTOR2I keyboardPos(
controls->GetSettings().m_lastKeyboardCursorPosition );
1315 grid.SetSnap(
false );
1329 long action =
controls->GetSettings().m_lastKeyboardCursorCommand;
1333 if( axisLock == AXIS_LOCK::HORIZONTAL )
1339 axisLock = AXIS_LOCK::NONE;
1345 axisLock = AXIS_LOCK::HORIZONTAL;
1350 if( axisLock == AXIS_LOCK::VERTICAL )
1356 axisLock = AXIS_LOCK::NONE;
1362 axisLock = AXIS_LOCK::VERTICAL;
1366 lastArrowKeyAction = action;
1373 m_cursor =
grid.ResolveSnap( mousePos, layers, selectionGrid, sel_items, prevPos ).position;
1376 if( axisLock == AXIS_LOCK::HORIZONTAL )
1378 else if( axisLock == AXIS_LOCK::VERTICAL )
1386 originalBBox =
BOX2I();
1406 bboxMovement += movement;
1414 item->Move( movement );
1435 if( aConstraintShapes && !aConstraintShapes->empty() && movement !=
VECTOR2I()
1436 && boardHasConstraints )
1438 std::vector<PCB_SHAPE*> solved;
1439 std::vector<BOARD_ITEM*> dimensions;
1441 const auto beforeConstraintModify =
1444 aCommit->
Modify( aItem );
1449 dimensions.push_back( aItem );
1452 bool solvedConstraints =
1453 constraintMoveSession
1454 ? constraintMoveSession->Solve(
m_cursor, &solved, beforeConstraintModify )
1456 beforeConstraintModify );
1458 if( solvedConstraints )
1471 item->Move( -movement );
1475 prevPos = previousCursor;
1476 bboxMovement -= movement;
1480 grid.ClearSnapFeedback();
1484 applyMoveFrameOrientation();
1486 if( redraw3D && allowRedraw3D )
1489 if( showCourtyardConflicts && drc_on_move->m_FpInMove.size() )
1492 drc_on_move->UpdateConflicts(
m_toolMgr->GetView(),
true );
1495 creepage_on_move->Update();
1515 enableLocalRatsnest =
false;
1528 static_cast<PCB_SHAPE*
>( item )->UpdateHatching();
1530 item->RunOnChildren(
1536 static_cast<PCB_SHAPE*
>( child )->UpdateHatching();
1547 grid.SetAuxAxes(
false );
1548 buildConstraintMoveSession(
selection.GetReferencePoint() );
1563 boardItem->
Move( movement );
1571 applyMoveFrameOrientation();
1576 if( showCourtyardConflicts )
1578 std::vector<FOOTPRINT*>& FPs = drc_on_move->m_FpInMove;
1583 FPs.push_back(
static_cast<FOOTPRINT*
>( item ) );
1585 item->RunOnChildren(
1589 FPs.push_back(
static_cast<FOOTPRINT*
>( child ) );
1595 creepage_on_move->Start( sel_items );
1604 if( moveWithReference )
1606 selection.SetReferencePoint( pickedReferencePoint );
1611 controls->ForceCursorPosition(
true, pickedReferencePoint );
1618 selection.SetReferencePoint( dragOrigin );
1621 grid.SetSnapLineOrigin( dragOrigin );
1623 grid.SetAuxAxes(
true, dragOrigin );
1631 originalPos =
selection.GetReferencePoint();
1632 buildConstraintMoveSession( originalPos );
1648 if( enableLocalRatsnest )
1656 restore_state =
true;
1665 restore_state =
true;
1689 eatFirstMouseUp =
false;
1697 eatFirstMouseUp =
false;
1704 orig_items[itemIdx]->SetPosition( originalPos );
1706 view()->Update( orig_items[itemIdx] );
1709 if( ++itemIdx < orig_items.size() )
1717 selection.SetReferencePoint( originalPos );
1723 sel_items.push_back( nextItem );
1725 moved_items.clear();
1726 moved_items.insert( nextItem );
1727 updateStatusPopup( nextItem, itemIdx + 1, orig_items.size() );
1730 frameFp = findSingleFp();
1731 frameRotate = frameFp || selectionHasFp();
1757 if( moveIndividually )
1758 orig_items[itemIdx]->SetPosition( originalPos );
1765 configureAngleSnap( angleSnapMode );
1766 displayConstraintsMessage( angleSnapMode );
1794 }
while( ( evt =
Wait() ) );
1797 if( showCourtyardConflicts )
1798 drc_on_move->ClearConflicts(
m_toolMgr->GetView() );
1800 creepage_on_move->Stop();
1802 controls->ForceCursorPosition(
false );
1817 if( sel_items.size() == 1 && sel_items.back()->Type() ==
PCB_GENERATOR_T )
1825 if( sel_items.size() == 1 && sel_items.back()->Type() ==
PCB_GENERATOR_T )
1834 std::set<PCB_GENERATOR*> regenParents;
1846 regenParents.insert( gen );
1849 if( !regenParents.empty() )
1855 gen->EditStart( genTool,
board, aCommit );
1856 gen->Update( genTool,
board, aCommit );
1857 gen->EditFinish( genTool,
board, aCommit );
1861 EDA_ITEMS oItems( orig_items.begin(), orig_items.end() );
1871 return !restore_state;
bool BoardHasConstraints(BOARD *aBoard)
True if the board or any of its footprints carries at least one geometric constraint.
bool ReSolveShapeClustersHoldingEdited(BOARD *aBoard, const std::vector< PCB_SHAPE * > &aEditedShapes, std::vector< PCB_SHAPE * > *aModified, const std::function< void(BOARD_ITEM *)> &aBeforeModify)
Re-solve clusters whose new geometry is authoritative holding every edited shape fully fixed so only ...
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION findPrevious
static TOOL_ACTION findNext
static TOOL_ACTION cursorDblClick
static TOOL_ACTION duplicate
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION increment
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION refreshPreview
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
constexpr const Vec & GetPosition() const
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr coord_type GetLeft() const
constexpr const Vec & GetOrigin() const
constexpr coord_type GetRight() const
constexpr const SizeVec & GetSize() const
constexpr coord_type GetTop() const
constexpr void Offset(coord_type dx, coord_type dy)
constexpr coord_type GetBottom() 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).
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, INFOBAR_MESSAGE_TYPE aType=INFOBAR_MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
void DisplayConstraintsMsg(const wxString &msg)
bool GetOverrideLocks() const
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A set of EDA_ITEMs (i.e., without duplicates).
virtual EDA_ITEM * AsEdaItem()=0
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
virtual void SetPosition(const VECTOR2I &aPos)
wxString GetTypeDesc() const
Return a translated description of the type for this EDA_ITEM for display in user facing messages.
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual EDA_GROUP * GetParentGroup() const
KICAD_T Type() const
Returns the type of object.
EDA_ITEM * GetParent() const
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
static const TOOL_EVENT SelectedEvent
static const TOOL_EVENT SelectedItemsModified
Selected item had a property changed (except movement)
static const TOOL_EVENT SelectedItemsMoved
Selected items were moved, this can be very high frequency on the canvas, use with care.
Used when the right click button is pressed, or when the select tool is in effect.
An interface for classes handling user events controlling the view behavior such as zooming,...
bool IsBOARD_ITEM() const
LSET is a set of PCB_LAYER_IDs.
static void SwapShapePositions(PAD *aLhs, PAD *aRhs)
Swap the visible shape positions of two pads, preserving each pad's own shape offset.
DISPLAY_OPTIONS m_Display
bool m_ShowCourtyardCollisions
static TOOL_ACTION mirrorH
Mirroring of selected items.
static TOOL_ACTION genFinishEdit
static TOOL_ACTION hideLocalRatsnest
static TOOL_ACTION genStartEdit
static TOOL_ACTION moveWithReference
move with a reference point
static TOOL_ACTION angleSnapModeChanged
Notification event when angle mode changes.
static TOOL_ACTION moveExact
Activation of the exact move tool.
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
static TOOL_ACTION genCancelEdit
static TOOL_ACTION genUpdateEdit
static TOOL_ACTION updateLocalRatsnest
static TOOL_ACTION moveIndividually
move items one-by-one
static TOOL_ACTION interactiveOffsetTool
static TOOL_ACTION positionRelative
static TOOL_ACTION move
move or drag an item
static TOOL_ACTION mirrorV
static TOOL_ACTION flip
Flipping of selected objects.
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
Common, abstract interface for edit frames.
virtual EDA_ANGLE GetRotationAngle() const
Return the angle used for rotate operations.
PCBNEW_SETTINGS * GetPcbNewSettings() const
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual PCB_LAYER_ID GetActiveLayer() const
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
virtual bool ChildrenAreIndividuallySelectable() const
static constexpr EDA_ANGLE ANGLE_0
#define IS_MOVING
Item being moved.
a few functions useful in geometry calculations.
LEADER_MODE
The kind of the leader line.
@ DIRECT
Unconstrained point-to-point.
PCB_LAYER_ID
A quick note on layer IDs:
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
@ GEOMETRY
Position or shape has changed.
@ VERTICAL
A segment (or two points) is vertical.
@ HORIZONTAL
A segment (or two points) is horizontal.
EDA_ANGLE GridFrameAngleAt(const BOARD &aBoard, const VECTOR2I &aPos, PCB_GRID_ROLE aRole)
World frame angle of the grid active for aRole at aPos; ANGLE_0 when no grid applies.
EDA_ANGLE GridFrameRotationDelta(const EDA_ANGLE &aFrom, const EDA_ANGLE &aTo, const EDA_ANGLE &aRotationStep)
Minimal rotation that re-aligns an item from frame angle aFrom to aTo, reduced modulo min( aRotationS...
Class to handle a set of BOARD_ITEMs.
std::vector< EDA_ITEM * > EDA_ITEMS
Increment event parameters.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DRILL_MAP_T
class PCB_DRILL_MAP, drill symbols drawn at the holes
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_GRID_ITEM_T
a subgrid placed on a board
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D