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 )
148 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
151 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
153 auto notMovingCondition = [](
const SELECTION& aSelection )
155 return aSelection.Empty() || !aSelection.Front()->IsMoving();
167 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
169 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
184 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
191 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
242 for(
const EDA_ITEM* it : aSelection )
255 if( units.size() < 2 )
258 const wxString& padNum =
pad->GetNumber();
259 bool inAnyUnit =
false;
261 for(
const auto& u : units )
263 for(
const auto& pnum : u.m_pins )
281 else if( single != fp )
292 std::unordered_set<wxString> padNums;
294 for(
const EDA_ITEM* it : aSelection )
301 if(
pad->GetParentFootprint() != aFootprint )
304 padNums.insert(
pad->GetNumber() );
313 const std::unordered_set<wxString>& aSelPadNums )
315 std::vector<int> indices;
319 for(
size_t i = 0; i < units.size(); ++i )
323 for(
const auto& pn : units[i].m_pins )
325 if( aSelPadNums.count( pn ) )
333 indices.push_back(
static_cast<int>( i ) );
343 if( aUnitIndices.empty() )
347 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
349 for(
int idx : aUnitIndices )
351 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
362 std::vector<int> targets;
365 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
367 for(
size_t i = 0; i < units.size(); ++i )
369 if(
static_cast<int>( i ) == aSourceIdx )
372 if( units[i].m_pins.size() != pinCount )
375 targets.push_back(
static_cast<int>( i ) );
405 if( unitsHit.size() != 1 )
408 const int sourceIdx = unitsHit.front();
411 for(
int idx : targets )
414 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
422 int id = aEvent.GetId();
437 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
453 auto menu = std::make_shared<GATE_SWAP_MENU>();
454 menu->SetTool( aTool );
465 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
468 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
473 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
476 subMenu->Evaluate( aSel );
477 return subMenu->GetMenuItemCount() > 0;
480 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
483 subMenu->Evaluate( aSel );
484 return subMenu->GetMenuItemCount() > 0;
488 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
499 if( unitsHit.size() != 1 )
502 const int sourceIdx = unitsHit.front();
504 return !targets.empty();
508 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
519 if( unitsHit.size() < 2 )
525 auto propertiesCondition = [
this](
const SELECTION& aSel )
527 if( aSel.GetSize() == 0 )
541 if( aSel.GetSize() == 1 )
553 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
558 auto canMirror = [
this](
const SELECTION& aSelection )
571 auto singleFootprintCondition =
574 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
576 bool foundFirst =
false;
592 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
594 return frame()->ToolStackIsEmpty();
597 auto notMovingCondition = [](
const SELECTION& aSelection )
599 return aSelection.Empty() || !aSelection.Front()->IsMoving();
602 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
604 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
607 auto isSkippable = [
this](
const SELECTION& aSelection )
613 && notMovingCondition && !inFootprintEditor;
662 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
670 && !inFootprintEditor );
682 menu.AddSeparator( 100 );
683 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
684 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
686 menu.AddSeparator( 150 );
699 menu.AddSeparator( 150 );
715 wxString footprintName;
716 wxArrayString fplist;
721 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
731 footprintName.Trim(
true );
732 footprintName.Trim(
false );
734 if( !footprintName.IsEmpty() )
738 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
838 std::vector<PCB_TRACK*> tracks;
839 std::vector<PCB_TRACK*> vias;
840 std::vector<FOOTPRINT*> footprints;
843 const auto gatherItemsByType = [&]()
850 vias.push_back( track );
852 tracks.push_back( track );
867 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
873 else if( tracks.size() || vias.size() )
900 if( tracks.size() == 2 && vias.size() == 0 )
902 if( connected( tracks[0], tracks[1]->GetStart() )
903 || connected( tracks[0], tracks[1]->GetEnd() ) )
905 aCollector.
Remove( tracks[1] );
908 else if( tracks.size() == 2 && vias.size() == 1 )
910 if( connected( tracks[0], vias[0]->GetPosition() )
911 && connected( tracks[1], vias[0]->GetPosition() ) )
913 aCollector.
Remove( tracks[0] );
914 aCollector.
Remove( tracks[1] );
952 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
954 frame()->ShowInfoBarError( msg );
967 bool restore_state =
false;
981 tanStart.
A = *tanIntersect;
983 tanEnd.
A = *tanIntersect;
986 std::set<PCB_TRACK*> addedTracks;
988 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
990 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
993 int allowedDeviation = theArc->
GetWidth();
995 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
997 for(
int i = 0; i < 3; i++ )
999 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1000 allowedDeviation /= 2;
1002 if( itemsOnAnchor.size() == 1 )
1008 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1010 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1016 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1024 track->
SetEnd( aAnchor );
1033 addedTracks.insert( track );
1039 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1040 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1045 tanStart.
B = trackOnStart->
GetEnd();
1051 tanEnd.
B = trackOnEnd->
GetEnd();
1055 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1058 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1060 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1061 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1063 return trackStartToArcStart < trackEndToArcStart;
1066 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1067 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1098 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1109 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1110 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1111 VECTOR2I tempTangentPoint = tanEndPoint;
1113 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1114 tempTangentPoint = tanStartPoint;
1120 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1121 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1122 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1124 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1125 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1126 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1128 bool eatFirstMouseUp =
true;
1139 std::vector<VECTOR2I> possiblePoints;
1146 for(
const VECTOR2I& candidate : possiblePoints )
1148 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1150 closest = candidate;
1174 theArc->
SetEnd( newEnd );
1175 theArc->
SetMid( newMid );
1177 if( isStartTrackOnStartPt )
1178 trackOnStart->
SetStart( newStart );
1180 trackOnStart->
SetEnd( newStart );
1182 if( isEndTrackOnStartPt )
1185 trackOnEnd->
SetEnd( newEnd );
1188 getView()->Update( trackOnStart );
1189 getView()->Update( trackOnEnd );
1193 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1195 eatFirstMouseUp =
false;
1197 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1199 restore_state =
true;
1204 restore_state =
true;
1212 eatFirstMouseUp =
false;
1224 if( isStartTrackOnStartPt )
1225 newStart = trackOnStart->
GetEnd();
1227 if( isEndTrackOnStartPt )
1228 newEnd = trackOnEnd->
GetEnd();
1232 if( trackOnStart->
GetLength() <= maxLengthIU )
1234 if( addedTracks.count( trackOnStart ) )
1236 getView()->Remove( trackOnStart );
1237 addedTracks.erase( trackOnStart );
1238 delete trackOnStart;
1242 commit.
Remove( trackOnStart );
1248 if( trackOnEnd->
GetLength() <= maxLengthIU )
1250 if( addedTracks.count( trackOnEnd ) )
1252 getView()->Remove( trackOnEnd );
1253 addedTracks.erase( trackOnEnd );
1258 commit.
Remove( trackOnEnd );
1261 theArc->
SetEnd( newEnd );
1270 commit.
Add( added );
1277 commit.
Push(
_(
"Drag Arc Track" ) );
1289 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1294 aCollector.
Remove( item );
1322 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1323 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1326 via->SetDrill( new_drill );
1334 wxCHECK( track, 0 );
1338 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1343 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1368 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1373 aCollector.
Remove( item );
1388 if( newLayer == origLayer )
1399 wxCHECK( track, 0 );
1407 commit.
Push(
_(
"Edit Track Layer" ) );
1424 static int filletRadius = 0;
1430 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1435 aCollector.
Remove( item );
1443 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1459 bool t1Start =
true;
1460 bool t2Start =
true;
1463 std::vector<FILLET_OP> filletOperations;
1464 bool operationPerformedOnAtLeastOne =
false;
1465 bool didOneAttemptFail =
false;
1466 std::set<PCB_TRACK*> processedTracks;
1468 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1470 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1472 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1476 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1482 if( processedTracks.find( trackOther ) == processedTracks.end() )
1484 if( itemsOnAnchor.size() == 1 )
1487 filletOp.t1 = aTrack;
1488 filletOp.t2 = trackOther;
1489 filletOp.t1Start = aStartPoint;
1490 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1491 filletOperations.push_back( filletOp );
1497 didOneAttemptFail =
true;
1511 processFilletOp( track,
true );
1512 processFilletOp( track,
false );
1514 processedTracks.insert( track );
1520 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1522 for( FILLET_OP filletOp : filletOperations )
1530 if( trackOnStart && trackOnEnd )
1533 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1541 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1544 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1546 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1551 aPointToSet.
x = aVecToTest.x;
1552 aPointToSet.
y = aVecToTest.y;
1560 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1561 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1563 didOneAttemptFail =
true;
1567 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1568 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1570 didOneAttemptFail =
true;
1582 itemsToAddToSelection.push_back( tArc );
1587 if( filletOp.t1Start )
1590 track1->
SetEnd( t1newPoint );
1592 if( filletOp.t2Start )
1595 track2->
SetEnd( t2newPoint );
1597 operationPerformedOnAtLeastOne =
true;
1601 commit.
Push(
_(
"Fillet Tracks" ) );
1604 for(
BOARD_ITEM* item : itemsToAddToSelection )
1607 if( !operationPerformedOnAtLeastOne )
1608 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1609 else if( didOneAttemptFail )
1610 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1630 return std::nullopt;
1634 return aPersitentRadius;
1646 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1653 _(
"Add slots in acute corners" ),
1655 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1662 return std::nullopt;
1664 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1665 wxCHECK( results.size() == 2, std::nullopt );
1669 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1670 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1672 catch(
const std::bad_variant_access& )
1675 return std::nullopt;
1678 return s_dogBoneParams;
1692 const int default_setback =
pcbIUScale.mmToIU( 1 );
1694 static CHAMFER_PARAMS params{ default_setback, default_setback };
1696 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1699 return std::nullopt;
1701 params.m_chamfer_setback_a = dlg.
GetValue();
1704 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1715 std::vector<VECTOR2I> pts;
1718 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1725 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1727 aCollector.
Remove( item );
1734 std::set<PCB_SHAPE*> lines_to_add;
1735 std::vector<PCB_SHAPE*> items_to_remove;
1739 std::vector<VECTOR2I> pts;
1746 items_to_remove.push_back( graphic );
1749 pts.emplace_back( start );
1751 pts.emplace_back(
end );
1757 items_to_remove.push_back( graphic );
1759 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1763 for(
size_t jj = 1; jj < pts.size(); ++jj )
1771 lines_to_add.insert( line );
1774 if( pts.size() > 1 )
1779 line->
SetEnd( pts.front() );
1782 lines_to_add.insert( line );
1790 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1797 else if( segmentCount < 2 )
1799 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1817 for(
PCB_SHAPE* item : items_to_remove )
1828 std::vector<BOARD_ITEM*> items_to_select_on_success;
1831 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1836 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1842 items_to_select_on_success.push_back( &aItem );
1846 bool any_items_created = !lines_to_add.empty();
1847 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1849 any_items_created =
true;
1850 items_to_select_on_success.push_back( aItem.get() );
1851 commit.
Add( aItem.release() );
1854 bool any_items_removed = !items_to_remove.empty();
1855 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1858 any_items_removed =
true;
1859 items_to_deselect_on_success.push_back( &aItem );
1865 item_removal_handler );
1868 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1872 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1873 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1875 if( filletRadiusIU.has_value() )
1877 pairwise_line_routine =
1878 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1885 if( dogboneParams.has_value() )
1887 pairwise_line_routine =
1888 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
1895 if( chamfer_params.has_value() )
1897 pairwise_line_routine =
1898 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
1903 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
1906 if( !pairwise_line_routine )
1917 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1919 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1920 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1922 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1927 for(
BOARD_ITEM* item : items_to_select_on_success )
1928 m_selectionTool->AddItemToSel( item,
true );
1931 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1932 m_selectionTool->RemoveItemFromSel( item,
true );
1934 if( any_items_removed )
1937 if( any_items_created )
1943 commit.Push( pairwise_line_routine->GetCommitDescription() );
1945 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
1946 frame()->ShowInfoBarMsg( *msg );
1957 std::vector<VECTOR2I> pts;
1960 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1964 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
1965 aCollector.
Remove( item );
1969 if( zone->IsTeardropArea() )
1970 aCollector.
Remove( item );
1978 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
1987 if( s_toleranceValue <= 0 )
1992 std::vector<PCB_SHAPE*> shapeList;
1996 commit.Modify( item );
2013 commit.
Push(
_(
"Simplify Polygons" ) );
2027 std::vector<VECTOR2I> pts;
2030 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2037 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2039 aCollector.
Remove( item );
2047 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2056 if( s_toleranceValue <= 0 )
2061 std::vector<PCB_SHAPE*> shapeList;
2067 shapeList.push_back( shape );
2068 commit.Modify( shape );
2074 commit.Push(
_(
"Heal Shapes" ) );
2089 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2093 static const std::vector<KICAD_T> polygonBooleanTypes = {
2099 if( !item->
IsType( polygonBooleanTypes ) )
2100 aCollector.
Remove( item );
2109 std::vector<PCB_SHAPE*> items_to_process;
2113 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2118 if( item == last_item )
2119 std::swap( items_to_process.back(), items_to_process.front() );
2125 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2127 commit.Modify( &aItem );
2130 std::vector<BOARD_ITEM*> items_to_select_on_success;
2132 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2134 items_to_select_on_success.push_back( aItem.get() );
2135 commit.Add( aItem.release() );
2138 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2140 commit.Remove( &aItem );
2145 item_removal_handler );
2148 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2150 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2157 wxCHECK(
model,
nullptr );
2161 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2165 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2169 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2174 const auto run_routine = [&]()
2177 for(
PCB_SHAPE* shape : items_to_process )
2178 boolean_routine->ProcessShape( *shape );
2180 boolean_routine->Finalize();
2183 boolean_routine = create_routine();
2185 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2192 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2196 items_to_select_on_success.clear();
2198 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2200 for(
PCB_SHAPE* shape : items_to_process )
2203 items_area[shape] = area;
2212 std::sort( items_to_process.begin(), items_to_process.end(),
2215 return items_area[a] > items_area[b];
2219 boolean_routine = create_routine();
2224 for(
BOARD_ITEM* item : items_to_select_on_success )
2230 commit.Push( boolean_routine->GetCommitDescription() );
2232 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2233 frame()->ShowInfoBarMsg( *msg );
2255 std::vector<PCB_TABLECELL*> cells;
2306 for(
EDA_ITEM* eda_item : selCopy )
2308 if( !eda_item->IsBOARD_ITEM() )
2348 if( editFrame && item )
2368 commit = &localCommit;
2389 std::optional<VECTOR2I> oldRefPt;
2394 oldRefPt =
selection.GetReferencePoint();
2418 bool usePcbShapeCenter =
false;
2425 usePcbShapeCenter =
true;
2429 usePcbShapeCenter =
true;
2435 else if( usePcbShapeCenter )
2447 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2448 rotateAngle = -rotateAngle;
2454 viewBBox.
Merge( item->ViewBBox() );
2463 typedef std::numeric_limits<int> coord_limits;
2468 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2469 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2477 if( item->IsBOARD_ITEM() )
2481 board_item->
Rotate( refPt, rotateAngle );
2485 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2489 if( !localCommit.
Empty() )
2490 localCommit.
Push(
_(
"Rotate" ) );
2507 selection.SetReferencePoint( *oldRefPt );
2525 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2558 commit = &localCommit;
2586 switch( item->Type() )
2589 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2593 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2598 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2610 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2616 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2620 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2629 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2637 if( !localCommit.
Empty() )
2638 localCommit.
Push(
_(
"Mirror" ) );
2667 commit = &localCommit;
2679 auto setJustify = [&](
EDA_TEXT* aTextItem )
2694 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2703 if( !localCommit.
Empty() )
2706 localCommit.
Push(
_(
"Left Justify" ) );
2708 localCommit.
Push(
_(
"Center Justify" ) );
2710 localCommit.
Push(
_(
"Right Justify" ) );
2740 commit = &localCommit;
2755 std::optional<VECTOR2I> oldRefPt;
2758 oldRefPt =
selection.GetReferencePoint();
2784 if( !item->IsBOARD_ITEM() )
2791 boardItem->
Flip( refPt, flipDirection );
2795 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2798 if( !localCommit.
Empty() )
2799 localCommit.
Push(
_(
"Change Side / Flip" ) );
2815 selection.SetReferencePoint( *oldRefPt );
2827 int commitFlags = 0;
2832 int itemsDeleted = 0;
2833 int fieldsHidden = 0;
2834 int fieldsAlreadyHidden = 0;
2838 if( !item->IsBOARD_ITEM() )
2844 switch( item->Type() )
2850 wxASSERT( parentFP );
2851 commit.
Modify( parentFP );
2860 fieldsAlreadyHidden++;
2863 getView()->Update( parentFP );
2880 commit.
Remove( board_item );
2886 commit.
Modify( board_item );
2887 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2899 commit.
Remove( board_item );
2906 commit.
Remove( board_item );
2916 if( !aIsCut && aItems.
GetSize() == 1 )
2919 ZONE* zone =
static_cast<ZONE*
>( board_item );
2921 int outlineIdx, holeIdx;
2942 commit.
Remove( board_item );
2953 commit.Push(
_(
"Delete" ), commitFlags );
2961 commit.
Remove( board_item );
2969 commit.
Remove( board_item );
2978 if( enteredGroup && enteredGroup->
GetItems().empty() )
2983 commit.
Push(
_(
"Cut" ), commitFlags );
2985 else if( itemsDeleted == 0 )
2987 if( fieldsHidden == 1 )
2988 commit.
Push(
_(
"Hide Field" ), commitFlags );
2989 else if( fieldsHidden > 1 )
2990 commit.
Push(
_(
"Hide Fields" ), commitFlags );
2991 else if( fieldsAlreadyHidden > 0 )
2992 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
2996 commit.
Push(
_(
"Delete" ), commitFlags );
3007 std::vector<BOARD_ITEM*> lockedItems;
3097 if( ret == wxID_OK )
3105 selCenter += translation;
3107 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3108 rotation = -rotation;
3112 if( !item->IsBOARD_ITEM() )
3120 boardItem->
Move( translation );
3122 switch( rotationAnchor )
3128 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3133 getView()->Update( boardItem );
3136 commit.
Push(
_(
"Move Exactly" ) );
3192 std::vector<BOARD_ITEM*> new_items;
3199 if( !item->IsBOARD_ITEM() )
3211 switch( orig_item->
Type() )
3231 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3233 dupe_item = orig_item->
Duplicate(
true, &commit );
3239 new_items.push_back( dupe_item );
3240 commit.
Add( dupe_item );
3250 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3252 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3258 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3265 new_items.push_back( dupe_item );
3266 commit.
Add( dupe_item );
3275 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3281 new_items.push_back( aItem );
3282 commit.
Add( aItem );
3287 new_items.push_back( dupe_item );
3288 commit.
Add( dupe_item );
3300 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3306 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3310 commit.
Push(
_(
"Duplicate" ) );
3328 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3330 switch( aCollector[i]->Type() )
3334 default: aCollector.
Remove( i );
break;
3357 commit = &localCommit;
3361 switch( item->Type() )
3371 if( !
pad.CanHaveNumber() )
3375 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3380 pad.SetNumber( *newNumber );
3389 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3394 text.SetText( *newText );
3406 commit->
Push(
_(
"Increment" ) );
3414 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3416 if( aCollector[i]->Type() !=
PCB_PAD_T )
3424 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3435 if( aSelection.
Empty() )
3459 BOX2I nonFieldsBBox;
3463 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3464 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3479 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3483 std::optional<VECTOR2I> pickedPoint;
3493 const auto setPickerLayerSet = [&]()
3499 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3507 setPickerLayerSet();
3510 [&](
const VECTOR2D& aPoint ) ->
bool
3512 pickedPoint = aPoint;
3514 if( !aSuccessMessage.empty() )
3536 if( !aCanceledMessage.empty() )
3548 [&](
const int& aFinalState )
3567 setPickerLayerSet();
3570 evt->SetPassEvent();
3581 canvas()->SetStatusPopup(
nullptr );
3585 aReferencePoint = *pickedPoint;
3587 return pickedPoint.has_value();
3595 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3598 frame()->PushTool( selectReferencePoint );
3613 std::vector<BOARD_ITEM*> items;
3617 if( item->IsBOARD_ITEM() )
3618 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3625 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3626 _(
"Copy canceled" ), refPoint ) )
3628 frame()->PopTool( selectReferencePoint );
3637 selection.SetReferencePoint( refPoint );
3641 frame()->SetStatusText(
_(
"Selection copied" ) );
3644 frame()->PopTool( selectReferencePoint );
3664 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3666 switch( aItem.Type() )
3678 return text.GetShownText(
true );
3692 for(
int row = 0; row <
table.GetRowCount(); ++row )
3694 for(
int col = 0; col <
table.GetColCount(); ++col )
3699 if( col <
table.GetColCount() - 1 )
3705 if( row <
table.GetRowCount() - 1 )
3716 return wxEmptyString;
3719 wxArrayString itemTexts;
3723 if( item->IsBOARD_ITEM() )
3726 wxString itemText = getItemText( *boardItem );
3728 itemText.Trim(
false ).Trim(
true );
3730 if( !itemText.IsEmpty() )
3732 itemTexts.Add( std::move( itemText ) );
3738 if( !itemTexts.empty() )
3740 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3765 board()->BuildConnectivity();
3767 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 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 interactiveOffsetTool
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.
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