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 )
198 auto canAddCornerCondition = [](
const SELECTION& aSelection )
200 const EDA_ITEM* item = aSelection.Front();
205 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
207 const EDA_ITEM* item = aSelection.Front();
212 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
278 for(
const EDA_ITEM* it : aSelection )
291 if( units.size() < 2 )
294 const wxString& padNum =
pad->GetNumber();
295 bool inAnyUnit =
false;
297 for(
const auto& u : units )
299 for(
const auto& pnum : u.m_pins )
317 else if( single != fp )
328 std::unordered_set<wxString> padNums;
330 for(
const EDA_ITEM* it : aSelection )
337 if(
pad->GetParentFootprint() != aFootprint )
340 padNums.insert(
pad->GetNumber() );
349 const std::unordered_set<wxString>& aSelPadNums )
351 std::vector<int> indices;
355 for(
size_t i = 0; i < units.size(); ++i )
359 for(
const auto& pn : units[i].m_pins )
361 if( aSelPadNums.count( pn ) )
369 indices.push_back(
static_cast<int>( i ) );
379 if( aUnitIndices.empty() )
383 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
385 for(
int idx : aUnitIndices )
387 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
398 std::vector<int> targets;
401 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
403 for(
size_t i = 0; i < units.size(); ++i )
405 if(
static_cast<int>( i ) == aSourceIdx )
408 if( units[i].m_pins.size() != pinCount )
411 targets.push_back(
static_cast<int>( i ) );
441 if( unitsHit.size() != 1 )
444 const int sourceIdx = unitsHit.front();
447 for(
int idx : targets )
450 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
458 int id = aEvent.GetId();
473 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
489 auto menu = std::make_shared<GATE_SWAP_MENU>();
490 menu->SetTool( aTool );
501 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
504 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
509 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
512 subMenu->Evaluate( aSel );
513 return subMenu->GetMenuItemCount() > 0;
516 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
519 subMenu->Evaluate( aSel );
520 return subMenu->GetMenuItemCount() > 0;
524 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
535 if( unitsHit.size() != 1 )
538 const int sourceIdx = unitsHit.front();
540 return !targets.empty();
544 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
555 if( unitsHit.size() < 2 )
561 auto propertiesCondition = [
this](
const SELECTION& aSel )
563 if( aSel.GetSize() == 0 )
577 if( aSel.GetSize() == 1 )
589 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
594 auto canMirror = [
this](
const SELECTION& aSelection )
607 auto singleFootprintCondition =
610 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
612 bool foundFirst =
false;
628 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
630 return frame()->ToolStackIsEmpty();
633 auto notMovingCondition = [](
const SELECTION& aSelection )
635 return aSelection.Empty() || !aSelection.Front()->IsMoving();
638 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
640 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
643 auto isSkippable = [
this](
const SELECTION& aSelection )
649 && notMovingCondition && !inFootprintEditor;
698 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
705 && !inFootprintEditor );
717 menu.AddSeparator( 100 );
718 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
719 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
721 menu.AddSeparator( 150 );
734 menu.AddSeparator( 150 );
750 wxString footprintName;
751 wxArrayString fplist;
756 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
766 footprintName.Trim(
true );
767 footprintName.Trim(
false );
769 if( !footprintName.IsEmpty() )
773 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
873 std::vector<PCB_TRACK*> tracks;
874 std::vector<PCB_TRACK*> vias;
875 std::vector<FOOTPRINT*> footprints;
878 const auto gatherItemsByType = [&]()
885 vias.push_back( track );
887 tracks.push_back( track );
902 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
908 else if( tracks.size() || vias.size() )
935 if( tracks.size() == 2 && vias.size() == 0 )
937 if( connected( tracks[0], tracks[1]->GetStart() )
938 || connected( tracks[0], tracks[1]->GetEnd() ) )
940 aCollector.
Remove( tracks[1] );
943 else if( tracks.size() == 2 && vias.size() == 1 )
945 if( connected( tracks[0], vias[0]->GetPosition() )
946 && connected( tracks[1], vias[0]->GetPosition() ) )
948 aCollector.
Remove( tracks[0] );
949 aCollector.
Remove( tracks[1] );
987 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
989 frame()->ShowInfoBarError( msg );
1002 bool restore_state =
false;
1016 tanStart.
A = *tanIntersect;
1018 tanEnd.
A = *tanIntersect;
1021 std::set<PCB_TRACK*> addedTracks;
1023 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1025 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1028 int allowedDeviation = theArc->
GetWidth();
1030 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1032 for(
int i = 0; i < 3; i++ )
1034 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1035 allowedDeviation /= 2;
1037 if( itemsOnAnchor.size() == 1 )
1043 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1045 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1051 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1059 track->
SetEnd( aAnchor );
1068 addedTracks.insert( track );
1074 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1075 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1080 tanStart.
B = trackOnStart->
GetEnd();
1086 tanEnd.
B = trackOnEnd->
GetEnd();
1090 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1093 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1095 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1096 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1098 return trackStartToArcStart < trackEndToArcStart;
1101 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1102 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1133 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1144 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1145 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1146 VECTOR2I tempTangentPoint = tanEndPoint;
1148 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1149 tempTangentPoint = tanStartPoint;
1155 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1156 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1157 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1159 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1160 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1161 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1163 bool eatFirstMouseUp =
true;
1174 std::vector<VECTOR2I> possiblePoints;
1181 for(
const VECTOR2I& candidate : possiblePoints )
1183 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1185 closest = candidate;
1209 theArc->
SetEnd( newEnd );
1210 theArc->
SetMid( newMid );
1212 if( isStartTrackOnStartPt )
1213 trackOnStart->
SetStart( newStart );
1215 trackOnStart->
SetEnd( newStart );
1217 if( isEndTrackOnStartPt )
1220 trackOnEnd->
SetEnd( newEnd );
1223 getView()->Update( trackOnStart );
1224 getView()->Update( trackOnEnd );
1228 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1230 eatFirstMouseUp =
false;
1232 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1234 restore_state =
true;
1239 restore_state =
true;
1247 eatFirstMouseUp =
false;
1259 if( isStartTrackOnStartPt )
1260 newStart = trackOnStart->
GetEnd();
1262 if( isEndTrackOnStartPt )
1263 newEnd = trackOnEnd->
GetEnd();
1267 if( trackOnStart->
GetLength() <= maxLengthIU )
1269 if( addedTracks.count( trackOnStart ) )
1271 getView()->Remove( trackOnStart );
1272 addedTracks.erase( trackOnStart );
1273 delete trackOnStart;
1277 commit.
Remove( trackOnStart );
1283 if( trackOnEnd->
GetLength() <= maxLengthIU )
1285 if( addedTracks.count( trackOnEnd ) )
1287 getView()->Remove( trackOnEnd );
1288 addedTracks.erase( trackOnEnd );
1293 commit.
Remove( trackOnEnd );
1296 theArc->
SetEnd( newEnd );
1305 commit.
Add( added );
1312 commit.
Push(
_(
"Drag Arc Track" ) );
1324 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1329 aCollector.
Remove( item );
1357 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1358 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1361 via->SetDrill( new_drill );
1369 wxCHECK( track, 0 );
1373 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1378 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1403 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1408 aCollector.
Remove( item );
1423 if( newLayer == origLayer )
1434 wxCHECK( track, 0 );
1442 commit.
Push(
_(
"Edit Track Layer" ) );
1459 static int filletRadius = 0;
1465 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1470 aCollector.
Remove( item );
1478 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1494 bool t1Start =
true;
1495 bool t2Start =
true;
1498 std::vector<FILLET_OP> filletOperations;
1499 bool operationPerformedOnAtLeastOne =
false;
1500 bool didOneAttemptFail =
false;
1501 std::set<PCB_TRACK*> processedTracks;
1503 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1505 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1507 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1511 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1517 if( processedTracks.find( trackOther ) == processedTracks.end() )
1519 if( itemsOnAnchor.size() == 1 )
1522 filletOp.t1 = aTrack;
1523 filletOp.t2 = trackOther;
1524 filletOp.t1Start = aStartPoint;
1525 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1526 filletOperations.push_back( filletOp );
1532 didOneAttemptFail =
true;
1546 processFilletOp( track,
true );
1547 processFilletOp( track,
false );
1549 processedTracks.insert( track );
1555 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1557 for( FILLET_OP filletOp : filletOperations )
1565 if( trackOnStart && trackOnEnd )
1568 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1576 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1579 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1581 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1586 aPointToSet.
x = aVecToTest.x;
1587 aPointToSet.
y = aVecToTest.y;
1595 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1596 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1598 didOneAttemptFail =
true;
1602 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1603 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1605 didOneAttemptFail =
true;
1617 itemsToAddToSelection.push_back( tArc );
1622 if( filletOp.t1Start )
1625 track1->
SetEnd( t1newPoint );
1627 if( filletOp.t2Start )
1630 track2->
SetEnd( t2newPoint );
1632 operationPerformedOnAtLeastOne =
true;
1636 commit.
Push(
_(
"Fillet Tracks" ) );
1639 for(
BOARD_ITEM* item : itemsToAddToSelection )
1642 if( !operationPerformedOnAtLeastOne )
1643 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1644 else if( didOneAttemptFail )
1645 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1665 return std::nullopt;
1669 return aPersitentRadius;
1681 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1688 _(
"Add slots in acute corners" ),
1690 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1697 return std::nullopt;
1699 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1700 wxCHECK( results.size() == 2, std::nullopt );
1704 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1705 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1707 catch(
const std::bad_variant_access& )
1710 return std::nullopt;
1713 return s_dogBoneParams;
1727 const int default_setback =
pcbIUScale.mmToIU( 1 );
1729 static CHAMFER_PARAMS params{ default_setback, default_setback };
1731 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1734 return std::nullopt;
1736 params.m_chamfer_setback_a = dlg.
GetValue();
1739 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1750 std::vector<VECTOR2I> pts;
1753 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1760 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1762 aCollector.
Remove( item );
1769 std::set<PCB_SHAPE*> lines_to_add;
1770 std::vector<PCB_SHAPE*> items_to_remove;
1774 std::vector<VECTOR2I> pts;
1781 items_to_remove.push_back( graphic );
1784 pts.emplace_back( start );
1786 pts.emplace_back(
end );
1792 items_to_remove.push_back( graphic );
1794 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1798 for(
size_t jj = 1; jj < pts.size(); ++jj )
1806 lines_to_add.insert( line );
1809 if( pts.size() > 1 )
1814 line->
SetEnd( pts.front() );
1817 lines_to_add.insert( line );
1825 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1832 else if( segmentCount < 2 )
1834 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1852 for(
PCB_SHAPE* item : items_to_remove )
1863 std::vector<BOARD_ITEM*> items_to_select_on_success;
1866 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1871 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1877 items_to_select_on_success.push_back( &aItem );
1881 bool any_items_created = !lines_to_add.empty();
1882 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1884 any_items_created =
true;
1885 items_to_select_on_success.push_back( aItem.get() );
1886 commit.
Add( aItem.release() );
1889 bool any_items_removed = !items_to_remove.empty();
1890 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1893 any_items_removed =
true;
1894 items_to_deselect_on_success.push_back( &aItem );
1900 item_removal_handler );
1903 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1907 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1908 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1910 if( filletRadiusIU.has_value() )
1912 pairwise_line_routine =
1913 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1920 if( dogboneParams.has_value() )
1922 pairwise_line_routine =
1923 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
1930 if( chamfer_params.has_value() )
1932 pairwise_line_routine =
1933 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
1938 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
1941 if( !pairwise_line_routine )
1952 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1954 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1955 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1957 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1962 for(
BOARD_ITEM* item : items_to_select_on_success )
1963 m_selectionTool->AddItemToSel( item,
true );
1966 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1967 m_selectionTool->RemoveItemFromSel( item,
true );
1969 if( any_items_removed )
1972 if( any_items_created )
1978 commit.Push( pairwise_line_routine->GetCommitDescription() );
1980 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
1981 frame()->ShowInfoBarMsg( *msg );
1992 std::vector<VECTOR2I> pts;
1995 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1999 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2000 aCollector.
Remove( item );
2004 if( zone->IsTeardropArea() )
2005 aCollector.
Remove( item );
2013 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2022 if( s_toleranceValue <= 0 )
2027 std::vector<PCB_SHAPE*> shapeList;
2031 commit.Modify( item );
2048 commit.
Push(
_(
"Simplify Polygons" ) );
2062 std::vector<VECTOR2I> pts;
2065 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2072 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2074 aCollector.
Remove( item );
2082 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2091 if( s_toleranceValue <= 0 )
2096 std::vector<PCB_SHAPE*> shapeList;
2102 shapeList.push_back( shape );
2103 commit.Modify( shape );
2109 commit.Push(
_(
"Heal Shapes" ) );
2124 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2128 static const std::vector<KICAD_T> polygonBooleanTypes = {
2134 if( !item->
IsType( polygonBooleanTypes ) )
2135 aCollector.
Remove( item );
2144 std::vector<PCB_SHAPE*> items_to_process;
2148 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2153 if( item == last_item )
2154 std::swap( items_to_process.back(), items_to_process.front() );
2160 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2162 commit.Modify( &aItem );
2165 std::vector<BOARD_ITEM*> items_to_select_on_success;
2167 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2169 items_to_select_on_success.push_back( aItem.get() );
2170 commit.Add( aItem.release() );
2173 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2175 commit.Remove( &aItem );
2180 item_removal_handler );
2183 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2185 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2192 wxCHECK(
model,
nullptr );
2196 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2200 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2204 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2209 const auto run_routine = [&]()
2212 for(
PCB_SHAPE* shape : items_to_process )
2213 boolean_routine->ProcessShape( *shape );
2215 boolean_routine->Finalize();
2218 boolean_routine = create_routine();
2220 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2227 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2231 items_to_select_on_success.clear();
2233 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2235 for(
PCB_SHAPE* shape : items_to_process )
2238 items_area[shape] = area;
2247 std::sort( items_to_process.begin(), items_to_process.end(),
2250 return items_area[a] > items_area[b];
2254 boolean_routine = create_routine();
2259 for(
BOARD_ITEM* item : items_to_select_on_success )
2265 commit.Push( boolean_routine->GetCommitDescription() );
2267 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2268 frame()->ShowInfoBarMsg( *msg );
2290 std::vector<PCB_TABLECELL*> cells;
2341 for(
EDA_ITEM* eda_item : selCopy )
2343 if( !eda_item->IsBOARD_ITEM() )
2383 if( editFrame && item )
2403 commit = &localCommit;
2424 std::optional<VECTOR2I> oldRefPt;
2429 oldRefPt =
selection.GetReferencePoint();
2453 bool usePcbShapeCenter =
false;
2460 usePcbShapeCenter =
true;
2464 usePcbShapeCenter =
true;
2470 else if( usePcbShapeCenter )
2482 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2483 rotateAngle = -rotateAngle;
2489 viewBBox.
Merge( item->ViewBBox() );
2498 typedef std::numeric_limits<int> coord_limits;
2503 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2504 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2512 if( item->IsBOARD_ITEM() )
2516 board_item->
Rotate( refPt, rotateAngle );
2520 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2524 if( !localCommit.
Empty() )
2525 localCommit.
Push(
_(
"Rotate" ) );
2542 selection.SetReferencePoint( *oldRefPt );
2560 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2593 commit = &localCommit;
2621 switch( item->Type() )
2624 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2628 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2633 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2645 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2651 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2655 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2664 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2672 if( !localCommit.
Empty() )
2673 localCommit.
Push(
_(
"Mirror" ) );
2702 commit = &localCommit;
2714 auto setJustify = [&](
EDA_TEXT* aTextItem )
2729 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2738 if( !localCommit.
Empty() )
2741 localCommit.
Push(
_(
"Left Justify" ) );
2743 localCommit.
Push(
_(
"Center Justify" ) );
2745 localCommit.
Push(
_(
"Right Justify" ) );
2775 commit = &localCommit;
2790 std::optional<VECTOR2I> oldRefPt;
2793 oldRefPt =
selection.GetReferencePoint();
2819 if( !item->IsBOARD_ITEM() )
2826 boardItem->
Flip( refPt, flipDirection );
2830 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2833 if( !localCommit.
Empty() )
2834 localCommit.
Push(
_(
"Change Side / Flip" ) );
2850 selection.SetReferencePoint( *oldRefPt );
2862 int commitFlags = 0;
2867 int itemsDeleted = 0;
2868 int fieldsHidden = 0;
2869 int fieldsAlreadyHidden = 0;
2873 if( !item->IsBOARD_ITEM() )
2879 switch( item->Type() )
2885 wxASSERT( parentFP );
2886 commit.
Modify( parentFP );
2895 fieldsAlreadyHidden++;
2898 getView()->Update( parentFP );
2915 commit.
Remove( board_item );
2921 commit.
Modify( board_item );
2922 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2934 commit.
Remove( board_item );
2941 commit.
Remove( board_item );
2951 if( !aIsCut && aItems.
GetSize() == 1 )
2954 ZONE* zone =
static_cast<ZONE*
>( board_item );
2956 int outlineIdx, holeIdx;
2977 commit.
Remove( board_item );
2988 commit.Push(
_(
"Delete" ), commitFlags );
2996 commit.
Remove( board_item );
3004 commit.
Remove( board_item );
3013 if( enteredGroup && enteredGroup->
GetItems().empty() )
3018 commit.
Push(
_(
"Cut" ), commitFlags );
3020 else if( itemsDeleted == 0 )
3022 if( fieldsHidden == 1 )
3023 commit.
Push(
_(
"Hide Field" ), commitFlags );
3024 else if( fieldsHidden > 1 )
3025 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3026 else if( fieldsAlreadyHidden > 0 )
3027 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3031 commit.
Push(
_(
"Delete" ), commitFlags );
3042 std::vector<BOARD_ITEM*> lockedItems;
3132 if( ret == wxID_OK )
3140 selCenter += translation;
3142 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3143 rotation = -rotation;
3147 if( !item->IsBOARD_ITEM() )
3155 boardItem->
Move( translation );
3157 switch( rotationAnchor )
3163 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3168 getView()->Update( boardItem );
3171 commit.
Push(
_(
"Move Exactly" ) );
3227 std::vector<BOARD_ITEM*> new_items;
3234 if( !item->IsBOARD_ITEM() )
3246 switch( orig_item->
Type() )
3266 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3268 dupe_item = orig_item->
Duplicate(
true, &commit );
3274 new_items.push_back( dupe_item );
3275 commit.
Add( dupe_item );
3285 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3287 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3293 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3300 new_items.push_back( dupe_item );
3301 commit.
Add( dupe_item );
3310 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3316 new_items.push_back( aItem );
3317 commit.
Add( aItem );
3322 new_items.push_back( dupe_item );
3323 commit.
Add( dupe_item );
3335 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3341 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3345 commit.
Push(
_(
"Duplicate" ) );
3363 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3365 switch( aCollector[i]->Type() )
3369 default: aCollector.
Remove( i );
break;
3392 commit = &localCommit;
3396 switch( item->Type() )
3406 if( !
pad.CanHaveNumber() )
3410 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3415 pad.SetNumber( *newNumber );
3424 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3429 text.SetText( *newText );
3441 commit->
Push(
_(
"Increment" ) );
3449 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3451 if( aCollector[i]->Type() !=
PCB_PAD_T )
3459 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3470 if( aSelection.
Empty() )
3494 BOX2I nonFieldsBBox;
3498 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3499 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3514 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3518 std::optional<VECTOR2I> pickedPoint;
3528 const auto setPickerLayerSet =
3535 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3543 setPickerLayerSet();
3546 [&](
const VECTOR2D& aPoint ) ->
bool
3548 pickedPoint = aPoint;
3550 if( !aSuccessMessage.empty() )
3572 if( !aCanceledMessage.empty() )
3584 [&](
const int& aFinalState )
3603 setPickerLayerSet();
3606 evt->SetPassEvent();
3617 canvas()->SetStatusPopup(
nullptr );
3621 aReferencePoint = *pickedPoint;
3623 return pickedPoint.has_value();
3631 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3634 frame()->PushTool( selectReferencePoint );
3649 std::vector<BOARD_ITEM*> items;
3653 if( item->IsBOARD_ITEM() )
3654 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3661 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3662 _(
"Copy canceled" ), refPoint ) )
3664 frame()->PopTool( selectReferencePoint );
3673 selection.SetReferencePoint( refPoint );
3677 frame()->SetStatusText(
_(
"Selection copied" ) );
3680 frame()->PopTool( selectReferencePoint );
3700 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3702 switch( aItem.Type() )
3714 return text.GetShownText(
true );
3728 for(
int row = 0; row <
table.GetRowCount(); ++row )
3730 for(
int col = 0; col <
table.GetColCount(); ++col )
3735 if( col <
table.GetColCount() - 1 )
3741 if( row <
table.GetRowCount() - 1 )
3752 return wxEmptyString;
3755 wxArrayString itemTexts;
3759 if( item->IsBOARD_ITEM() )
3762 wxString itemText = getItemText( *boardItem );
3764 itemText.Trim(
false ).Trim(
true );
3766 if( !itemText.IsEmpty() )
3768 itemTexts.Add( std::move( itemText ) );
3774 if( !itemTexts.empty() )
3776 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3801 board()->BuildConnectivity();
3803 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, 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 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
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