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 )
150 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
153 menu->SetUntranslatedTitle(
_HKI(
"Mirror / Rotate" ) );
155 auto canMirror = [](
const SELECTION& aSelection )
179 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
182 menu->SetUntranslatedTitle(
_HKI(
"Routing" ) );
184 auto notMovingCondition = [](
const SELECTION& aSelection )
186 return aSelection.Empty() || !aSelection.Front()->IsMoving();
204 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
207 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
209 auto notMovingCondition = [](
const SELECTION& aSelection )
211 return aSelection.Empty() || !aSelection.Front()->IsMoving();
225 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
227 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
242 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
249 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
256 auto canAddCornerCondition = [](
const SELECTION& aSelection )
258 const EDA_ITEM* item = aSelection.Front();
263 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
265 const EDA_ITEM* item = aSelection.Front();
270 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
336 for(
const EDA_ITEM* it : aSelection )
349 if( units.size() < 2 )
352 const wxString& padNum =
pad->GetNumber();
353 bool inAnyUnit =
false;
355 for(
const auto& u : units )
357 for(
const auto& pnum : u.m_pins )
375 else if( single != fp )
386 std::unordered_set<wxString> padNums;
388 for(
const EDA_ITEM* it : aSelection )
395 if(
pad->GetParentFootprint() != aFootprint )
398 padNums.insert(
pad->GetNumber() );
407 const std::unordered_set<wxString>& aSelPadNums )
409 std::vector<int> indices;
413 for(
size_t i = 0; i < units.size(); ++i )
417 for(
const auto& pn : units[i].m_pins )
419 if( aSelPadNums.count( pn ) )
427 indices.push_back(
static_cast<int>( i ) );
437 if( aUnitIndices.empty() )
441 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
443 for(
int idx : aUnitIndices )
445 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
456 std::vector<int> targets;
459 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
461 for(
size_t i = 0; i < units.size(); ++i )
463 if(
static_cast<int>( i ) == aSourceIdx )
466 if( units[i].m_pins.size() != pinCount )
469 targets.push_back(
static_cast<int>( i ) );
499 if( unitsHit.size() != 1 )
502 const int sourceIdx = unitsHit.front();
505 for(
int idx : targets )
508 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
516 int id = aEvent.GetId();
531 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
547 auto menu = std::make_shared<GATE_SWAP_MENU>();
548 menu->SetTool( aTool );
562 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
568 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
573 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
576 subMenu->Evaluate( aSel );
577 return subMenu->GetMenuItemCount() > 0;
580 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
583 subMenu->Evaluate( aSel );
584 return subMenu->GetMenuItemCount() > 0;
588 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
599 if( unitsHit.size() != 1 )
602 const int sourceIdx = unitsHit.front();
604 return !targets.empty();
608 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
619 if( unitsHit.size() < 2 )
625 auto propertiesCondition = [
this](
const SELECTION& aSel )
627 if( aSel.GetSize() == 0 )
641 if( aSel.GetSize() == 1 )
653 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
658 auto canMirror = [
this](
const SELECTION& aSelection )
671 auto singleFootprintCondition =
674 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
676 bool foundFirst =
false;
692 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
694 return frame()->ToolStackIsEmpty();
697 auto notMovingCondition = [](
const SELECTION& aSelection )
699 return aSelection.Empty() || !aSelection.Front()->IsMoving();
702 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
704 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
707 auto isSkippable = [
this](
const SELECTION& aSelection )
713 && notMovingCondition && !inFootprintEditor;
751 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
766 && !inFootprintEditor );
778 menu.AddSeparator( 100 );
779 menu.AddMenu( routingSubMenu.get(), isRoutable, 100 );
780 menu.AddMenu( mirrorRotateSubMenu.get(), canMirror, 100 );
781 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
782 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
784 menu.AddSeparator( 150 );
797 menu.AddSeparator( 2000 );
812 wxString footprintName;
813 wxArrayString fplist;
818 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
828 footprintName.Trim(
true );
829 footprintName.Trim(
false );
831 if( !footprintName.IsEmpty() )
835 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
935 std::vector<PCB_TRACK*> tracks;
936 std::vector<PCB_TRACK*> vias;
937 std::vector<FOOTPRINT*> footprints;
940 const auto gatherItemsByType = [&]()
947 vias.push_back( track );
949 tracks.push_back( track );
964 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
970 else if( tracks.size() || vias.size() )
997 if( tracks.size() == 2 && vias.size() == 0 )
999 if( connected( tracks[0], tracks[1]->GetStart() )
1000 || connected( tracks[0], tracks[1]->GetEnd() ) )
1002 aCollector.
Remove( tracks[1] );
1005 else if( tracks.size() == 2 && vias.size() == 1 )
1007 if( connected( tracks[0], vias[0]->GetPosition() )
1008 && connected( tracks[1], vias[0]->GetPosition() ) )
1010 aCollector.
Remove( tracks[0] );
1011 aCollector.
Remove( tracks[1] );
1051 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
1053 frame()->ShowInfoBarError( msg );
1066 bool restore_state =
false;
1080 tanStart.
A = *tanIntersect;
1082 tanEnd.
A = *tanIntersect;
1085 std::set<PCB_TRACK*> addedTracks;
1087 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1089 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1092 int allowedDeviation = theArc->
GetWidth();
1094 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1096 for(
int i = 0; i < 3; i++ )
1098 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1099 allowedDeviation /= 2;
1101 if( itemsOnAnchor.size() == 1 )
1107 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1109 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1115 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1123 track->
SetEnd( aAnchor );
1132 addedTracks.insert( track );
1138 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1139 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1144 tanStart.
B = trackOnStart->
GetEnd();
1150 tanEnd.
B = trackOnEnd->
GetEnd();
1154 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1157 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1159 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1160 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1162 return trackStartToArcStart < trackEndToArcStart;
1165 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1166 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1197 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1208 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1209 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1210 VECTOR2I tempTangentPoint = tanEndPoint;
1212 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1213 tempTangentPoint = tanStartPoint;
1219 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1220 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1221 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1223 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1224 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1225 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1227 bool eatFirstMouseUp =
true;
1238 std::vector<VECTOR2I> possiblePoints;
1245 for(
const VECTOR2I& candidate : possiblePoints )
1247 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1249 closest = candidate;
1273 theArc->
SetEnd( newEnd );
1274 theArc->
SetMid( newMid );
1276 if( isStartTrackOnStartPt )
1277 trackOnStart->
SetStart( newStart );
1279 trackOnStart->
SetEnd( newStart );
1281 if( isEndTrackOnStartPt )
1284 trackOnEnd->
SetEnd( newEnd );
1287 getView()->Update( trackOnStart );
1288 getView()->Update( trackOnEnd );
1292 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1294 eatFirstMouseUp =
false;
1296 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1298 restore_state =
true;
1303 restore_state =
true;
1311 eatFirstMouseUp =
false;
1323 if( isStartTrackOnStartPt )
1324 newStart = trackOnStart->
GetEnd();
1326 if( isEndTrackOnStartPt )
1327 newEnd = trackOnEnd->
GetEnd();
1331 if( trackOnStart->
GetLength() <= maxLengthIU )
1333 if( addedTracks.count( trackOnStart ) )
1335 getView()->Remove( trackOnStart );
1336 addedTracks.erase( trackOnStart );
1337 delete trackOnStart;
1341 commit.
Remove( trackOnStart );
1347 if( trackOnEnd->
GetLength() <= maxLengthIU )
1349 if( addedTracks.count( trackOnEnd ) )
1351 getView()->Remove( trackOnEnd );
1352 addedTracks.erase( trackOnEnd );
1357 commit.
Remove( trackOnEnd );
1360 theArc->
SetEnd( newEnd );
1369 commit.
Add( added );
1376 commit.
Push(
_(
"Drag Arc Track" ) );
1388 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1393 aCollector.
Remove( item );
1423 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1424 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1427 via->SetDrill( new_drill );
1435 wxCHECK( track, 0 );
1439 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1444 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1469 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1474 aCollector.
Remove( item );
1491 if( newLayer == origLayer )
1502 wxCHECK( track, 0 );
1510 commit.
Push(
_(
"Edit Track Layer" ) );
1527 static int filletRadius = 0;
1533 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1538 aCollector.
Remove( item );
1548 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1564 bool t1Start =
true;
1565 bool t2Start =
true;
1568 std::vector<FILLET_OP> filletOperations;
1569 bool operationPerformedOnAtLeastOne =
false;
1570 bool didOneAttemptFail =
false;
1571 std::set<PCB_TRACK*> processedTracks;
1573 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1575 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1577 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1581 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1587 if( processedTracks.find( trackOther ) == processedTracks.end() )
1589 if( itemsOnAnchor.size() == 1 )
1592 filletOp.t1 = aTrack;
1593 filletOp.t2 = trackOther;
1594 filletOp.t1Start = aStartPoint;
1595 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1596 filletOperations.push_back( filletOp );
1602 didOneAttemptFail =
true;
1616 processFilletOp( track,
true );
1617 processFilletOp( track,
false );
1619 processedTracks.insert( track );
1625 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1627 for( FILLET_OP filletOp : filletOperations )
1635 if( trackOnStart && trackOnEnd )
1638 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1646 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1649 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1651 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1656 aPointToSet.
x = aVecToTest.x;
1657 aPointToSet.
y = aVecToTest.y;
1665 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1666 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1668 didOneAttemptFail =
true;
1672 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1673 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1675 didOneAttemptFail =
true;
1687 itemsToAddToSelection.push_back( tArc );
1692 if( filletOp.t1Start )
1695 track1->
SetEnd( t1newPoint );
1697 if( filletOp.t2Start )
1700 track2->
SetEnd( t2newPoint );
1702 operationPerformedOnAtLeastOne =
true;
1706 commit.
Push(
_(
"Fillet Tracks" ) );
1709 for(
BOARD_ITEM* item : itemsToAddToSelection )
1712 if( !operationPerformedOnAtLeastOne )
1713 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1714 else if( didOneAttemptFail )
1715 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1735 return std::nullopt;
1739 return aPersitentRadius;
1751 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1758 _(
"Add slots in acute corners" ),
1760 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1767 return std::nullopt;
1769 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1770 wxCHECK( results.size() == 2, std::nullopt );
1774 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1775 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1777 catch(
const std::bad_variant_access& )
1780 return std::nullopt;
1783 return s_dogBoneParams;
1797 const int default_setback =
pcbIUScale.mmToIU( 1 );
1799 static CHAMFER_PARAMS params{ default_setback, default_setback };
1801 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1804 return std::nullopt;
1806 params.m_chamfer_setback_a = dlg.
GetValue();
1809 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1820 std::vector<VECTOR2I> pts;
1823 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1830 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1832 aCollector.
Remove( item );
1841 std::set<PCB_SHAPE*> lines_to_add;
1842 std::vector<PCB_SHAPE*> items_to_remove;
1846 std::vector<VECTOR2I> pts;
1853 items_to_remove.push_back( graphic );
1856 pts.emplace_back( start );
1858 pts.emplace_back(
end );
1864 items_to_remove.push_back( graphic );
1866 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1870 for(
size_t jj = 1; jj < pts.size(); ++jj )
1878 lines_to_add.insert( line );
1881 if( pts.size() > 1 )
1886 line->
SetEnd( pts.front() );
1889 lines_to_add.insert( line );
1897 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1904 else if( segmentCount < 2 )
1906 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1924 for(
PCB_SHAPE* item : items_to_remove )
1935 std::vector<BOARD_ITEM*> items_to_select_on_success;
1938 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1943 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1949 items_to_select_on_success.push_back( &aItem );
1953 bool any_items_created = !lines_to_add.empty();
1954 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1956 any_items_created =
true;
1957 items_to_select_on_success.push_back( aItem.get() );
1958 commit.
Add( aItem.release() );
1961 bool any_items_removed = !items_to_remove.empty();
1962 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1965 any_items_removed =
true;
1966 items_to_deselect_on_success.push_back( &aItem );
1972 item_removal_handler );
1975 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1979 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1980 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1982 if( filletRadiusIU.has_value() )
1984 pairwise_line_routine =
1985 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1992 if( dogboneParams.has_value() )
1994 pairwise_line_routine =
1995 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
2002 if( chamfer_params.has_value() )
2004 pairwise_line_routine =
2005 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
2010 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
2013 if( !pairwise_line_routine )
2024 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
2026 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
2027 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
2029 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
2034 for(
BOARD_ITEM* item : items_to_select_on_success )
2035 m_selectionTool->AddItemToSel( item,
true );
2038 for(
BOARD_ITEM* item : items_to_deselect_on_success )
2039 m_selectionTool->RemoveItemFromSel( item,
true );
2041 if( any_items_removed )
2044 if( any_items_created )
2050 commit.Push( pairwise_line_routine->GetCommitDescription() );
2052 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
2053 frame()->ShowInfoBarMsg( *msg );
2064 std::vector<VECTOR2I> pts;
2067 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2071 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2072 aCollector.
Remove( item );
2076 if( zone->IsTeardropArea() )
2077 aCollector.
Remove( item );
2087 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2096 if( s_toleranceValue <= 0 )
2101 std::vector<PCB_SHAPE*> shapeList;
2105 commit.Modify( item );
2119 zone->HatchBorder();
2123 commit.
Push(
_(
"Simplify Polygons" ) );
2137 std::vector<VECTOR2I> pts;
2140 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2147 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2149 aCollector.
Remove( item );
2159 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2168 if( s_toleranceValue <= 0 )
2173 std::vector<PCB_SHAPE*> shapeList;
2179 shapeList.push_back( shape );
2180 commit.Modify( shape );
2186 commit.Push(
_(
"Heal Shapes" ) );
2201 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2205 static const std::vector<KICAD_T> polygonBooleanTypes = {
2211 if( !item->
IsType( polygonBooleanTypes ) )
2212 aCollector.
Remove( item );
2223 std::vector<PCB_SHAPE*> items_to_process;
2227 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2232 if( item == last_item )
2233 std::swap( items_to_process.back(), items_to_process.front() );
2239 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2241 commit.Modify( &aItem );
2244 std::vector<BOARD_ITEM*> items_to_select_on_success;
2246 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2248 items_to_select_on_success.push_back( aItem.get() );
2249 commit.Add( aItem.release() );
2252 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2254 commit.Remove( &aItem );
2259 item_removal_handler );
2262 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2264 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2271 wxCHECK(
model,
nullptr );
2275 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2279 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2283 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2288 const auto run_routine = [&]()
2291 for(
PCB_SHAPE* shape : items_to_process )
2292 boolean_routine->ProcessShape( *shape );
2294 boolean_routine->Finalize();
2297 boolean_routine = create_routine();
2299 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2306 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2310 items_to_select_on_success.clear();
2312 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2314 for(
PCB_SHAPE* shape : items_to_process )
2317 items_area[shape] = area;
2326 std::sort( items_to_process.begin(), items_to_process.end(),
2329 return items_area[a] > items_area[b];
2333 boolean_routine = create_routine();
2338 for(
BOARD_ITEM* item : items_to_select_on_success )
2344 commit.Push( boolean_routine->GetCommitDescription() );
2346 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2347 frame()->ShowInfoBarMsg( *msg );
2369 std::vector<PCB_TABLECELL*> cells;
2420 for(
EDA_ITEM* eda_item : selCopy )
2422 if( !eda_item->IsBOARD_ITEM() )
2464 if( editFrame && item )
2484 commit = &localCommit;
2507 std::optional<VECTOR2I> oldRefPt;
2512 oldRefPt =
selection.GetReferencePoint();
2538 bool usePcbShapeCenter =
false;
2545 usePcbShapeCenter =
true;
2549 usePcbShapeCenter =
true;
2555 else if( usePcbShapeCenter )
2567 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2568 rotateAngle = -rotateAngle;
2574 viewBBox.
Merge( item->ViewBBox() );
2583 typedef std::numeric_limits<int> coord_limits;
2588 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2589 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2597 if( item->IsBOARD_ITEM() )
2601 board_item->
Rotate( refPt, rotateAngle );
2605 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2612 localCommit.
Push(
_(
"Rotate" ) );
2629 selection.SetReferencePoint( *oldRefPt );
2647 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2680 commit = &localCommit;
2710 switch( item->Type() )
2713 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2717 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2722 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2734 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2740 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2744 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2753 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2764 localCommit.
Push(
_(
"Mirror" ) );
2793 commit = &localCommit;
2807 auto setJustify = [&](
EDA_TEXT* aTextItem )
2822 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2831 if( !localCommit.
Empty() )
2834 localCommit.
Push(
_(
"Left Justify" ) );
2836 localCommit.
Push(
_(
"Center Justify" ) );
2838 localCommit.
Push(
_(
"Right Justify" ) );
2868 commit = &localCommit;
2885 std::optional<VECTOR2I> oldRefPt;
2888 oldRefPt =
selection.GetReferencePoint();
2914 if( !item->IsBOARD_ITEM() )
2921 boardItem->
Flip( refPt, flipDirection );
2925 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2931 localCommit.
Push(
_(
"Change Side / Flip" ) );
2947 selection.SetReferencePoint( *oldRefPt );
2959 int commitFlags = 0;
2964 int itemsDeleted = 0;
2965 int fieldsHidden = 0;
2966 int fieldsAlreadyHidden = 0;
2970 if( !item->IsBOARD_ITEM() )
2976 switch( item->Type() )
2982 wxASSERT( parentFP );
2983 commit.
Modify( parentFP );
2992 fieldsAlreadyHidden++;
2995 getView()->Update( parentFP );
3012 commit.
Remove( board_item );
3018 commit.
Modify( board_item );
3019 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
3031 commit.
Remove( board_item );
3038 commit.
Remove( board_item );
3048 if( !aIsCut && aItems.
GetSize() == 1 )
3051 ZONE* zone =
static_cast<ZONE*
>( board_item );
3053 int outlineIdx, holeIdx;
3074 commit.
Remove( board_item );
3085 commit.Push(
_(
"Delete" ), commitFlags );
3093 commit.
Remove( board_item );
3101 commit.
Remove( board_item );
3110 if( enteredGroup && enteredGroup->
GetItems().empty() )
3115 commit.
Push(
_(
"Cut" ), commitFlags );
3117 else if( itemsDeleted == 0 )
3119 if( fieldsHidden == 1 )
3120 commit.
Push(
_(
"Hide Field" ), commitFlags );
3121 else if( fieldsHidden > 1 )
3122 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3123 else if( fieldsAlreadyHidden > 0 )
3124 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3128 commit.
Push(
_(
"Delete" ), commitFlags );
3139 std::vector<BOARD_ITEM*> lockedItems;
3193 if( selectionCopy.
Empty() )
3241 if( ret == wxID_OK )
3249 selCenter += translation;
3251 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3252 rotation = -rotation;
3256 if( !item->IsBOARD_ITEM() )
3264 boardItem->
Move( translation );
3266 switch( rotationAnchor )
3272 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3277 getView()->Update( boardItem );
3280 commit.
Push(
_(
"Move Exactly" ) );
3336 std::vector<BOARD_ITEM*> new_items;
3343 if( !item->IsBOARD_ITEM() )
3355 switch( orig_item->
Type() )
3375 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3377 dupe_item = orig_item->
Duplicate(
true, &commit );
3388 new_items.push_back( dupe_item );
3389 commit.
Add( dupe_item );
3399 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3401 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3407 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3414 new_items.push_back( dupe_item );
3415 commit.
Add( dupe_item );
3424 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3430 new_items.push_back( aItem );
3431 commit.
Add( aItem );
3436 new_items.push_back( dupe_item );
3437 commit.
Add( dupe_item );
3449 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3455 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3459 commit.
Push(
_(
"Duplicate" ) );
3477 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3479 switch( aCollector[i]->Type() )
3483 default: aCollector.
Remove( i );
break;
3508 commit = &localCommit;
3512 switch( item->Type() )
3522 if( !
pad.CanHaveNumber() )
3526 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3531 pad.SetNumber( *newNumber );
3540 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3545 text.SetText( *newText );
3557 commit->
Push(
_(
"Increment" ) );
3565 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3567 if( aCollector[i]->Type() !=
PCB_PAD_T )
3575 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3586 if( aSelection.
Empty() )
3610 BOX2I nonFieldsBBox;
3614 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3615 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3630 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3634 std::optional<VECTOR2I> pickedPoint;
3644 const auto setPickerLayerSet =
3651 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3659 setPickerLayerSet();
3662 [&](
const VECTOR2D& aPoint ) ->
bool
3664 pickedPoint = aPoint;
3666 if( !aSuccessMessage.empty() )
3688 if( !aCanceledMessage.empty() )
3700 [&](
const int& aFinalState )
3719 setPickerLayerSet();
3722 evt->SetPassEvent();
3733 canvas()->SetStatusPopup(
nullptr );
3737 aReferencePoint = *pickedPoint;
3739 return pickedPoint.has_value();
3747 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3750 frame()->PushTool( selectReferencePoint );
3767 std::vector<BOARD_ITEM*> items;
3771 if( item->IsBOARD_ITEM() )
3772 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3779 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3780 _(
"Copy canceled" ), refPoint ) )
3782 frame()->PopTool( selectReferencePoint );
3791 selection.SetReferencePoint( refPoint );
3795 frame()->SetStatusText(
_(
"Selection copied" ) );
3798 frame()->PopTool( selectReferencePoint );
3818 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3820 switch( aItem.Type() )
3832 return text.GetShownText(
true );
3846 for(
int row = 0; row <
table.GetRowCount(); ++row )
3848 for(
int col = 0; col <
table.GetColCount(); ++col )
3853 if( col <
table.GetColCount() - 1 )
3859 if( row <
table.GetRowCount() - 1 )
3870 return wxEmptyString;
3873 wxArrayString itemTexts;
3877 if( item->IsBOARD_ITEM() )
3880 wxString itemText = getItemText( *boardItem );
3882 itemText.Trim(
false ).Trim(
true );
3884 if( !itemText.IsEmpty() )
3886 itemTexts.Add( std::move( itemText ) );
3892 if( !itemTexts.empty() )
3894 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3919 board()->BuildConnectivity();
3921 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