67using namespace std::placeholders;
69#include <wx/hyperlink.h>
74#include <dialogs/dialog_tablecell_properties.h>
75#include <dialogs/dialog_table_properties.h>
95 ZONE* zone =
static_cast<ZONE*
>( aItem );
108 if( aSelection.
GetSize() != 1 )
161 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
164 menu->SetUntranslatedTitle(
_HKI(
"Positioning Tools" ) );
166 auto notMovingCondition = [](
const SELECTION& aSelection )
168 return aSelection.Empty() || !aSelection.Front()->IsMoving();
184 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
186 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
205 auto hasCornerCondition =
213 auto hasMidpointCondition =
265 for(
const EDA_ITEM* it : aSelection )
278 if( units.size() < 2 )
281 const wxString& padNum =
pad->GetNumber();
282 bool inAnyUnit =
false;
284 for(
const auto& u : units )
286 for(
const auto& pnum : u.m_pins )
304 else if( single != fp )
315 std::unordered_set<wxString> padNums;
317 for(
const EDA_ITEM* it : aSelection )
324 if(
pad->GetParentFootprint() != aFootprint )
327 padNums.insert(
pad->GetNumber() );
336 const std::unordered_set<wxString>& aSelPadNums )
338 std::vector<int> indices;
342 for(
size_t i = 0; i < units.size(); ++i )
346 for(
const auto& pn : units[i].m_pins )
348 if( aSelPadNums.count( pn ) )
356 indices.push_back(
static_cast<int>( i ) );
366 if( aUnitIndices.empty() )
370 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
372 for(
int idx : aUnitIndices )
374 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
385 std::vector<int> targets;
388 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
390 for(
size_t i = 0; i < units.size(); ++i )
392 if(
static_cast<int>( i ) == aSourceIdx )
395 if( units[i].m_pins.size() != pinCount )
398 targets.push_back(
static_cast<int>( i ) );
428 if( unitsHit.size() != 1 )
431 const int sourceIdx = unitsHit.front();
434 for(
int idx : targets )
437 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
445 int id = aEvent.GetId();
460 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
476 auto menu = std::make_shared<GATE_SWAP_MENU>();
477 menu->SetTool( aTool );
488 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
491 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
496 auto positioningToolsCondition =
500 subMenu->Evaluate( aSel );
501 return subMenu->GetMenuItemCount() > 0;
504 auto shapeModificationCondition =
508 subMenu->Evaluate( aSel );
509 return subMenu->GetMenuItemCount() > 0;
513 auto gateSwapSingleUnitOnOneFootprint =
525 if( unitsHit.size() != 1 )
528 const int sourceIdx = unitsHit.front();
530 return !targets.empty();
534 auto gateSwapMultipleUnitsOnOneFootprint =
546 if( unitsHit.size() < 2 )
553 auto propertiesCondition =
556 if( aSel.GetSize() == 0 )
570 if( aSel.GetSize() == 1 )
582 auto inFootprintEditor =
606 auto multipleFootprintsCondition =
609 bool foundFirst =
false;
625 auto noActiveToolCondition =
628 return frame()->ToolStackIsEmpty();
631 auto notMovingCondition =
634 return aSelection.Empty() || !aSelection.Front()->IsMoving();
637 auto noItemsCondition =
638 [
this](
const SELECTION& aSelections ) ->
bool
640 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
652 && notMovingCondition
653 && !inFootprintEditor;
675 && notMovingCondition );
683 && notMovingCondition );
702 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
710 && !inFootprintEditor );
722 menu.AddSeparator( 100 );
723 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
724 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
726 menu.AddSeparator( 150 );
738 menu.AddSeparator( 150 );
754 wxString footprintName;
755 wxArrayString fplist;
760 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
770 footprintName.Trim(
true );
771 footprintName.Trim(
false );
773 if( !footprintName.IsEmpty() )
777 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
877 std::vector<PCB_TRACK*> tracks;
878 std::vector<PCB_TRACK*> vias;
879 std::vector<FOOTPRINT*> footprints;
882 const auto gatherItemsByType =
890 vias.push_back( track );
892 tracks.push_back( track );
907 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
913 else if( tracks.size() || vias.size() )
940 if( tracks.size() == 2 && vias.size() == 0 )
942 if( connected( tracks[0], tracks[1]->GetStart() )
943 || connected( tracks[0], tracks[1]->GetEnd() ) )
945 aCollector.
Remove( tracks[1] );
948 else if( tracks.size() == 2 && vias.size() == 1 )
950 if( connected( tracks[0], vias[0]->GetPosition() )
951 && connected( tracks[1], vias[0]->GetPosition() ) )
953 aCollector.
Remove( tracks[0] );
954 aCollector.
Remove( tracks[1] );
992 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
994 frame()->ShowInfoBarError( msg );
1007 bool restore_state =
false;
1021 tanStart.
A = *tanIntersect;
1023 tanEnd.
A = *tanIntersect;
1026 std::set<PCB_TRACK*> addedTracks;
1028 auto getUniqueTrackAtAnchorCollinear =
1031 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1034 int allowedDeviation = theArc->
GetWidth();
1036 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1038 for(
int i = 0; i < 3; i++ )
1040 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
1043 allowedDeviation /= 2;
1045 if( itemsOnAnchor.size() == 1 )
1051 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1053 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1059 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1067 track->
SetEnd( aAnchor );
1076 addedTracks.insert( track );
1082 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart);
1083 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1088 tanStart.
B = trackOnStart->
GetEnd();
1094 tanEnd.
B = trackOnEnd->
GetEnd();
1098 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1101 auto isTrackStartClosestToArcStart =
1104 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1105 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1107 return trackStartToArcStart < trackEndToArcStart;
1110 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1111 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1140 auto getFurthestPointToTanInterstect =
1143 if( ( aPointA - *tanIntersect ).EuclideanNorm()
1144 > ( aPointB - *tanIntersect ).EuclideanNorm() )
1155 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1156 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1157 VECTOR2I tempTangentPoint = tanEndPoint;
1159 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1160 tempTangentPoint = tanStartPoint;
1166 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1167 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1168 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1170 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1171 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1172 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1174 bool eatFirstMouseUp =
true;
1186 std::vector<VECTOR2I> possiblePoints;
1193 for(
const VECTOR2I& candidate : possiblePoints )
1195 if( ( candidate -
m_cursor ).SquaredEuclideanNorm()
1196 < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1198 closest = candidate;
1222 theArc->
SetEnd( newEnd );
1223 theArc->
SetMid( newMid );
1225 if( isStartTrackOnStartPt )
1226 trackOnStart->
SetStart( newStart );
1228 trackOnStart->
SetEnd( newStart );
1230 if( isEndTrackOnStartPt )
1233 trackOnEnd->
SetEnd( newEnd );
1236 getView()->Update( trackOnStart );
1237 getView()->Update( trackOnEnd );
1241 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1243 eatFirstMouseUp =
false;
1245 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1247 restore_state =
true;
1252 restore_state =
true;
1261 eatFirstMouseUp =
false;
1273 if( isStartTrackOnStartPt )
1274 newStart = trackOnStart->
GetEnd();
1276 if( isEndTrackOnStartPt )
1277 newEnd = trackOnEnd->
GetEnd();
1282 if( trackOnStart->
GetLength() <= maxLengthIU )
1284 if( addedTracks.count( trackOnStart ) )
1286 getView()->Remove( trackOnStart );
1287 addedTracks.erase( trackOnStart );
1288 delete trackOnStart;
1292 commit.
Remove( trackOnStart );
1298 if( trackOnEnd->
GetLength() <= maxLengthIU )
1300 if( addedTracks.count( trackOnEnd ) )
1302 getView()->Remove( trackOnEnd );
1303 addedTracks.erase( trackOnEnd );
1308 commit.
Remove( trackOnEnd );
1311 theArc->
SetEnd( newEnd );
1320 commit.
Add( added );
1327 commit.
Push(
_(
"Drag Arc Track" ) );
1339 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1344 aCollector.
Remove( item );
1372 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1373 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1376 via->SetDrill( new_drill );
1384 wxCHECK( track, 0 );
1388 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1393 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1418 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1423 aCollector.
Remove( item );
1438 if( newLayer == origLayer )
1449 wxCHECK( track, 0 );
1457 commit.
Push(
_(
"Edit Track Layer" ) );
1474 static int filletRadius = 0;
1480 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1485 aCollector.
Remove( item );
1493 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1509 bool t1Start =
true;
1510 bool t2Start =
true;
1513 std::vector<FILLET_OP> filletOperations;
1514 bool operationPerformedOnAtLeastOne =
false;
1515 bool didOneAttemptFail =
false;
1516 std::set<PCB_TRACK*> processedTracks;
1518 auto processFilletOp =
1519 [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1521 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1523 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1527 if( itemsOnAnchor.size() > 0
1528 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1534 if( processedTracks.find( trackOther ) == processedTracks.end() )
1536 if( itemsOnAnchor.size() == 1 )
1539 filletOp.t1 = aTrack;
1540 filletOp.t2 = trackOther;
1541 filletOp.t1Start = aStartPoint;
1542 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1543 filletOperations.push_back( filletOp );
1549 didOneAttemptFail =
true;
1563 processFilletOp( track,
true );
1564 processFilletOp( track,
false );
1566 processedTracks.insert( track );
1572 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1574 for( FILLET_OP filletOp : filletOperations )
1582 if( trackOnStart && trackOnEnd )
1585 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1593 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1596 auto setIfPointOnSeg =
1599 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1604 aPointToSet.
x = aVecToTest.x;
1605 aPointToSet.
y = aVecToTest.y;
1613 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1614 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1616 didOneAttemptFail =
true;
1620 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1621 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1623 didOneAttemptFail =
true;
1635 itemsToAddToSelection.push_back( tArc );
1640 if( filletOp.t1Start )
1643 track1->
SetEnd( t1newPoint );
1645 if( filletOp.t2Start )
1648 track2->
SetEnd( t2newPoint );
1650 operationPerformedOnAtLeastOne =
true;
1654 commit.
Push(
_(
"Fillet Tracks" ) );
1657 for(
BOARD_ITEM* item : itemsToAddToSelection )
1660 if( !operationPerformedOnAtLeastOne )
1661 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1662 else if( didOneAttemptFail )
1663 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1679 int& aPersitentRadius )
1684 return std::nullopt;
1688 return aPersitentRadius;
1692static std::optional<DOGBONE_CORNER_ROUTINE::PARAMETERS>
1701 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1708 _(
"Add slots in acute corners" ),
1710 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1717 return std::nullopt;
1719 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1720 wxCHECK( results.size() == 2, std::nullopt );
1724 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1725 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1727 catch(
const std::bad_variant_access& )
1730 return std::nullopt;
1733 return s_dogBoneParams;
1747 const int default_setback =
pcbIUScale.mmToIU( 1 );
1749 static CHAMFER_PARAMS params{ default_setback, default_setback };
1752 params.m_chamfer_setback_a );
1755 return std::nullopt;
1757 params.m_chamfer_setback_a = dlg.
GetValue();
1760 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1771 std::vector<VECTOR2I> pts;
1774 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1780 if( !item->
IsType( { PCB_SHAPE_LOCATE_SEGMENT_T,
1781 PCB_SHAPE_LOCATE_POLY_T,
1782 PCB_SHAPE_LOCATE_RECT_T } ) )
1784 aCollector.
Remove( item );
1791 std::set<PCB_SHAPE*> lines_to_add;
1792 std::vector<PCB_SHAPE*> items_to_remove;
1796 std::vector<VECTOR2I> pts;
1803 items_to_remove.push_back( graphic );
1806 pts.emplace_back( start );
1808 pts.emplace_back(
end );
1814 items_to_remove.push_back( graphic );
1816 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1820 for(
size_t jj = 1; jj < pts.size(); ++jj )
1828 lines_to_add.insert( line );
1831 if( pts.size() > 1 )
1836 line->
SetEnd( pts.front() );
1839 lines_to_add.insert( line );
1847 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1854 else if( segmentCount < 2 )
1856 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1874 for(
PCB_SHAPE* item : items_to_remove )
1885 std::vector<BOARD_ITEM*> items_to_select_on_success;
1888 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1893 auto item_modification_handler =
1900 items_to_select_on_success.push_back( &aItem );
1904 bool any_items_created = !lines_to_add.empty();
1905 auto item_creation_handler =
1906 [&]( std::unique_ptr<BOARD_ITEM> aItem )
1908 any_items_created =
true;
1909 items_to_select_on_success.push_back( aItem.get() );
1910 commit.
Add( aItem.release() );
1913 bool any_items_removed = !items_to_remove.empty();
1914 auto item_removal_handler =
1918 any_items_removed =
true;
1919 items_to_deselect_on_success.push_back( &aItem );
1925 item_creation_handler, item_modification_handler, item_removal_handler );
1928 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1932 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1933 std::optional<int> filletRadiusIU =
1936 if( filletRadiusIU.has_value() )
1938 pairwise_line_routine = std::make_unique<LINE_FILLET_ROUTINE>(
1939 frame()->GetModel(), change_handler, *filletRadiusIU );
1944 std::optional<DOGBONE_CORNER_ROUTINE::PARAMETERS> dogboneParams =
1947 if( dogboneParams.has_value() )
1949 pairwise_line_routine = std::make_unique<DOGBONE_CORNER_ROUTINE>(
1950 frame()->GetModel(), change_handler, *dogboneParams );
1957 if( chamfer_params.has_value() )
1959 pairwise_line_routine = std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(),
1966 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(),
1970 if( !pairwise_line_routine )
1981 if( ( a->GetFlags() & STRUCT_DELETED ) == 0
1982 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1984 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1985 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1987 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1992 for(
BOARD_ITEM* item : items_to_select_on_success )
1993 m_selectionTool->AddItemToSel( item,
true );
1996 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1997 m_selectionTool->RemoveItemFromSel( item,
true );
1999 if( any_items_removed )
2002 if( any_items_created )
2008 commit.Push( pairwise_line_routine->GetCommitDescription() );
2010 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
2011 frame()->ShowInfoBarMsg( *msg );
2022 std::vector<VECTOR2I> pts;
2025 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2029 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2030 aCollector.
Remove( item );
2034 if( zone->IsTeardropArea() )
2035 aCollector.
Remove( item );
2043 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2053 if( s_toleranceValue <= 0 )
2058 std::vector<PCB_SHAPE*> shapeList;
2062 commit.Modify( item );
2079 commit.
Push(
_(
"Simplify Polygons" ) );
2093 std::vector<VECTOR2I> pts;
2096 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2102 if( !item->
IsType( { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T,
2103 PCB_SHAPE_LOCATE_BEZIER_T } ) )
2105 aCollector.
Remove( item );
2113 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2123 if( s_toleranceValue <= 0 )
2128 std::vector<PCB_SHAPE*> shapeList;
2134 shapeList.push_back( shape );
2135 commit.Modify( shape );
2141 commit.Push(
_(
"Heal Shapes" ) );
2156 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2160 static const std::vector<KICAD_T> polygonBooleanTypes = {
2166 if( !item->
IsType( polygonBooleanTypes ) )
2167 aCollector.
Remove( item );
2176 std::vector<PCB_SHAPE*> items_to_process;
2180 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2185 if( item == last_item )
2186 std::swap( items_to_process.back(), items_to_process.front() );
2192 auto item_modification_handler =
2195 commit.Modify( &aItem );
2198 std::vector<BOARD_ITEM*> items_to_select_on_success;
2200 auto item_creation_handler =
2201 [&]( std::unique_ptr<BOARD_ITEM> aItem )
2203 items_to_select_on_success.push_back( aItem.get() );
2204 commit.Add( aItem.release() );
2207 auto item_removal_handler =
2210 commit.Remove( &aItem );
2215 item_modification_handler,
2216 item_removal_handler );
2219 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2221 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2228 wxCHECK( model,
nullptr );
2232 return std::make_unique<POLYGON_MERGE_ROUTINE>( model, change_handler );
2236 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>( model, change_handler );
2240 return std::make_unique<POLYGON_INTERSECT_ROUTINE>( model, change_handler );
2245 const auto run_routine = [&]()
2248 for(
PCB_SHAPE* shape : items_to_process )
2249 boolean_routine->ProcessShape( *shape );
2251 boolean_routine->Finalize();
2254 boolean_routine = create_routine();
2256 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2263 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2267 items_to_select_on_success.clear();
2269 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2271 for(
PCB_SHAPE* shape : items_to_process )
2274 items_area[shape] = area;
2283 std::sort( items_to_process.begin(), items_to_process.end(),
2286 return items_area[a] > items_area[b];
2290 boolean_routine = create_routine();
2295 for(
BOARD_ITEM* item : items_to_select_on_success )
2301 commit.Push( boolean_routine->GetCommitDescription() );
2303 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2304 frame()->ShowInfoBarMsg( *msg );
2326 std::vector<PCB_TABLECELL*> cells;
2376 for(
EDA_ITEM* eda_item : selCopy )
2378 if( !eda_item->IsBOARD_ITEM() )
2418 if( editFrame && item )
2438 commit = &localCommit;
2459 std::optional<VECTOR2I> oldRefPt;
2464 oldRefPt =
selection.GetReferencePoint();
2488 bool usePcbShapeCenter =
false;
2495 usePcbShapeCenter =
true;
2499 usePcbShapeCenter =
true;
2505 else if( usePcbShapeCenter )
2517 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2518 rotateAngle = -rotateAngle;
2524 viewBBox.
Merge( item->ViewBBox() );
2533 typedef std::numeric_limits<int> coord_limits;
2538 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max
2539 || rotEnd.
x < min || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2547 if( item->IsBOARD_ITEM() )
2551 board_item->
Rotate( refPt, rotateAngle );
2555 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2559 if( !localCommit.
Empty() )
2560 localCommit.
Push(
_(
"Rotate" ) );
2577 selection.SetReferencePoint( *oldRefPt );
2595 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2638 commit = &localCommit;
2666 switch( item->Type() )
2669 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2673 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2678 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2690 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2696 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2700 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2708 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2717 if( !localCommit.
Empty() )
2718 localCommit.
Push(
_(
"Mirror" ) );
2747 commit = &localCommit;
2775 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2784 if( !localCommit.
Empty() )
2787 localCommit.
Push(
_(
"Left Justify" ) );
2789 localCommit.
Push(
_(
"Center Justify" ) );
2791 localCommit.
Push(
_(
"Right Justify" ) );
2821 commit = &localCommit;
2836 std::optional<VECTOR2I> oldRefPt;
2839 oldRefPt =
selection.GetReferencePoint();
2865 if( !item->IsBOARD_ITEM() )
2872 boardItem->
Flip( refPt, flipDirection );
2876 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2879 if( !localCommit.
Empty() )
2880 localCommit.
Push(
_(
"Change Side / Flip" ) );
2896 selection.SetReferencePoint( *oldRefPt );
2908 int commitFlags = 0;
2913 int itemsDeleted = 0;
2914 int fieldsHidden = 0;
2915 int fieldsAlreadyHidden = 0;
2919 if( !item->IsBOARD_ITEM() )
2925 switch( item->Type() )
2931 wxASSERT( parentFP );
2932 commit.
Modify( parentFP );
2941 fieldsAlreadyHidden++;
2944 getView()->Update( parentFP );
2961 commit.
Remove( board_item );
2967 commit.
Modify( board_item );
2968 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2980 commit.
Remove( board_item );
2987 commit.
Remove( board_item );
2997 if( !aIsCut && aItems.
GetSize() == 1 )
3000 ZONE* zone =
static_cast<ZONE*
>( board_item );
3002 int outlineIdx, holeIdx;
3023 commit.
Remove( board_item );
3034 commit.Push(
_(
"Delete" ), commitFlags );
3042 commit.
Remove( board_item );
3050 commit.
Remove( board_item );
3059 if( enteredGroup && enteredGroup->
GetItems().empty() )
3064 commit.
Push(
_(
"Cut" ), commitFlags );
3066 else if( itemsDeleted == 0 )
3068 if( fieldsHidden == 1 )
3069 commit.
Push(
_(
"Hide Field" ), commitFlags );
3070 else if( fieldsHidden > 1 )
3071 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3072 else if( fieldsAlreadyHidden > 0 )
3073 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3077 commit.
Push(
_(
"Delete" ), commitFlags );
3088 std::vector<BOARD_ITEM*> lockedItems;
3180 if( ret == wxID_OK )
3188 selCenter += translation;
3190 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3191 rotation = -rotation;
3195 if( !item->IsBOARD_ITEM() )
3203 boardItem->
Move( translation );
3205 switch( rotationAnchor )
3211 boardItem->
Rotate( selCenter, angle );
3214 boardItem->
Rotate(
frame()->GetScreen()->m_LocalOrigin, angle );
3217 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3222 getView()->Update( boardItem );
3225 commit.
Push(
_(
"Move Exactly" ) );
3281 std::vector<BOARD_ITEM*> new_items;
3288 if( !item->IsBOARD_ITEM() )
3300 switch( orig_item->
Type() )
3320 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3322 dupe_item = orig_item->
Duplicate(
true, &commit );
3328 new_items.push_back( dupe_item );
3329 commit.
Add( dupe_item );
3339 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3341 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3347 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3354 new_items.push_back( dupe_item );
3355 commit.
Add( dupe_item );
3364 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3370 new_items.push_back( aItem );
3371 commit.
Add( aItem );
3376 new_items.push_back( dupe_item );
3377 commit.
Add( dupe_item );
3391 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3397 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3401 commit.
Push(
_(
"Duplicate" ) );
3419 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3421 switch( aCollector[i]->Type() )
3451 commit = &localCommit;
3455 switch( item->Type() )
3465 if( !
pad.CanHaveNumber() )
3469 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3474 pad.SetNumber( *newNumber );
3483 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3488 text.SetText( *newText );
3501 commit->
Push(
_(
"Increment" ) );
3509 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3511 if( aCollector[i]->Type() !=
PCB_PAD_T )
3519 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3530 if( aSelection.
Empty() )
3554 BOX2I nonFieldsBBox;
3558 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3559 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3574 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3578 std::optional<VECTOR2I> pickedPoint;
3588 const auto setPickerLayerSet =
3595 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3603 setPickerLayerSet();
3606 [&](
const VECTOR2D& aPoint ) ->
bool
3608 pickedPoint = aPoint;
3610 if( !aSuccessMessage.empty() )
3632 if( !aCanceledMessage.empty() )
3644 [&](
const int& aFinalState )
3663 setPickerLayerSet();
3666 evt->SetPassEvent();
3677 canvas()->SetStatusPopup(
nullptr );
3681 aReferencePoint = *pickedPoint;
3683 return pickedPoint.has_value();
3692 "pcbnew.InteractiveEdit.selectReferencePoint",
3695 frame()->PushTool( selectReferencePoint );
3710 std::vector<BOARD_ITEM*> items;
3714 if( item->IsBOARD_ITEM() )
3715 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3723 _(
"Selection copied" ),
_(
"Copy canceled" ), refPoint ) )
3725 frame()->PopTool( selectReferencePoint );
3734 selection.SetReferencePoint( refPoint );
3738 frame()->SetStatusText(
_(
"Selection copied" ) );
3741 frame()->PopTool( selectReferencePoint );
3761 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3763 switch( aItem.Type() )
3775 return text.GetShownText(
true );
3789 for(
int row = 0; row <
table.GetRowCount(); ++row )
3791 for(
int col = 0; col <
table.GetColCount(); ++col )
3796 if( col <
table.GetColCount() - 1 )
3802 if( row <
table.GetRowCount() - 1 )
3813 return wxEmptyString;
3816 wxArrayString itemTexts;
3820 if( item->IsBOARD_ITEM() )
3823 wxString itemText = getItemText( *boardItem );
3825 itemText.Trim(
false ).Trim(
true );
3827 if( !itemText.IsEmpty() )
3829 itemTexts.Add( std::move( itemText ) );
3835 if( !itemTexts.empty() )
3837 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3862 board()->BuildConnectivity();
3864 canvas()->RedrawRatsnest();
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION decrementPrimary
static TOOL_ACTION pickerSubTool
static TOOL_ACTION unselectAll
static TOOL_ACTION decrementSecondary
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
static TOOL_ACTION pasteSpecial
static TOOL_ACTION rightJustify
static TOOL_ACTION pageSettings
static TOOL_ACTION incrementSecondary
static TOOL_ACTION duplicate
static TOOL_ACTION incrementPrimary
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION increment
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION leftJustify
static TOOL_ACTION copyAsText
static TOOL_ACTION refreshPreview
static TOOL_ACTION selectAll
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
static TOOL_ACTION centerJustify
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
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...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
void SetLocked(bool aLocked) override
bool IsLocked() const override
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
BOARD_ITEM_CONTAINER * GetParent() const
virtual void Normalize()
Perform any normalization required after a user rotate and/or flip.
virtual void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Flip this object, i.e.
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
const FOOTPRINTS & Footprints() const
constexpr const Vec & GetPosition() const
constexpr const Vec GetEnd() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr bool IsValid() const
Represent basic circle geometry with utility geometry functions.
VECTOR2I Center
Public to make access simpler.
int Radius
Public to make access simpler.
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Construct this circle such that it is tangent to the given segments and passes through the given poin...
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetBoard(BOARD *aBoard)
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 & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
@ TABLECELL_PROPS_EDIT_TABLE
enum TABLECELL_PROPS_RETVALUE GetReturnValue()
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, WX_INFOBAR::MESSAGE_TYPE aType=WX_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 DisplayToolMsg(const wxString &msg) override
std::unordered_set< EDA_ITEM * > & GetItems()
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetEnd(const VECTOR2I &aEnd)
void SetWidth(int aWidth)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual bool IsVisible() const
virtual void SetVisible(bool aVisible)
static const TOOL_EVENT SelectedEvent
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
static const TOOL_EVENT UnselectedEvent
Used when the right click button is pressed, or when the select tool is in effect.
static const std::vector< KICAD_T > DraggableItems
A scan list for items that can be dragged.
A handler that is based on a set of callbacks provided by the user of the ITEM_MODIFICATION_ROUTINE.
An interface for classes handling user events controlling the view behavior such as zooming,...
bool IsBOARD_ITEM() const
virtual wxString GetClass() const =0
Return the class name.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllLayersMask()
A collection of nets and the parameters used to route or test these nets.
int GetuViaDiameter() const
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
VECTOR2I GetPosition() const override
void SetDelta(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void FlipPrimitives(FLIP_DIRECTION aFlipDirection)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
void SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
void SetPosition(const VECTOR2I &aPos) override
const VECTOR2I & GetOffset(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
static TOOL_ACTION drag45Degree
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
static TOOL_ACTION layerPrev
static TOOL_ACTION changeTrackWidth
Update selected tracks & vias to the current track & via dimensions.
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
static TOOL_ACTION mirrorH
Mirroring of selected items.
static TOOL_ACTION updateFootprint
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
static TOOL_ACTION pointEditorMoveMidpoint
static TOOL_ACTION getAndPlace
Find an item and start moving.
static TOOL_ACTION routerRouteSelectedFromEnd
static TOOL_ACTION swapPadNets
Swap nets between selected pads/gates (and connected copper)
static TOOL_ACTION properties
Activation of the edit tool.
static TOOL_ACTION editFpInFpEditor
static TOOL_ACTION moveWithReference
move with a reference point
static TOOL_ACTION changeTrackLayerPrev
static TOOL_ACTION swap
Swapping of selected items.
static TOOL_ACTION routerAutorouteSelected
static TOOL_ACTION moveExact
Activation of the exact move tool.
static TOOL_ACTION intersectPolygons
Intersection of multiple polygons.
static TOOL_ACTION pointEditorMoveCorner
static TOOL_ACTION genRemove
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
static TOOL_ACTION assignNetClass
static TOOL_ACTION packAndMoveFootprints
Pack and start moving selected footprints.
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
static TOOL_ACTION healShapes
Connect selected shapes, possibly extending or cutting them, or adding extra geometry.
static TOOL_ACTION dragFreeAngle
static TOOL_ACTION positionRelativeInteractively
static TOOL_ACTION inspectClearance
static TOOL_ACTION updateLocalRatsnest
static TOOL_ACTION updateFootprints
static TOOL_ACTION deleteFull
static TOOL_ACTION unrouteSegment
Removes track segment from the selected item to the next segment.
static TOOL_ACTION moveIndividually
move items one-by-one
static TOOL_ACTION changeFootprints
static TOOL_ACTION chamferLines
Chamfer (i.e. adds a straight line) all selected straight lines by a user defined setback.
static TOOL_ACTION dogboneCorners
Add "dogbone" corners to selected lines to allow routing with a cutter radius.
static TOOL_ACTION filletTracks
Fillet (i.e. adds an arc tangent to) all selected straight tracks by a user defined radius.
static TOOL_ACTION simplifyPolygons
Simplify polygon outlines.
static TOOL_ACTION footprintProperties
static TOOL_ACTION filletLines
Fillet (i.e. adds an arc tangent to) all selected straight lines by a user defined radius.
static TOOL_ACTION changeFootprint
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
static TOOL_ACTION positionRelative
static TOOL_ACTION move
move or drag an item
static TOOL_ACTION mirrorV
static TOOL_ACTION mergePolygons
Merge multiple polygons into a single polygon.
static TOOL_ACTION subtractPolygons
Subtract polygons from other polygons.
static TOOL_ACTION changeTrackLayerNext
static TOOL_ACTION flip
Flipping of selected objects.
static TOOL_ACTION editVertices
Edit polygon vertices in a table.
static TOOL_ACTION swapGateNets
static TOOL_ACTION layerNext
static TOOL_ACTION extendLines
Extend selected lines to meet at a point.
static TOOL_ACTION routerRouteSelected
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
virtual double GetLength() const override
Return the length of the arc track.
void SetMid(const VECTOR2I &aMid)
EDA_ANGLE GetAngle() const
const VECTOR2I & GetMid() const
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Common, abstract interface for edit frames.
virtual void OnEditItemRequest(BOARD_ITEM *aItem)
Install the corresponding dialog editor for the given item.
void OpenVertexEditor(BOARD_ITEM *aItem)
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
static const TOOL_EVENT & SnappingModeChangedByKeyEvent()
Hotkey feedback.
A set of BOARD_ITEMs (i.e., without duplicates).
Tool that displays edit points allowing to modify items by dragging the points.
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
void SetHasSolderMask(bool aVal)
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
void SetEnd(const VECTOR2I &aEnd)
bool HasSolderMask() const
void SetStart(const VECTOR2I &aStart)
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
std::optional< int > GetLocalSolderMaskMargin() const
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Return STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if point if near (dist = m...
virtual void SetWidth(int aWidth)
virtual int GetWidth() const
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
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...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
virtual unsigned int GetSize() const override
Return the number of stored items.
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
int Size() const
Returns the number of selected parts.
std::deque< EDA_ITEM * > & Items()
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
bool HasReferencePoint() const
size_t CountType(KICAD_T aType) const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void SimplifyOutlines(int aMaxError=0)
Simplifies the lines in the polyset.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Heuristically increment a string's n'th part from the right.
void SetSkipIOSQXZ(bool aSkip)
If a alphabetic part is found, skip the letters I, O, S, Q, X, Z.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2_TRAITS< int32_t >::extended_type extended_type
A dialog like WX_UNIT_ENTRY_DIALOG, but with multiple entries.
std::vector< RESULT > GetValues() const
Returns the values in the order they were added.
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
int GetValue()
Return the value in internal units.
Handle a list of polygons defining a copper zone.
bool UnFill()
Removes the zone filling.
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Test if the given point is contained within a cutout of the zone.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
bool IsTeardropArea() const
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static constexpr EDA_ANGLE ANGLE_180
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
#define IS_NEW
New item, just created.
#define STRUCT_DELETED
flag indication structures to be erased
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
@ LAYER_SCHEMATIC_DRAWINGSHEET
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Class to handle a set of BOARD_ITEMs.
@ ID_POPUP_PCB_SWAP_UNIT_LAST
@ ID_POPUP_PCB_SWAP_UNIT_BASE
std::optional< VECTOR2I > OPT_VECTOR2I
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
Parameters that define a simple chamfer operation.
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ 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_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_SHAPE_LOCATE_CIRCLE_T
@ PCB_SHAPE_LOCATE_SEGMENT_T
@ PCB_SHAPE_LOCATE_RECT_T
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_SHAPE_LOCATE_BEZIER_T
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_SHAPE_LOCATE_POLY_T
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D