68using namespace std::placeholders;
70#include <wx/hyperlink.h>
75#include <dialogs/dialog_tablecell_properties.h>
76#include <dialogs/dialog_table_properties.h>
96 ZONE* zone =
static_cast<ZONE*
>( aItem );
109 if( aSelection.
GetSize() != 1 )
149 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
152 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
154 auto notMovingCondition = [](
const SELECTION& aSelection )
156 return aSelection.Empty() || !aSelection.Front()->IsMoving();
168 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
170 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
185 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
192 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
199 auto canAddCornerCondition = [](
const SELECTION& aSelection )
201 const EDA_ITEM* item = aSelection.Front();
206 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
208 const EDA_ITEM* item = aSelection.Front();
213 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
279 for(
const EDA_ITEM* it : aSelection )
292 if( units.size() < 2 )
295 const wxString& padNum =
pad->GetNumber();
296 bool inAnyUnit =
false;
298 for(
const auto& u : units )
300 for(
const auto& pnum : u.m_pins )
318 else if( single != fp )
329 std::unordered_set<wxString> padNums;
331 for(
const EDA_ITEM* it : aSelection )
338 if(
pad->GetParentFootprint() != aFootprint )
341 padNums.insert(
pad->GetNumber() );
350 const std::unordered_set<wxString>& aSelPadNums )
352 std::vector<int> indices;
356 for(
size_t i = 0; i < units.size(); ++i )
360 for(
const auto& pn : units[i].m_pins )
362 if( aSelPadNums.count( pn ) )
370 indices.push_back(
static_cast<int>( i ) );
380 if( aUnitIndices.empty() )
384 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
386 for(
int idx : aUnitIndices )
388 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
399 std::vector<int> targets;
402 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
404 for(
size_t i = 0; i < units.size(); ++i )
406 if(
static_cast<int>( i ) == aSourceIdx )
409 if( units[i].m_pins.size() != pinCount )
412 targets.push_back(
static_cast<int>( i ) );
442 if( unitsHit.size() != 1 )
445 const int sourceIdx = unitsHit.front();
448 for(
int idx : targets )
451 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
459 int id = aEvent.GetId();
474 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
490 auto menu = std::make_shared<GATE_SWAP_MENU>();
491 menu->SetTool( aTool );
502 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
505 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
510 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
513 subMenu->Evaluate( aSel );
514 return subMenu->GetMenuItemCount() > 0;
517 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
520 subMenu->Evaluate( aSel );
521 return subMenu->GetMenuItemCount() > 0;
525 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
536 if( unitsHit.size() != 1 )
539 const int sourceIdx = unitsHit.front();
541 return !targets.empty();
545 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
556 if( unitsHit.size() < 2 )
562 auto propertiesCondition = [
this](
const SELECTION& aSel )
564 if( aSel.GetSize() == 0 )
578 if( aSel.GetSize() == 1 )
590 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
595 auto canMirror = [
this](
const SELECTION& aSelection )
608 auto singleFootprintCondition =
611 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
613 bool foundFirst =
false;
629 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
631 return frame()->ToolStackIsEmpty();
634 auto notMovingCondition = [](
const SELECTION& aSelection )
636 return aSelection.Empty() || !aSelection.Front()->IsMoving();
639 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
641 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
644 auto isSkippable = [
this](
const SELECTION& aSelection )
650 && notMovingCondition && !inFootprintEditor;
699 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
706 && !inFootprintEditor );
718 menu.AddSeparator( 100 );
719 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
720 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
722 menu.AddSeparator( 150 );
735 menu.AddSeparator( 150 );
751 wxString footprintName;
752 wxArrayString fplist;
757 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
767 footprintName.Trim(
true );
768 footprintName.Trim(
false );
770 if( !footprintName.IsEmpty() )
774 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
874 std::vector<PCB_TRACK*> tracks;
875 std::vector<PCB_TRACK*> vias;
876 std::vector<FOOTPRINT*> footprints;
879 const auto gatherItemsByType = [&]()
886 vias.push_back( track );
888 tracks.push_back( track );
903 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
909 else if( tracks.size() || vias.size() )
936 if( tracks.size() == 2 && vias.size() == 0 )
938 if( connected( tracks[0], tracks[1]->GetStart() )
939 || connected( tracks[0], tracks[1]->GetEnd() ) )
941 aCollector.
Remove( tracks[1] );
944 else if( tracks.size() == 2 && vias.size() == 1 )
946 if( connected( tracks[0], vias[0]->GetPosition() )
947 && connected( tracks[1], vias[0]->GetPosition() ) )
949 aCollector.
Remove( tracks[0] );
950 aCollector.
Remove( tracks[1] );
988 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
990 frame()->ShowInfoBarError( msg );
1003 bool restore_state =
false;
1017 tanStart.
A = *tanIntersect;
1019 tanEnd.
A = *tanIntersect;
1022 std::set<PCB_TRACK*> addedTracks;
1024 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1026 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1029 int allowedDeviation = theArc->
GetWidth();
1031 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1033 for(
int i = 0; i < 3; i++ )
1035 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1036 allowedDeviation /= 2;
1038 if( itemsOnAnchor.size() == 1 )
1044 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1046 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1052 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1060 track->
SetEnd( aAnchor );
1069 addedTracks.insert( track );
1075 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1076 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1081 tanStart.
B = trackOnStart->
GetEnd();
1087 tanEnd.
B = trackOnEnd->
GetEnd();
1091 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1094 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1096 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1097 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1099 return trackStartToArcStart < trackEndToArcStart;
1102 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1103 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1134 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1145 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1146 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1147 VECTOR2I tempTangentPoint = tanEndPoint;
1149 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1150 tempTangentPoint = tanStartPoint;
1156 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1157 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1158 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1160 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1161 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1162 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1164 bool eatFirstMouseUp =
true;
1175 std::vector<VECTOR2I> possiblePoints;
1182 for(
const VECTOR2I& candidate : possiblePoints )
1184 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1186 closest = candidate;
1210 theArc->
SetEnd( newEnd );
1211 theArc->
SetMid( newMid );
1213 if( isStartTrackOnStartPt )
1214 trackOnStart->
SetStart( newStart );
1216 trackOnStart->
SetEnd( newStart );
1218 if( isEndTrackOnStartPt )
1221 trackOnEnd->
SetEnd( newEnd );
1224 getView()->Update( trackOnStart );
1225 getView()->Update( trackOnEnd );
1229 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1231 eatFirstMouseUp =
false;
1233 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1235 restore_state =
true;
1240 restore_state =
true;
1248 eatFirstMouseUp =
false;
1260 if( isStartTrackOnStartPt )
1261 newStart = trackOnStart->
GetEnd();
1263 if( isEndTrackOnStartPt )
1264 newEnd = trackOnEnd->
GetEnd();
1268 if( trackOnStart->
GetLength() <= maxLengthIU )
1270 if( addedTracks.count( trackOnStart ) )
1272 getView()->Remove( trackOnStart );
1273 addedTracks.erase( trackOnStart );
1274 delete trackOnStart;
1278 commit.
Remove( trackOnStart );
1284 if( trackOnEnd->
GetLength() <= maxLengthIU )
1286 if( addedTracks.count( trackOnEnd ) )
1288 getView()->Remove( trackOnEnd );
1289 addedTracks.erase( trackOnEnd );
1294 commit.
Remove( trackOnEnd );
1297 theArc->
SetEnd( newEnd );
1306 commit.
Add( added );
1313 commit.
Push(
_(
"Drag Arc Track" ) );
1325 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1330 aCollector.
Remove( item );
1358 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1359 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1362 via->SetDrill( new_drill );
1370 wxCHECK( track, 0 );
1374 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1379 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1404 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1409 aCollector.
Remove( item );
1424 if( newLayer == origLayer )
1435 wxCHECK( track, 0 );
1443 commit.
Push(
_(
"Edit Track Layer" ) );
1460 static int filletRadius = 0;
1466 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1471 aCollector.
Remove( item );
1479 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1495 bool t1Start =
true;
1496 bool t2Start =
true;
1499 std::vector<FILLET_OP> filletOperations;
1500 bool operationPerformedOnAtLeastOne =
false;
1501 bool didOneAttemptFail =
false;
1502 std::set<PCB_TRACK*> processedTracks;
1504 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1506 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1508 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1512 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1518 if( processedTracks.find( trackOther ) == processedTracks.end() )
1520 if( itemsOnAnchor.size() == 1 )
1523 filletOp.t1 = aTrack;
1524 filletOp.t2 = trackOther;
1525 filletOp.t1Start = aStartPoint;
1526 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1527 filletOperations.push_back( filletOp );
1533 didOneAttemptFail =
true;
1547 processFilletOp( track,
true );
1548 processFilletOp( track,
false );
1550 processedTracks.insert( track );
1556 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1558 for( FILLET_OP filletOp : filletOperations )
1566 if( trackOnStart && trackOnEnd )
1569 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1577 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1580 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1582 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1587 aPointToSet.
x = aVecToTest.x;
1588 aPointToSet.
y = aVecToTest.y;
1596 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1597 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1599 didOneAttemptFail =
true;
1603 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1604 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1606 didOneAttemptFail =
true;
1618 itemsToAddToSelection.push_back( tArc );
1623 if( filletOp.t1Start )
1626 track1->
SetEnd( t1newPoint );
1628 if( filletOp.t2Start )
1631 track2->
SetEnd( t2newPoint );
1633 operationPerformedOnAtLeastOne =
true;
1637 commit.
Push(
_(
"Fillet Tracks" ) );
1640 for(
BOARD_ITEM* item : itemsToAddToSelection )
1643 if( !operationPerformedOnAtLeastOne )
1644 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1645 else if( didOneAttemptFail )
1646 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1666 return std::nullopt;
1670 return aPersitentRadius;
1682 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1689 _(
"Add slots in acute corners" ),
1691 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1698 return std::nullopt;
1700 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1701 wxCHECK( results.size() == 2, std::nullopt );
1705 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1706 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1708 catch(
const std::bad_variant_access& )
1711 return std::nullopt;
1714 return s_dogBoneParams;
1728 const int default_setback =
pcbIUScale.mmToIU( 1 );
1730 static CHAMFER_PARAMS params{ default_setback, default_setback };
1732 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1735 return std::nullopt;
1737 params.m_chamfer_setback_a = dlg.
GetValue();
1740 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1751 std::vector<VECTOR2I> pts;
1754 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1761 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1763 aCollector.
Remove( item );
1770 std::set<PCB_SHAPE*> lines_to_add;
1771 std::vector<PCB_SHAPE*> items_to_remove;
1775 std::vector<VECTOR2I> pts;
1782 items_to_remove.push_back( graphic );
1785 pts.emplace_back( start );
1787 pts.emplace_back(
end );
1793 items_to_remove.push_back( graphic );
1795 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1799 for(
size_t jj = 1; jj < pts.size(); ++jj )
1807 lines_to_add.insert( line );
1810 if( pts.size() > 1 )
1815 line->
SetEnd( pts.front() );
1818 lines_to_add.insert( line );
1826 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1833 else if( segmentCount < 2 )
1835 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1853 for(
PCB_SHAPE* item : items_to_remove )
1864 std::vector<BOARD_ITEM*> items_to_select_on_success;
1867 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1872 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1878 items_to_select_on_success.push_back( &aItem );
1882 bool any_items_created = !lines_to_add.empty();
1883 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1885 any_items_created =
true;
1886 items_to_select_on_success.push_back( aItem.get() );
1887 commit.
Add( aItem.release() );
1890 bool any_items_removed = !items_to_remove.empty();
1891 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1894 any_items_removed =
true;
1895 items_to_deselect_on_success.push_back( &aItem );
1901 item_removal_handler );
1904 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1908 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1909 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1911 if( filletRadiusIU.has_value() )
1913 pairwise_line_routine =
1914 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1921 if( dogboneParams.has_value() )
1923 pairwise_line_routine =
1924 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
1931 if( chamfer_params.has_value() )
1933 pairwise_line_routine =
1934 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
1939 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
1942 if( !pairwise_line_routine )
1953 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1955 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1956 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1958 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1963 for(
BOARD_ITEM* item : items_to_select_on_success )
1964 m_selectionTool->AddItemToSel( item,
true );
1967 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1968 m_selectionTool->RemoveItemFromSel( item,
true );
1970 if( any_items_removed )
1973 if( any_items_created )
1979 commit.Push( pairwise_line_routine->GetCommitDescription() );
1981 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
1982 frame()->ShowInfoBarMsg( *msg );
1993 std::vector<VECTOR2I> pts;
1996 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2000 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2001 aCollector.
Remove( item );
2005 if( zone->IsTeardropArea() )
2006 aCollector.
Remove( item );
2014 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2023 if( s_toleranceValue <= 0 )
2028 std::vector<PCB_SHAPE*> shapeList;
2032 commit.Modify( item );
2046 zone->HatchBorder();
2050 commit.
Push(
_(
"Simplify Polygons" ) );
2064 std::vector<VECTOR2I> pts;
2067 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2074 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2076 aCollector.
Remove( item );
2084 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2093 if( s_toleranceValue <= 0 )
2098 std::vector<PCB_SHAPE*> shapeList;
2104 shapeList.push_back( shape );
2105 commit.Modify( shape );
2111 commit.Push(
_(
"Heal Shapes" ) );
2126 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2130 static const std::vector<KICAD_T> polygonBooleanTypes = {
2136 if( !item->
IsType( polygonBooleanTypes ) )
2137 aCollector.
Remove( item );
2146 std::vector<PCB_SHAPE*> items_to_process;
2150 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2155 if( item == last_item )
2156 std::swap( items_to_process.back(), items_to_process.front() );
2162 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2164 commit.Modify( &aItem );
2167 std::vector<BOARD_ITEM*> items_to_select_on_success;
2169 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2171 items_to_select_on_success.push_back( aItem.get() );
2172 commit.Add( aItem.release() );
2175 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2177 commit.Remove( &aItem );
2182 item_removal_handler );
2185 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2187 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2194 wxCHECK(
model,
nullptr );
2198 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2202 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2206 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2211 const auto run_routine = [&]()
2214 for(
PCB_SHAPE* shape : items_to_process )
2215 boolean_routine->ProcessShape( *shape );
2217 boolean_routine->Finalize();
2220 boolean_routine = create_routine();
2222 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2229 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2233 items_to_select_on_success.clear();
2235 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2237 for(
PCB_SHAPE* shape : items_to_process )
2240 items_area[shape] = area;
2249 std::sort( items_to_process.begin(), items_to_process.end(),
2252 return items_area[a] > items_area[b];
2256 boolean_routine = create_routine();
2261 for(
BOARD_ITEM* item : items_to_select_on_success )
2267 commit.Push( boolean_routine->GetCommitDescription() );
2269 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2270 frame()->ShowInfoBarMsg( *msg );
2292 std::vector<PCB_TABLECELL*> cells;
2343 for(
EDA_ITEM* eda_item : selCopy )
2345 if( !eda_item->IsBOARD_ITEM() )
2385 if( editFrame && item )
2405 commit = &localCommit;
2426 std::optional<VECTOR2I> oldRefPt;
2431 oldRefPt =
selection.GetReferencePoint();
2455 bool usePcbShapeCenter =
false;
2462 usePcbShapeCenter =
true;
2466 usePcbShapeCenter =
true;
2472 else if( usePcbShapeCenter )
2484 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2485 rotateAngle = -rotateAngle;
2491 viewBBox.
Merge( item->ViewBBox() );
2500 typedef std::numeric_limits<int> coord_limits;
2505 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2506 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2514 if( item->IsBOARD_ITEM() )
2518 board_item->
Rotate( refPt, rotateAngle );
2522 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2529 localCommit.
Push(
_(
"Rotate" ) );
2546 selection.SetReferencePoint( *oldRefPt );
2564 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2597 commit = &localCommit;
2625 switch( item->Type() )
2628 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2632 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2637 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2649 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2655 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2659 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2668 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2679 localCommit.
Push(
_(
"Mirror" ) );
2708 commit = &localCommit;
2720 auto setJustify = [&](
EDA_TEXT* aTextItem )
2735 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2744 if( !localCommit.
Empty() )
2747 localCommit.
Push(
_(
"Left Justify" ) );
2749 localCommit.
Push(
_(
"Center Justify" ) );
2751 localCommit.
Push(
_(
"Right Justify" ) );
2781 commit = &localCommit;
2796 std::optional<VECTOR2I> oldRefPt;
2799 oldRefPt =
selection.GetReferencePoint();
2825 if( !item->IsBOARD_ITEM() )
2832 boardItem->
Flip( refPt, flipDirection );
2836 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2842 localCommit.
Push(
_(
"Change Side / Flip" ) );
2858 selection.SetReferencePoint( *oldRefPt );
2870 int commitFlags = 0;
2875 int itemsDeleted = 0;
2876 int fieldsHidden = 0;
2877 int fieldsAlreadyHidden = 0;
2881 if( !item->IsBOARD_ITEM() )
2887 switch( item->Type() )
2893 wxASSERT( parentFP );
2894 commit.
Modify( parentFP );
2903 fieldsAlreadyHidden++;
2906 getView()->Update( parentFP );
2923 commit.
Remove( board_item );
2929 commit.
Modify( board_item );
2930 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2942 commit.
Remove( board_item );
2949 commit.
Remove( board_item );
2959 if( !aIsCut && aItems.
GetSize() == 1 )
2962 ZONE* zone =
static_cast<ZONE*
>( board_item );
2964 int outlineIdx, holeIdx;
2985 commit.
Remove( board_item );
2996 commit.Push(
_(
"Delete" ), commitFlags );
3004 commit.
Remove( board_item );
3012 commit.
Remove( board_item );
3021 if( enteredGroup && enteredGroup->
GetItems().empty() )
3026 commit.
Push(
_(
"Cut" ), commitFlags );
3028 else if( itemsDeleted == 0 )
3030 if( fieldsHidden == 1 )
3031 commit.
Push(
_(
"Hide Field" ), commitFlags );
3032 else if( fieldsHidden > 1 )
3033 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3034 else if( fieldsAlreadyHidden > 0 )
3035 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3039 commit.
Push(
_(
"Delete" ), commitFlags );
3050 std::vector<BOARD_ITEM*> lockedItems;
3142 if( ret == wxID_OK )
3150 selCenter += translation;
3152 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3153 rotation = -rotation;
3157 if( !item->IsBOARD_ITEM() )
3165 boardItem->
Move( translation );
3167 switch( rotationAnchor )
3173 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3178 getView()->Update( boardItem );
3181 commit.
Push(
_(
"Move Exactly" ) );
3237 std::vector<BOARD_ITEM*> new_items;
3244 if( !item->IsBOARD_ITEM() )
3256 switch( orig_item->
Type() )
3276 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3278 dupe_item = orig_item->
Duplicate(
true, &commit );
3284 new_items.push_back( dupe_item );
3285 commit.
Add( dupe_item );
3295 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3297 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3303 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3310 new_items.push_back( dupe_item );
3311 commit.
Add( dupe_item );
3320 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3326 new_items.push_back( aItem );
3327 commit.
Add( aItem );
3332 new_items.push_back( dupe_item );
3333 commit.
Add( dupe_item );
3345 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3351 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3355 commit.
Push(
_(
"Duplicate" ) );
3373 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3375 switch( aCollector[i]->Type() )
3379 default: aCollector.
Remove( i );
break;
3402 commit = &localCommit;
3406 switch( item->Type() )
3416 if( !
pad.CanHaveNumber() )
3420 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3425 pad.SetNumber( *newNumber );
3434 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3439 text.SetText( *newText );
3451 commit->
Push(
_(
"Increment" ) );
3459 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3461 if( aCollector[i]->Type() !=
PCB_PAD_T )
3469 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3480 if( aSelection.
Empty() )
3504 BOX2I nonFieldsBBox;
3508 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3509 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3524 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3528 std::optional<VECTOR2I> pickedPoint;
3538 const auto setPickerLayerSet =
3545 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3553 setPickerLayerSet();
3556 [&](
const VECTOR2D& aPoint ) ->
bool
3558 pickedPoint = aPoint;
3560 if( !aSuccessMessage.empty() )
3582 if( !aCanceledMessage.empty() )
3594 [&](
const int& aFinalState )
3613 setPickerLayerSet();
3616 evt->SetPassEvent();
3627 canvas()->SetStatusPopup(
nullptr );
3631 aReferencePoint = *pickedPoint;
3633 return pickedPoint.has_value();
3641 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3644 frame()->PushTool( selectReferencePoint );
3659 std::vector<BOARD_ITEM*> items;
3663 if( item->IsBOARD_ITEM() )
3664 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3671 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3672 _(
"Copy canceled" ), refPoint ) )
3674 frame()->PopTool( selectReferencePoint );
3683 selection.SetReferencePoint( refPoint );
3687 frame()->SetStatusText(
_(
"Selection copied" ) );
3690 frame()->PopTool( selectReferencePoint );
3710 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3712 switch( aItem.Type() )
3724 return text.GetShownText(
true );
3738 for(
int row = 0; row <
table.GetRowCount(); ++row )
3740 for(
int col = 0; col <
table.GetColCount(); ++col )
3745 if( col <
table.GetColCount() - 1 )
3751 if( row <
table.GetRowCount() - 1 )
3762 return wxEmptyString;
3765 wxArrayString itemTexts;
3769 if( item->IsBOARD_ITEM() )
3772 wxString itemText = getItemText( *boardItem );
3774 itemText.Trim(
false ).Trim(
true );
3776 if( !itemText.IsEmpty() )
3778 itemTexts.Add( std::move( itemText ) );
3784 if( !itemTexts.empty() )
3786 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3811 board()->BuildConnectivity();
3813 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.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
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 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.
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, INFOBAR_MESSAGE_TYPE aType=INFOBAR_MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
void 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 pointEditorChamferCorner
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 pointEditorRemoveCorner
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 pointEditorAddCorner
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.
bool CanRemoveCorner(const SELECTION &aSelection)
Condition to display "Remove Corner" context menu entry.
static bool CanChamferCorner(const EDA_ITEM &aItem)
Check if a corner of the given item can be chamfered (zones, polys only).
static bool CanAddCorner(const EDA_ITEM &aItem)
Check if a corner can be added to the given item (zones, polys, segments, arcs).
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
#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::vector< EDA_ITEM * > EDA_ITEMS
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