69using namespace std::placeholders;
71#include <wx/hyperlink.h>
76#include <dialogs/dialog_tablecell_properties.h>
77#include <dialogs/dialog_table_properties.h>
97 ZONE* zone =
static_cast<ZONE*
>( aItem );
110 if( aSelection.
GetSize() != 1 )
152 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
155 menu->SetUntranslatedTitle(
_HKI(
"Mirror / Rotate" ) );
157 auto canMirror = [](
const SELECTION& aSelection )
181 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
184 menu->SetUntranslatedTitle(
_HKI(
"Routing" ) );
186 auto notMovingCondition = [](
const SELECTION& aSelection )
188 return aSelection.Empty() || !aSelection.Front()->IsMoving();
206 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
209 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
211 auto notMovingCondition = [](
const SELECTION& aSelection )
213 return aSelection.Empty() || !aSelection.Front()->IsMoving();
227 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
229 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
244 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
251 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
258 auto canAddCornerCondition = [](
const SELECTION& aSelection )
260 const EDA_ITEM* item = aSelection.Front();
265 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
267 const EDA_ITEM* item = aSelection.Front();
272 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
338 for(
const EDA_ITEM* it : aSelection )
351 if( units.size() < 2 )
354 const wxString& padNum =
pad->GetNumber();
355 bool inAnyUnit =
false;
357 for(
const auto& u : units )
359 for(
const auto& pnum : u.m_pins )
377 else if( single != fp )
388 std::unordered_set<wxString> padNums;
390 for(
const EDA_ITEM* it : aSelection )
397 if(
pad->GetParentFootprint() != aFootprint )
400 padNums.insert(
pad->GetNumber() );
409 const std::unordered_set<wxString>& aSelPadNums )
411 std::vector<int> indices;
415 for(
size_t i = 0; i < units.size(); ++i )
419 for(
const auto& pn : units[i].m_pins )
421 if( aSelPadNums.count( pn ) )
429 indices.push_back(
static_cast<int>( i ) );
439 if( aUnitIndices.empty() )
443 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
445 for(
int idx : aUnitIndices )
447 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
458 std::vector<int> targets;
461 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
463 for(
size_t i = 0; i < units.size(); ++i )
465 if(
static_cast<int>( i ) == aSourceIdx )
468 if( units[i].m_pins.size() != pinCount )
471 targets.push_back(
static_cast<int>( i ) );
501 if( unitsHit.size() != 1 )
504 const int sourceIdx = unitsHit.front();
507 for(
int idx : targets )
510 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
518 int id = aEvent.GetId();
533 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
549 auto menu = std::make_shared<GATE_SWAP_MENU>();
550 menu->SetTool( aTool );
564 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
570 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
575 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
578 subMenu->Evaluate( aSel );
579 return subMenu->GetMenuItemCount() > 0;
582 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
585 subMenu->Evaluate( aSel );
586 return subMenu->GetMenuItemCount() > 0;
590 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
601 if( unitsHit.size() != 1 )
604 const int sourceIdx = unitsHit.front();
606 return !targets.empty();
610 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
621 if( unitsHit.size() < 2 )
627 auto propertiesCondition = [
this](
const SELECTION& aSel )
629 if( aSel.GetSize() == 0 )
643 if( aSel.GetSize() == 1 )
655 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
660 auto canMirror = [
this](
const SELECTION& aSelection )
673 auto singleFootprintCondition =
676 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
678 bool foundFirst =
false;
694 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
696 return frame()->ToolStackIsEmpty();
699 auto notMovingCondition = [](
const SELECTION& aSelection )
701 return aSelection.Empty() || !aSelection.Front()->IsMoving();
704 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
706 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
709 auto isSkippable = [
this](
const SELECTION& aSelection )
715 && notMovingCondition && !inFootprintEditor;
753 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
768 && !inFootprintEditor );
780 menu.AddSeparator( 100 );
781 menu.AddMenu( routingSubMenu.get(), isRoutable, 100 );
782 menu.AddMenu( mirrorRotateSubMenu.get(), canMirror, 100 );
783 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
784 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
786 menu.AddSeparator( 150 );
799 menu.AddSeparator( 2000 );
814 wxString footprintName;
815 wxArrayString fplist;
820 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
830 footprintName.Trim(
true );
831 footprintName.Trim(
false );
833 if( !footprintName.IsEmpty() )
837 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
937 std::vector<PCB_TRACK*> tracks;
938 std::vector<PCB_TRACK*> vias;
939 std::vector<FOOTPRINT*> footprints;
942 const auto gatherItemsByType = [&]()
949 vias.push_back( track );
951 tracks.push_back( track );
966 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
972 else if( tracks.size() || vias.size() )
999 if( tracks.size() == 2 && vias.size() == 0 )
1001 if( connected( tracks[0], tracks[1]->GetStart() )
1002 || connected( tracks[0], tracks[1]->GetEnd() ) )
1004 aCollector.
Remove( tracks[1] );
1007 else if( tracks.size() == 2 && vias.size() == 1 )
1009 if( connected( tracks[0], vias[0]->GetPosition() )
1010 && connected( tracks[1], vias[0]->GetPosition() ) )
1012 aCollector.
Remove( tracks[0] );
1013 aCollector.
Remove( tracks[1] );
1053 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
1055 frame()->ShowInfoBarError( msg );
1068 bool restore_state =
false;
1082 tanStart.
A = *tanIntersect;
1084 tanEnd.
A = *tanIntersect;
1087 std::set<PCB_TRACK*> addedTracks;
1089 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1091 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1094 int allowedDeviation = theArc->
GetWidth();
1096 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1098 for(
int i = 0; i < 3; i++ )
1100 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1101 allowedDeviation /= 2;
1103 if( itemsOnAnchor.size() == 1 )
1109 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1111 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1117 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1125 track->
SetEnd( aAnchor );
1134 addedTracks.insert( track );
1140 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1141 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1146 tanStart.
B = trackOnStart->
GetEnd();
1152 tanEnd.
B = trackOnEnd->
GetEnd();
1156 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1159 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1161 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1162 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1164 return trackStartToArcStart < trackEndToArcStart;
1167 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1168 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1199 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1210 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1211 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1212 VECTOR2I tempTangentPoint = tanEndPoint;
1214 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1215 tempTangentPoint = tanStartPoint;
1221 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1222 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1223 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1225 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1226 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1227 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1229 bool eatFirstMouseUp =
true;
1240 std::vector<VECTOR2I> possiblePoints;
1247 for(
const VECTOR2I& candidate : possiblePoints )
1249 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1251 closest = candidate;
1275 theArc->
SetEnd( newEnd );
1276 theArc->
SetMid( newMid );
1278 if( isStartTrackOnStartPt )
1279 trackOnStart->
SetStart( newStart );
1281 trackOnStart->
SetEnd( newStart );
1283 if( isEndTrackOnStartPt )
1286 trackOnEnd->
SetEnd( newEnd );
1289 getView()->Update( trackOnStart );
1290 getView()->Update( trackOnEnd );
1294 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1296 eatFirstMouseUp =
false;
1298 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1300 restore_state =
true;
1305 restore_state =
true;
1313 eatFirstMouseUp =
false;
1325 if( isStartTrackOnStartPt )
1326 newStart = trackOnStart->
GetEnd();
1328 if( isEndTrackOnStartPt )
1329 newEnd = trackOnEnd->
GetEnd();
1333 if( trackOnStart->
GetLength() <= maxLengthIU )
1335 if( addedTracks.count( trackOnStart ) )
1337 getView()->Remove( trackOnStart );
1338 addedTracks.erase( trackOnStart );
1339 delete trackOnStart;
1343 commit.
Remove( trackOnStart );
1349 if( trackOnEnd->
GetLength() <= maxLengthIU )
1351 if( addedTracks.count( trackOnEnd ) )
1353 getView()->Remove( trackOnEnd );
1354 addedTracks.erase( trackOnEnd );
1359 commit.
Remove( trackOnEnd );
1362 theArc->
SetEnd( newEnd );
1371 commit.
Add( added );
1378 commit.
Push(
_(
"Drag Arc Track" ) );
1390 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1395 aCollector.
Remove( item );
1425 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1426 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1429 via->SetDrill( new_drill );
1437 wxCHECK( track, 0 );
1441 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1446 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1471 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1476 aCollector.
Remove( item );
1493 if( newLayer == origLayer )
1504 wxCHECK( track, 0 );
1512 commit.
Push(
_(
"Edit Track Layer" ) );
1529 static int filletRadius = 0;
1535 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1540 aCollector.
Remove( item );
1550 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1566 bool t1Start =
true;
1567 bool t2Start =
true;
1570 std::vector<FILLET_OP> filletOperations;
1571 bool operationPerformedOnAtLeastOne =
false;
1572 bool didOneAttemptFail =
false;
1573 std::set<PCB_TRACK*> processedTracks;
1575 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1577 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1579 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1583 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1589 if( processedTracks.find( trackOther ) == processedTracks.end() )
1591 if( itemsOnAnchor.size() == 1 )
1594 filletOp.t1 = aTrack;
1595 filletOp.t2 = trackOther;
1596 filletOp.t1Start = aStartPoint;
1597 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1598 filletOperations.push_back( filletOp );
1604 didOneAttemptFail =
true;
1618 processFilletOp( track,
true );
1619 processFilletOp( track,
false );
1621 processedTracks.insert( track );
1627 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1629 for( FILLET_OP filletOp : filletOperations )
1637 if( trackOnStart && trackOnEnd )
1640 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1648 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1651 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1653 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1658 aPointToSet.
x = aVecToTest.x;
1659 aPointToSet.
y = aVecToTest.y;
1667 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1668 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1670 didOneAttemptFail =
true;
1674 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1675 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1677 didOneAttemptFail =
true;
1689 itemsToAddToSelection.push_back( tArc );
1694 if( filletOp.t1Start )
1697 track1->
SetEnd( t1newPoint );
1699 if( filletOp.t2Start )
1702 track2->
SetEnd( t2newPoint );
1704 operationPerformedOnAtLeastOne =
true;
1708 commit.
Push(
_(
"Fillet Tracks" ) );
1711 for(
BOARD_ITEM* item : itemsToAddToSelection )
1714 if( !operationPerformedOnAtLeastOne )
1715 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1716 else if( didOneAttemptFail )
1717 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1737 return std::nullopt;
1741 return aPersitentRadius;
1753 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1760 _(
"Add slots in acute corners" ),
1762 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1769 return std::nullopt;
1771 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1772 wxCHECK( results.size() == 2, std::nullopt );
1776 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1777 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1779 catch(
const std::bad_variant_access& )
1782 return std::nullopt;
1785 return s_dogBoneParams;
1799 const int default_setback =
pcbIUScale.mmToIU( 1 );
1801 static CHAMFER_PARAMS params{ default_setback, default_setback };
1803 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1806 return std::nullopt;
1808 params.m_chamfer_setback_a = dlg.
GetValue();
1811 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1822 std::vector<VECTOR2I> pts;
1825 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1832 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1834 aCollector.
Remove( item );
1843 std::set<PCB_SHAPE*> lines_to_add;
1844 std::vector<PCB_SHAPE*> items_to_remove;
1848 std::vector<VECTOR2I> pts;
1855 items_to_remove.push_back( graphic );
1858 pts.emplace_back( start );
1860 pts.emplace_back(
end );
1866 items_to_remove.push_back( graphic );
1868 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1872 for(
size_t jj = 1; jj < pts.size(); ++jj )
1880 lines_to_add.insert( line );
1883 if( pts.size() > 1 )
1888 line->
SetEnd( pts.front() );
1891 lines_to_add.insert( line );
1899 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1906 else if( segmentCount < 2 )
1908 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1926 for(
PCB_SHAPE* item : items_to_remove )
1937 std::vector<BOARD_ITEM*> items_to_select_on_success;
1940 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1945 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1951 items_to_select_on_success.push_back( &aItem );
1955 bool any_items_created = !lines_to_add.empty();
1956 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1958 any_items_created =
true;
1959 items_to_select_on_success.push_back( aItem.get() );
1960 commit.
Add( aItem.release() );
1963 bool any_items_removed = !items_to_remove.empty();
1964 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1967 any_items_removed =
true;
1968 items_to_deselect_on_success.push_back( &aItem );
1974 item_removal_handler );
1977 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1981 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1982 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1984 if( filletRadiusIU.has_value() )
1986 pairwise_line_routine =
1987 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1994 if( dogboneParams.has_value() )
1996 pairwise_line_routine =
1997 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
2004 if( chamfer_params.has_value() )
2006 pairwise_line_routine =
2007 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
2012 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
2015 if( !pairwise_line_routine )
2026 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
2028 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
2029 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
2031 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
2036 for(
BOARD_ITEM* item : items_to_select_on_success )
2037 m_selectionTool->AddItemToSel( item,
true );
2040 for(
BOARD_ITEM* item : items_to_deselect_on_success )
2041 m_selectionTool->RemoveItemFromSel( item,
true );
2043 if( any_items_removed )
2046 if( any_items_created )
2052 commit.Push( pairwise_line_routine->GetCommitDescription() );
2054 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
2055 frame()->ShowInfoBarMsg( *msg );
2066 std::vector<VECTOR2I> pts;
2069 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2073 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2074 aCollector.
Remove( item );
2078 if( zone->IsTeardropArea() )
2079 aCollector.
Remove( item );
2089 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2098 if( s_toleranceValue <= 0 )
2103 std::vector<PCB_SHAPE*> shapeList;
2107 commit.Modify( item );
2121 zone->HatchBorder();
2125 commit.
Push(
_(
"Simplify Polygons" ) );
2139 std::vector<VECTOR2I> pts;
2142 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2149 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2151 aCollector.
Remove( item );
2161 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2170 if( s_toleranceValue <= 0 )
2175 std::vector<PCB_SHAPE*> shapeList;
2181 shapeList.push_back( shape );
2182 commit.Modify( shape );
2188 commit.Push(
_(
"Heal Shapes" ) );
2203 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2207 static const std::vector<KICAD_T> polygonBooleanTypes = {
2213 if( !item->
IsType( polygonBooleanTypes ) )
2214 aCollector.
Remove( item );
2225 std::vector<PCB_SHAPE*> items_to_process;
2229 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2234 if( item == last_item )
2235 std::swap( items_to_process.back(), items_to_process.front() );
2241 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2243 commit.Modify( &aItem );
2246 std::vector<BOARD_ITEM*> items_to_select_on_success;
2248 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2250 items_to_select_on_success.push_back( aItem.get() );
2251 commit.Add( aItem.release() );
2254 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2256 commit.Remove( &aItem );
2261 item_removal_handler );
2264 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2266 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2273 wxCHECK(
model,
nullptr );
2277 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2281 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2285 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2290 const auto run_routine = [&]()
2293 for(
PCB_SHAPE* shape : items_to_process )
2294 boolean_routine->ProcessShape( *shape );
2296 boolean_routine->Finalize();
2299 boolean_routine = create_routine();
2301 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2308 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2312 items_to_select_on_success.clear();
2314 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2316 for(
PCB_SHAPE* shape : items_to_process )
2319 items_area[shape] = area;
2328 std::sort( items_to_process.begin(), items_to_process.end(),
2331 return items_area[a] > items_area[b];
2335 boolean_routine = create_routine();
2340 for(
BOARD_ITEM* item : items_to_select_on_success )
2346 commit.Push( boolean_routine->GetCommitDescription() );
2348 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2349 frame()->ShowInfoBarMsg( *msg );
2371 std::vector<PCB_TABLECELL*> cells;
2422 for(
EDA_ITEM* eda_item : selCopy )
2424 if( !eda_item->IsBOARD_ITEM() )
2466 if( editFrame && item )
2486 commit = &localCommit;
2509 std::optional<VECTOR2I> oldRefPt;
2514 oldRefPt =
selection.GetReferencePoint();
2540 bool usePcbShapeCenter =
false;
2547 usePcbShapeCenter =
true;
2551 usePcbShapeCenter =
true;
2557 else if( usePcbShapeCenter )
2569 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2570 rotateAngle = -rotateAngle;
2576 viewBBox.
Merge( item->ViewBBox() );
2585 typedef std::numeric_limits<int> coord_limits;
2590 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2591 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2599 if( item->IsBOARD_ITEM() )
2603 board_item->
Rotate( refPt, rotateAngle );
2607 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2614 localCommit.
Push(
_(
"Rotate" ) );
2631 selection.SetReferencePoint( *oldRefPt );
2649 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2682 commit = &localCommit;
2704 int skippedFootprints = 0;
2711 skippedFootprints++;
2719 switch( item->Type() )
2722 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2726 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2731 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2741 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2747 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2751 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2760 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2771 localCommit.
Push(
_(
"Mirror" ) );
2775 frame()->ShowInfoBarMsg(
_(
"Footprints cannot be mirrored. Use Flip to move them to "
2776 "the other side of the board." ) );
2806 commit = &localCommit;
2820 auto setJustify = [&](
EDA_TEXT* aTextItem )
2835 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2844 if( !localCommit.
Empty() )
2847 localCommit.
Push(
_(
"Left Justify" ) );
2849 localCommit.
Push(
_(
"Center Justify" ) );
2851 localCommit.
Push(
_(
"Right Justify" ) );
2881 commit = &localCommit;
2898 std::optional<VECTOR2I> oldRefPt;
2901 oldRefPt =
selection.GetReferencePoint();
2931 if( !item->IsBOARD_ITEM() )
2938 boardItem->
Flip( refPt, flipDirection );
2942 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2948 localCommit.
Push(
_(
"Change Side / Flip" ) );
2964 selection.SetReferencePoint( *oldRefPt );
2976 int commitFlags = 0;
2981 int itemsDeleted = 0;
2982 int fieldsHidden = 0;
2983 int fieldsAlreadyHidden = 0;
2987 if( !item->IsBOARD_ITEM() )
2993 switch( item->Type() )
2999 wxASSERT( parentFP );
3000 commit.
Modify( parentFP );
3009 fieldsAlreadyHidden++;
3012 getView()->Update( parentFP );
3029 commit.
Remove( board_item );
3035 commit.
Modify( board_item );
3036 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
3048 commit.
Remove( board_item );
3055 commit.
Remove( board_item );
3065 if( !aIsCut && aItems.
GetSize() == 1 )
3068 ZONE* zone =
static_cast<ZONE*
>( board_item );
3070 int outlineIdx, holeIdx;
3091 commit.
Remove( board_item );
3102 commit.Push(
_(
"Delete" ), commitFlags );
3110 commit.
Remove( board_item );
3118 commit.
Remove( board_item );
3127 if( enteredGroup && enteredGroup->
GetItems().empty() )
3132 commit.
Push(
_(
"Cut" ), commitFlags );
3134 else if( itemsDeleted == 0 )
3136 if( fieldsHidden == 1 )
3137 commit.
Push(
_(
"Hide Field" ), commitFlags );
3138 else if( fieldsHidden > 1 )
3139 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3140 else if( fieldsAlreadyHidden > 0 )
3141 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3145 commit.
Push(
_(
"Delete" ), commitFlags );
3156 std::vector<BOARD_ITEM*> lockedItems;
3174 const bool hadInitialSelection = !
m_selectionTool->GetSelection().Empty();
3189 if( hadInitialSelection && selectionCopy.
Empty() )
3219 if( selectionCopy.
Empty() )
3267 if( ret == wxID_OK )
3275 selCenter += translation;
3277 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3278 rotation = -rotation;
3282 if( !item->IsBOARD_ITEM() )
3290 boardItem->
Move( translation );
3292 switch( rotationAnchor )
3298 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3303 getView()->Update( boardItem );
3306 commit.
Push(
_(
"Move Exactly" ) );
3362 std::vector<BOARD_ITEM*> new_items;
3369 if( !item->IsBOARD_ITEM() )
3381 switch( orig_item->
Type() )
3401 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3403 dupe_item = orig_item->
Duplicate(
true, &commit );
3414 new_items.push_back( dupe_item );
3415 commit.
Add( dupe_item );
3425 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3427 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3433 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3440 new_items.push_back( dupe_item );
3441 commit.
Add( dupe_item );
3450 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3456 new_items.push_back( aItem );
3457 commit.
Add( aItem );
3462 new_items.push_back( dupe_item );
3463 commit.
Add( dupe_item );
3475 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3481 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3485 commit.
Push(
_(
"Duplicate" ) );
3503 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3505 switch( aCollector[i]->Type() )
3509 default: aCollector.
Remove( i );
break;
3534 commit = &localCommit;
3538 switch( item->Type() )
3548 if( !
pad.CanHaveNumber() )
3552 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3557 pad.SetNumber( *newNumber );
3566 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3571 text.SetText( *newText );
3583 commit->
Push(
_(
"Increment" ) );
3591 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3593 if( aCollector[i]->Type() !=
PCB_PAD_T )
3601 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3612 if( aSelection.
Empty() )
3636 BOX2I nonFieldsBBox;
3640 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3641 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3656 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3660 std::optional<VECTOR2I> pickedPoint;
3670 const auto setPickerLayerSet =
3677 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3685 setPickerLayerSet();
3688 [&](
const VECTOR2D& aPoint ) ->
bool
3690 pickedPoint = aPoint;
3692 if( !aSuccessMessage.empty() )
3714 if( !aCanceledMessage.empty() )
3726 [&](
const int& aFinalState )
3745 setPickerLayerSet();
3748 evt->SetPassEvent();
3759 canvas()->SetStatusPopup(
nullptr );
3763 aReferencePoint = *pickedPoint;
3765 return pickedPoint.has_value();
3773 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3776 frame()->PushTool( selectReferencePoint );
3793 std::vector<BOARD_ITEM*> items;
3797 if( item->IsBOARD_ITEM() )
3798 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3805 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3806 _(
"Copy canceled" ), refPoint ) )
3808 frame()->PopTool( selectReferencePoint );
3817 selection.SetReferencePoint( refPoint );
3821 frame()->SetStatusText(
_(
"Selection copied" ) );
3824 frame()->PopTool( selectReferencePoint );
3844 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3846 switch( aItem.Type() )
3858 return text.GetShownText(
true );
3872 for(
int row = 0; row <
table.GetRowCount(); ++row )
3874 for(
int col = 0; col <
table.GetColCount(); ++col )
3879 if( col <
table.GetColCount() - 1 )
3885 if( row <
table.GetRowCount() - 1 )
3896 return wxEmptyString;
3899 wxArrayString itemTexts;
3903 if( item->IsBOARD_ITEM() )
3906 wxString itemText = getItemText( *boardItem );
3908 itemText.Trim(
false ).Trim(
true );
3910 if( !itemText.IsEmpty() )
3912 itemTexts.Add( std::move( itemText ) );
3918 if( !itemTexts.empty() )
3920 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3945 board()->BuildConnectivity();
3947 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.
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
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.
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()
bool IsHatchedFill() const
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.
std::deque< FOOTPRINT * > FOOTPRINTS
@ 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.
std::vector< std::vector< std::string > > table
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