70using namespace std::placeholders;
72#include <wx/hyperlink.h>
77#include <dialogs/dialog_tablecell_properties.h>
78#include <dialogs/dialog_table_properties.h>
98 ZONE* zone =
static_cast<ZONE*
>( aItem );
111 if( aSelection.
GetSize() != 1 )
153 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
156 menu->SetUntranslatedTitle(
_HKI(
"Mirror / Rotate" ) );
158 auto canMirror = [](
const SELECTION& aSelection )
182 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
185 menu->SetUntranslatedTitle(
_HKI(
"Routing" ) );
187 auto notMovingCondition = [](
const SELECTION& aSelection )
189 return aSelection.Empty() || !aSelection.Front()->IsMoving();
207 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
210 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
212 auto notMovingCondition = [](
const SELECTION& aSelection )
214 return aSelection.Empty() || !aSelection.Front()->IsMoving();
228 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
230 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
245 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
252 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
259 auto canAddCornerCondition = [](
const SELECTION& aSelection )
261 const EDA_ITEM* item = aSelection.Front();
266 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
268 const EDA_ITEM* item = aSelection.Front();
273 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
339 for(
const EDA_ITEM* it : aSelection )
352 if( units.size() < 2 )
355 const wxString& padNum =
pad->GetNumber();
356 bool inAnyUnit =
false;
358 for(
const auto& u : units )
360 for(
const auto& pnum : u.m_pins )
378 else if( single != fp )
389 std::unordered_set<wxString> padNums;
391 for(
const EDA_ITEM* it : aSelection )
398 if(
pad->GetParentFootprint() != aFootprint )
401 padNums.insert(
pad->GetNumber() );
410 const std::unordered_set<wxString>& aSelPadNums )
412 std::vector<int> indices;
416 for(
size_t i = 0; i < units.size(); ++i )
420 for(
const auto& pn : units[i].m_pins )
422 if( aSelPadNums.count( pn ) )
430 indices.push_back(
static_cast<int>( i ) );
440 if( aUnitIndices.empty() )
444 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
446 for(
int idx : aUnitIndices )
448 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
459 std::vector<int> targets;
462 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
464 for(
size_t i = 0; i < units.size(); ++i )
466 if(
static_cast<int>( i ) == aSourceIdx )
469 if( units[i].m_pins.size() != pinCount )
472 targets.push_back(
static_cast<int>( i ) );
502 if( unitsHit.size() != 1 )
505 const int sourceIdx = unitsHit.front();
508 for(
int idx : targets )
511 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
519 int id = aEvent.GetId();
534 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
550 auto menu = std::make_shared<GATE_SWAP_MENU>();
551 menu->SetTool( aTool );
565 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
571 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
576 auto fpAttributesMenu = std::make_shared<CONDITIONAL_MENU>(
this );
577 fpAttributesMenu->SetUntranslatedTitle(
_HKI(
"Attributes" ) );
582 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
585 subMenu->Evaluate( aSel );
586 return subMenu->GetMenuItemCount() > 0;
589 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
592 subMenu->Evaluate( aSel );
593 return subMenu->GetMenuItemCount() > 0;
597 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
608 if( unitsHit.size() != 1 )
611 const int sourceIdx = unitsHit.front();
613 return !targets.empty();
617 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
628 if( unitsHit.size() < 2 )
634 auto propertiesCondition = [
this](
const SELECTION& aSel )
636 if( aSel.GetSize() == 0 )
650 if( aSel.GetSize() == 1 )
662 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
667 auto canMirror = [
this](
const SELECTION& aSelection )
680 auto singleFootprintCondition =
683 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
685 bool foundFirst =
false;
701 auto excludeFromBOMCond = [
this](
const SELECTION& aSel )
703 wxString variantName;
704 int checked = 0, unchecked = 0;
707 variantName =
board->GetCurrentVariant();
713 if(
static_cast<const FOOTPRINT*
>( item )->GetExcludedFromBOMForVariant( variantName ) )
720 return checked > 0 && unchecked == 0;
723 auto excludeFromPosFilesCond = [
this](
const SELECTION& aSel )
725 wxString variantName;
726 int checked = 0, unchecked = 0;
729 variantName =
board->GetCurrentVariant();
735 if(
static_cast<const FOOTPRINT*
>( item )->GetExcludedFromPosFilesForVariant( variantName ) )
742 return checked > 0 && unchecked == 0;
745 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
747 return frame()->ToolStackIsEmpty();
750 auto notMovingCondition = [](
const SELECTION& aSelection )
752 return aSelection.Empty() || !aSelection.Front()->IsMoving();
755 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
757 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
760 auto isSkippable = [
this](
const SELECTION& aSelection )
766 && notMovingCondition && !inFootprintEditor;
804 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
819 && !inFootprintEditor );
829 menu.AddMenu( fpAttributesMenu.get(), singleFootprintCondition || multipleFootprintsCondition );
832 menu.AddSeparator( 100 );
833 menu.AddMenu( routingSubMenu.get(), isRoutable, 100 );
834 menu.AddMenu( mirrorRotateSubMenu.get(), canMirror, 100 );
835 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
836 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
838 menu.AddSeparator( 150 );
851 menu.AddSeparator( 2000 );
870 wxString footprintName;
871 wxArrayString fplist;
876 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
886 footprintName.Trim(
true );
887 footprintName.Trim(
false );
889 if( !footprintName.IsEmpty() )
893 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
993 std::vector<PCB_TRACK*> tracks;
994 std::vector<PCB_TRACK*> vias;
995 std::vector<FOOTPRINT*> footprints;
998 const auto gatherItemsByType = [&]()
1005 vias.push_back( track );
1007 tracks.push_back( track );
1017 gatherItemsByType();
1022 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
1028 else if( tracks.size() || vias.size() )
1042 gatherItemsByType();
1055 if( tracks.size() == 2 && vias.size() == 0 )
1057 if( connected( tracks[0], tracks[1]->GetStart() )
1058 || connected( tracks[0], tracks[1]->GetEnd() ) )
1060 aCollector.
Remove( tracks[1] );
1063 else if( tracks.size() == 2 && vias.size() == 1 )
1065 if( connected( tracks[0], vias[0]->GetPosition() )
1066 && connected( tracks[1], vias[0]->GetPosition() ) )
1068 aCollector.
Remove( tracks[0] );
1069 aCollector.
Remove( tracks[1] );
1109 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
1111 frame()->ShowInfoBarError( msg );
1124 bool restore_state =
false;
1138 tanStart.
A = *tanIntersect;
1140 tanEnd.
A = *tanIntersect;
1143 std::set<PCB_TRACK*> addedTracks;
1145 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1147 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1150 int allowedDeviation = theArc->
GetWidth();
1152 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1154 for(
int i = 0; i < 3; i++ )
1156 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1157 allowedDeviation /= 2;
1159 if( itemsOnAnchor.size() == 1 )
1165 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1167 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1173 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1181 track->
SetEnd( aAnchor );
1190 addedTracks.insert( track );
1196 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1197 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1202 tanStart.
B = trackOnStart->
GetEnd();
1208 tanEnd.
B = trackOnEnd->
GetEnd();
1212 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1215 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1217 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1218 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1220 return trackStartToArcStart < trackEndToArcStart;
1223 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1224 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1255 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1266 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1267 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1268 VECTOR2I tempTangentPoint = tanEndPoint;
1270 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1271 tempTangentPoint = tanStartPoint;
1277 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1278 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1279 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1281 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1282 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1283 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1285 bool eatFirstMouseUp =
true;
1296 std::vector<VECTOR2I> possiblePoints;
1303 for(
const VECTOR2I& candidate : possiblePoints )
1305 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1307 closest = candidate;
1331 theArc->
SetEnd( newEnd );
1332 theArc->
SetMid( newMid );
1334 if( isStartTrackOnStartPt )
1335 trackOnStart->
SetStart( newStart );
1337 trackOnStart->
SetEnd( newStart );
1339 if( isEndTrackOnStartPt )
1342 trackOnEnd->
SetEnd( newEnd );
1345 getView()->Update( trackOnStart );
1346 getView()->Update( trackOnEnd );
1350 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1352 eatFirstMouseUp =
false;
1354 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1356 restore_state =
true;
1361 restore_state =
true;
1369 eatFirstMouseUp =
false;
1381 if( isStartTrackOnStartPt )
1382 newStart = trackOnStart->
GetEnd();
1384 if( isEndTrackOnStartPt )
1385 newEnd = trackOnEnd->
GetEnd();
1389 if( trackOnStart->
GetLength() <= maxLengthIU )
1391 if( addedTracks.count( trackOnStart ) )
1393 getView()->Remove( trackOnStart );
1394 addedTracks.erase( trackOnStart );
1395 delete trackOnStart;
1399 commit.
Remove( trackOnStart );
1405 if( trackOnEnd->
GetLength() <= maxLengthIU )
1407 if( addedTracks.count( trackOnEnd ) )
1409 getView()->Remove( trackOnEnd );
1410 addedTracks.erase( trackOnEnd );
1415 commit.
Remove( trackOnEnd );
1418 theArc->
SetEnd( newEnd );
1427 commit.
Add( added );
1434 commit.
Push(
_(
"Drag Arc Track" ) );
1447 wxString variantName;
1450 variantName =
board->GetCurrentVariant();
1452 bool new_state =
false;
1475 if( !variantName.IsEmpty() )
1499 if( !commit.
Empty() )
1500 commit.
Push(
_(
"Toggle Attribute" ) );
1515 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1520 aCollector.
Remove( item );
1550 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1551 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1554 via->SetDrill( new_drill );
1562 wxCHECK( track, 0 );
1566 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1571 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1596 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1601 aCollector.
Remove( item );
1618 if( newLayer == origLayer )
1629 wxCHECK( track, 0 );
1637 commit.
Push(
_(
"Edit Track Layer" ) );
1654 static int filletRadius = 0;
1660 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1665 aCollector.
Remove( item );
1675 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1691 bool t1Start =
true;
1692 bool t2Start =
true;
1695 std::vector<FILLET_OP> filletOperations;
1696 bool operationPerformedOnAtLeastOne =
false;
1697 bool didOneAttemptFail =
false;
1698 std::set<PCB_TRACK*> processedTracks;
1700 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1702 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1704 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1708 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1714 if( processedTracks.find( trackOther ) == processedTracks.end() )
1716 if( itemsOnAnchor.size() == 1 )
1719 filletOp.t1 = aTrack;
1720 filletOp.t2 = trackOther;
1721 filletOp.t1Start = aStartPoint;
1722 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1723 filletOperations.push_back( filletOp );
1729 didOneAttemptFail =
true;
1743 processFilletOp( track,
true );
1744 processFilletOp( track,
false );
1746 processedTracks.insert( track );
1752 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1754 for( FILLET_OP filletOp : filletOperations )
1762 if( trackOnStart && trackOnEnd )
1765 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1773 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1776 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1778 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1783 aPointToSet.
x = aVecToTest.x;
1784 aPointToSet.
y = aVecToTest.y;
1792 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1793 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1795 didOneAttemptFail =
true;
1799 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1800 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1802 didOneAttemptFail =
true;
1814 itemsToAddToSelection.push_back( tArc );
1819 if( filletOp.t1Start )
1822 track1->
SetEnd( t1newPoint );
1824 if( filletOp.t2Start )
1827 track2->
SetEnd( t2newPoint );
1829 operationPerformedOnAtLeastOne =
true;
1833 commit.
Push(
_(
"Fillet Tracks" ) );
1836 for(
BOARD_ITEM* item : itemsToAddToSelection )
1839 if( !operationPerformedOnAtLeastOne )
1840 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1841 else if( didOneAttemptFail )
1842 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1862 return std::nullopt;
1866 return aPersitentRadius;
1878 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1885 _(
"Add slots in acute corners" ),
1887 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1894 return std::nullopt;
1896 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1897 wxCHECK( results.size() == 2, std::nullopt );
1901 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1902 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1904 catch(
const std::bad_variant_access& )
1907 return std::nullopt;
1910 return s_dogBoneParams;
1924 const int default_setback =
pcbIUScale.mmToIU( 1 );
1926 static CHAMFER_PARAMS params{ default_setback, default_setback };
1928 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1931 return std::nullopt;
1933 params.m_chamfer_setback_a = dlg.
GetValue();
1936 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1947 std::vector<VECTOR2I> pts;
1950 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1957 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1959 aCollector.
Remove( item );
1968 std::set<PCB_SHAPE*> lines_to_add;
1969 std::vector<PCB_SHAPE*> items_to_remove;
1973 std::vector<VECTOR2I> pts;
1980 items_to_remove.push_back( graphic );
1983 pts.emplace_back( start );
1985 pts.emplace_back(
end );
1991 items_to_remove.push_back( graphic );
1993 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1997 for(
size_t jj = 1; jj < pts.size(); ++jj )
2005 lines_to_add.insert( line );
2008 if( pts.size() > 1 )
2013 line->
SetEnd( pts.front() );
2016 lines_to_add.insert( line );
2024 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
2031 else if( segmentCount < 2 )
2033 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
2051 for(
PCB_SHAPE* item : items_to_remove )
2062 std::vector<BOARD_ITEM*> items_to_select_on_success;
2065 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
2070 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2076 items_to_select_on_success.push_back( &aItem );
2080 bool any_items_created = !lines_to_add.empty();
2081 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2083 any_items_created =
true;
2084 items_to_select_on_success.push_back( aItem.get() );
2085 commit.
Add( aItem.release() );
2088 bool any_items_removed = !items_to_remove.empty();
2089 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2092 any_items_removed =
true;
2093 items_to_deselect_on_success.push_back( &aItem );
2099 item_removal_handler );
2102 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
2106 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
2107 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
2109 if( filletRadiusIU.has_value() )
2111 pairwise_line_routine =
2112 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
2119 if( dogboneParams.has_value() )
2121 pairwise_line_routine =
2122 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
2129 if( chamfer_params.has_value() )
2131 pairwise_line_routine =
2132 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
2137 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
2140 if( !pairwise_line_routine )
2151 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
2153 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
2154 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
2156 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
2161 for(
BOARD_ITEM* item : items_to_select_on_success )
2162 m_selectionTool->AddItemToSel( item,
true );
2165 for(
BOARD_ITEM* item : items_to_deselect_on_success )
2166 m_selectionTool->RemoveItemFromSel( item,
true );
2168 if( any_items_removed )
2171 if( any_items_created )
2177 commit.Push( pairwise_line_routine->GetCommitDescription() );
2179 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
2180 frame()->ShowInfoBarMsg( *msg );
2191 std::vector<VECTOR2I> pts;
2194 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2198 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2199 aCollector.
Remove( item );
2203 if( zone->IsTeardropArea() )
2204 aCollector.
Remove( item );
2214 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2223 if( s_toleranceValue <= 0 )
2228 std::vector<PCB_SHAPE*> shapeList;
2232 commit.Modify( item );
2246 zone->HatchBorder();
2250 commit.
Push(
_(
"Simplify Polygons" ) );
2264 std::vector<VECTOR2I> pts;
2267 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2274 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2276 aCollector.
Remove( item );
2286 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2295 if( s_toleranceValue <= 0 )
2300 std::vector<PCB_SHAPE*> shapeList;
2306 shapeList.push_back( shape );
2307 commit.Modify( shape );
2313 commit.Push(
_(
"Heal Shapes" ) );
2328 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2332 static const std::vector<KICAD_T> polygonBooleanTypes = {
2338 if( !item->
IsType( polygonBooleanTypes ) )
2339 aCollector.
Remove( item );
2350 std::vector<PCB_SHAPE*> items_to_process;
2354 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2359 if( item == last_item )
2360 std::swap( items_to_process.back(), items_to_process.front() );
2366 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2368 commit.Modify( &aItem );
2371 std::vector<BOARD_ITEM*> items_to_select_on_success;
2373 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2375 items_to_select_on_success.push_back( aItem.get() );
2376 commit.Add( aItem.release() );
2379 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2381 commit.Remove( &aItem );
2386 item_removal_handler );
2389 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2391 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2398 wxCHECK(
model,
nullptr );
2402 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2406 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2410 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2415 const auto run_routine = [&]()
2418 for(
PCB_SHAPE* shape : items_to_process )
2419 boolean_routine->ProcessShape( *shape );
2421 boolean_routine->Finalize();
2424 boolean_routine = create_routine();
2426 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2433 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2437 items_to_select_on_success.clear();
2439 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2441 for(
PCB_SHAPE* shape : items_to_process )
2444 items_area[shape] = area;
2453 std::sort( items_to_process.begin(), items_to_process.end(),
2456 return items_area[a] > items_area[b];
2460 boolean_routine = create_routine();
2465 for(
BOARD_ITEM* item : items_to_select_on_success )
2471 commit.Push( boolean_routine->GetCommitDescription() );
2473 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2474 frame()->ShowInfoBarMsg( *msg );
2496 std::vector<PCB_TABLECELL*> cells;
2547 for(
EDA_ITEM* eda_item : selCopy )
2549 if( !eda_item->IsBOARD_ITEM() )
2591 if( editFrame && item )
2611 commit = &localCommit;
2634 std::optional<VECTOR2I> oldRefPt;
2639 oldRefPt =
selection.GetReferencePoint();
2665 bool usePcbShapeCenter =
false;
2672 usePcbShapeCenter =
true;
2676 usePcbShapeCenter =
true;
2682 else if( usePcbShapeCenter )
2694 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2695 rotateAngle = -rotateAngle;
2701 viewBBox.
Merge( item->ViewBBox() );
2710 typedef std::numeric_limits<int> coord_limits;
2715 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2716 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2724 if( item->IsBOARD_ITEM() )
2728 board_item->
Rotate( refPt, rotateAngle );
2732 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2739 localCommit.
Push(
_(
"Rotate" ) );
2756 selection.SetReferencePoint( *oldRefPt );
2774 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2807 commit = &localCommit;
2829 int skippedFootprints = 0;
2836 skippedFootprints++;
2844 switch( item->Type() )
2847 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2851 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2856 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2866 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2872 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2876 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2885 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2896 localCommit.
Push(
_(
"Mirror" ) );
2900 frame()->ShowInfoBarMsg(
_(
"Footprints cannot be mirrored. Use Flip to move them to "
2901 "the other side of the board." ) );
2931 commit = &localCommit;
2945 auto setJustify = [&](
EDA_TEXT* aTextItem )
2960 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2969 if( !localCommit.
Empty() )
2972 localCommit.
Push(
_(
"Left Justify" ) );
2974 localCommit.
Push(
_(
"Center Justify" ) );
2976 localCommit.
Push(
_(
"Right Justify" ) );
3006 commit = &localCommit;
3023 std::optional<VECTOR2I> oldRefPt;
3026 oldRefPt =
selection.GetReferencePoint();
3056 if( !item->IsBOARD_ITEM() )
3063 boardItem->
Flip( refPt, flipDirection );
3067 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
3073 localCommit.
Push(
_(
"Change Side / Flip" ) );
3089 selection.SetReferencePoint( *oldRefPt );
3101 int commitFlags = 0;
3106 int itemsDeleted = 0;
3107 int fieldsHidden = 0;
3108 int fieldsAlreadyHidden = 0;
3112 if( !item->IsBOARD_ITEM() )
3118 switch( item->Type() )
3124 wxASSERT( parentFP );
3125 commit.
Modify( parentFP );
3134 fieldsAlreadyHidden++;
3137 getView()->Update( parentFP );
3154 commit.
Remove( board_item );
3160 commit.
Modify( board_item );
3161 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
3173 commit.
Remove( board_item );
3180 commit.
Remove( board_item );
3190 if( !aIsCut && aItems.
GetSize() == 1 )
3193 ZONE* zone =
static_cast<ZONE*
>( board_item );
3195 int outlineIdx, holeIdx;
3216 commit.
Remove( board_item );
3227 commit.Push(
_(
"Delete" ), commitFlags );
3235 commit.
Remove( board_item );
3243 commit.
Remove( board_item );
3252 if( enteredGroup && enteredGroup->
GetItems().empty() )
3257 commit.
Push(
_(
"Cut" ), commitFlags );
3259 else if( itemsDeleted == 0 )
3261 if( fieldsHidden == 1 )
3262 commit.
Push(
_(
"Hide Field" ), commitFlags );
3263 else if( fieldsHidden > 1 )
3264 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3265 else if( fieldsAlreadyHidden > 0 )
3266 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3270 commit.
Push(
_(
"Delete" ), commitFlags );
3281 std::vector<BOARD_ITEM*> lockedItems;
3299 const bool hadInitialSelection = !
m_selectionTool->GetSelection().Empty();
3314 if( hadInitialSelection && selectionCopy.
Empty() )
3344 if( selectionCopy.
Empty() )
3392 if( ret == wxID_OK )
3400 selCenter += translation;
3402 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3403 rotation = -rotation;
3407 if( !item->IsBOARD_ITEM() )
3415 boardItem->
Move( translation );
3417 switch( rotationAnchor )
3423 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3428 getView()->Update( boardItem );
3431 commit.
Push(
_(
"Move Exactly" ) );
3487 std::vector<BOARD_ITEM*> new_items;
3494 if( !item->IsBOARD_ITEM() )
3506 switch( orig_item->
Type() )
3526 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3528 dupe_item = orig_item->
Duplicate(
true, &commit );
3539 new_items.push_back( dupe_item );
3540 commit.
Add( dupe_item );
3550 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3552 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3558 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3565 new_items.push_back( dupe_item );
3566 commit.
Add( dupe_item );
3575 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3581 new_items.push_back( aItem );
3582 commit.
Add( aItem );
3587 new_items.push_back( dupe_item );
3588 commit.
Add( dupe_item );
3600 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3606 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3610 commit.
Push(
_(
"Duplicate" ) );
3628 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3630 switch( aCollector[i]->Type() )
3634 default: aCollector.
Remove( i );
break;
3659 commit = &localCommit;
3663 switch( item->Type() )
3673 if( !
pad.CanHaveNumber() )
3677 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3682 pad.SetNumber( *newNumber );
3691 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3696 text.SetText( *newText );
3708 commit->
Push(
_(
"Increment" ) );
3716 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3718 if( aCollector[i]->Type() !=
PCB_PAD_T )
3726 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3737 if( aSelection.
Empty() )
3761 BOX2I nonFieldsBBox;
3765 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3766 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3781 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3785 std::optional<VECTOR2I> pickedPoint;
3795 const auto setPickerLayerSet =
3802 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3810 setPickerLayerSet();
3813 [&](
const VECTOR2D& aPoint ) ->
bool
3815 pickedPoint = aPoint;
3817 if( !aSuccessMessage.empty() )
3839 if( !aCanceledMessage.empty() )
3851 [&](
const int& aFinalState )
3870 setPickerLayerSet();
3873 evt->SetPassEvent();
3884 canvas()->SetStatusPopup(
nullptr );
3888 aReferencePoint = *pickedPoint;
3890 return pickedPoint.has_value();
3898 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3901 frame()->PushTool( selectReferencePoint );
3918 std::vector<BOARD_ITEM*> items;
3922 if( item->IsBOARD_ITEM() )
3923 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3930 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3931 _(
"Copy canceled" ), refPoint ) )
3933 frame()->PopTool( selectReferencePoint );
3942 selection.SetReferencePoint( refPoint );
3946 frame()->SetStatusText(
_(
"Selection copied" ) );
3949 frame()->PopTool( selectReferencePoint );
3969 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3971 switch( aItem.Type() )
3983 return text.GetShownText(
true );
3997 for(
int row = 0; row <
table.GetRowCount(); ++row )
3999 for(
int col = 0; col <
table.GetColCount(); ++col )
4004 if( col <
table.GetColCount() - 1 )
4010 if( row <
table.GetRowCount() - 1 )
4021 return wxEmptyString;
4024 wxArrayString itemTexts;
4028 if( item->IsBOARD_ITEM() )
4031 wxString itemText = getItemText( *boardItem );
4033 itemText.Trim(
false ).Trim(
true );
4035 if( !itemText.IsEmpty() )
4037 itemTexts.Add( std::move( itemText ) );
4043 if( !itemTexts.empty() )
4045 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
4070 board()->BuildConnectivity();
4072 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
Manage TOOL_ACTION objects.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
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.
Information pertinent to a Pcbnew printed circuit board.
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 toggleExcludeFromBOM
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 toggleExcludeFromPosFiles
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 bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
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.
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
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