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(
"Position" ) );
155 auto notMovingCondition = [](
const SELECTION& aSelection )
157 return aSelection.Empty() || !aSelection.Front()->IsMoving();
169 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
171 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
186 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
193 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
200 auto canAddCornerCondition = [](
const SELECTION& aSelection )
202 const EDA_ITEM* item = aSelection.Front();
207 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
209 const EDA_ITEM* item = aSelection.Front();
214 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
280 for(
const EDA_ITEM* it : aSelection )
293 if( units.size() < 2 )
296 const wxString& padNum =
pad->GetNumber();
297 bool inAnyUnit =
false;
299 for(
const auto& u : units )
301 for(
const auto& pnum : u.m_pins )
319 else if( single != fp )
330 std::unordered_set<wxString> padNums;
332 for(
const EDA_ITEM* it : aSelection )
339 if(
pad->GetParentFootprint() != aFootprint )
342 padNums.insert(
pad->GetNumber() );
351 const std::unordered_set<wxString>& aSelPadNums )
353 std::vector<int> indices;
357 for(
size_t i = 0; i < units.size(); ++i )
361 for(
const auto& pn : units[i].m_pins )
363 if( aSelPadNums.count( pn ) )
371 indices.push_back(
static_cast<int>( i ) );
381 if( aUnitIndices.empty() )
385 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
387 for(
int idx : aUnitIndices )
389 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
400 std::vector<int> targets;
403 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
405 for(
size_t i = 0; i < units.size(); ++i )
407 if(
static_cast<int>( i ) == aSourceIdx )
410 if( units[i].m_pins.size() != pinCount )
413 targets.push_back(
static_cast<int>( i ) );
443 if( unitsHit.size() != 1 )
446 const int sourceIdx = unitsHit.front();
449 for(
int idx : targets )
452 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
460 int id = aEvent.GetId();
475 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
491 auto menu = std::make_shared<GATE_SWAP_MENU>();
492 menu->SetTool( aTool );
503 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
506 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
511 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
514 subMenu->Evaluate( aSel );
515 return subMenu->GetMenuItemCount() > 0;
518 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
521 subMenu->Evaluate( aSel );
522 return subMenu->GetMenuItemCount() > 0;
526 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
537 if( unitsHit.size() != 1 )
540 const int sourceIdx = unitsHit.front();
542 return !targets.empty();
546 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
557 if( unitsHit.size() < 2 )
563 auto propertiesCondition = [
this](
const SELECTION& aSel )
565 if( aSel.GetSize() == 0 )
579 if( aSel.GetSize() == 1 )
591 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
596 auto canMirror = [
this](
const SELECTION& aSelection )
609 auto singleFootprintCondition =
612 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
614 bool foundFirst =
false;
630 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
632 return frame()->ToolStackIsEmpty();
635 auto notMovingCondition = [](
const SELECTION& aSelection )
637 return aSelection.Empty() || !aSelection.Front()->IsMoving();
640 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
642 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
645 auto isSkippable = [
this](
const SELECTION& aSelection )
651 && notMovingCondition && !inFootprintEditor;
700 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
707 && !inFootprintEditor );
719 menu.AddSeparator( 100 );
720 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
721 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
723 menu.AddSeparator( 150 );
736 menu.AddSeparator( 150 );
752 wxString footprintName;
753 wxArrayString fplist;
758 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
768 footprintName.Trim(
true );
769 footprintName.Trim(
false );
771 if( !footprintName.IsEmpty() )
775 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
875 std::vector<PCB_TRACK*> tracks;
876 std::vector<PCB_TRACK*> vias;
877 std::vector<FOOTPRINT*> footprints;
880 const auto gatherItemsByType = [&]()
887 vias.push_back( track );
889 tracks.push_back( track );
904 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
910 else if( tracks.size() || vias.size() )
937 if( tracks.size() == 2 && vias.size() == 0 )
939 if( connected( tracks[0], tracks[1]->GetStart() )
940 || connected( tracks[0], tracks[1]->GetEnd() ) )
942 aCollector.
Remove( tracks[1] );
945 else if( tracks.size() == 2 && vias.size() == 1 )
947 if( connected( tracks[0], vias[0]->GetPosition() )
948 && connected( tracks[1], vias[0]->GetPosition() ) )
950 aCollector.
Remove( tracks[0] );
951 aCollector.
Remove( tracks[1] );
989 wxString msg = wxString::Format(
_(
"Unable to resize arc tracks of %s or greater." ),
991 frame()->ShowInfoBarError( msg );
1004 bool restore_state =
false;
1018 tanStart.
A = *tanIntersect;
1020 tanEnd.
A = *tanIntersect;
1023 std::set<PCB_TRACK*> addedTracks;
1025 auto getUniqueTrackAtAnchorCollinear = [&](
const VECTOR2I& aAnchor,
const SEG& aCollinearSeg ) ->
PCB_TRACK*
1027 std::shared_ptr<CONNECTIVITY_DATA> conn =
board()->GetConnectivity();
1030 int allowedDeviation = theArc->
GetWidth();
1032 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1034 for(
int i = 0; i < 3; i++ )
1036 itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
baseConnectedTypes, allowedDeviation );
1037 allowedDeviation /= 2;
1039 if( itemsOnAnchor.size() == 1 )
1045 if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() ==
PCB_TRACE_T )
1047 track =
static_cast<PCB_TRACK*
>( itemsOnAnchor.front() );
1053 if( trackSeg.
Angle( aCollinearSeg ) > maxTangentDeviation )
1061 track->
SetEnd( aAnchor );
1070 addedTracks.insert( track );
1076 PCB_TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->
GetStart(), tanStart );
1077 PCB_TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->
GetEnd(), tanEnd );
1082 tanStart.
B = trackOnStart->
GetEnd();
1088 tanEnd.
B = trackOnEnd->
GetEnd();
1092 if( tanIntersect = tanStart.
IntersectLines( tanEnd ); !tanIntersect )
1095 auto isTrackStartClosestToArcStart = [&](
PCB_TRACK* aTrack ) ->
bool
1097 double trackStartToArcStart = aTrack->GetStart().Distance( theArc->
GetStart() );
1098 double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->
GetStart() );
1100 return trackStartToArcStart < trackEndToArcStart;
1103 bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
1104 bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
1135 if( ( aPointA - *tanIntersect ).EuclideanNorm() > ( aPointB - *tanIntersect ).EuclideanNorm() )
1146 VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.
A, tanStart.
B );
1147 VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.
A, tanEnd.
B );
1148 VECTOR2I tempTangentPoint = tanEndPoint;
1150 if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
1151 tempTangentPoint = tanStartPoint;
1157 SEG cSegTanStart( maxTanPtStart, *tanIntersect );
1158 SEG cSegTanEnd( maxTanPtEnd, *tanIntersect );
1159 SEG cSegChord( maxTanPtStart, maxTanPtEnd );
1161 int cSegTanStartSide = cSegTanStart.
Side( theArc->
GetMid() );
1162 int cSegTanEndSide = cSegTanEnd.
Side( theArc->
GetMid() );
1163 int cSegChordSide = cSegChord.
Side( theArc->
GetMid() );
1165 bool eatFirstMouseUp =
true;
1176 std::vector<VECTOR2I> possiblePoints;
1183 for(
const VECTOR2I& candidate : possiblePoints )
1185 if( ( candidate -
m_cursor ).SquaredEuclideanNorm() < ( closest -
m_cursor ).SquaredEuclideanNorm() )
1187 closest = candidate;
1211 theArc->
SetEnd( newEnd );
1212 theArc->
SetMid( newMid );
1214 if( isStartTrackOnStartPt )
1215 trackOnStart->
SetStart( newStart );
1217 trackOnStart->
SetEnd( newStart );
1219 if( isEndTrackOnStartPt )
1222 trackOnEnd->
SetEnd( newEnd );
1225 getView()->Update( trackOnStart );
1226 getView()->Update( trackOnEnd );
1230 if( evt->IsMotion() || evt->IsDrag(
BUT_LEFT ) )
1232 eatFirstMouseUp =
false;
1234 else if( evt->IsCancelInteractive() || evt->IsActivate() )
1236 restore_state =
true;
1241 restore_state =
true;
1249 eatFirstMouseUp =
false;
1261 if( isStartTrackOnStartPt )
1262 newStart = trackOnStart->
GetEnd();
1264 if( isEndTrackOnStartPt )
1265 newEnd = trackOnEnd->
GetEnd();
1269 if( trackOnStart->
GetLength() <= maxLengthIU )
1271 if( addedTracks.count( trackOnStart ) )
1273 getView()->Remove( trackOnStart );
1274 addedTracks.erase( trackOnStart );
1275 delete trackOnStart;
1279 commit.
Remove( trackOnStart );
1285 if( trackOnEnd->
GetLength() <= maxLengthIU )
1287 if( addedTracks.count( trackOnEnd ) )
1289 getView()->Remove( trackOnEnd );
1290 addedTracks.erase( trackOnEnd );
1295 commit.
Remove( trackOnEnd );
1298 theArc->
SetEnd( newEnd );
1307 commit.
Add( added );
1314 commit.
Push(
_(
"Drag Arc Track" ) );
1326 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1331 aCollector.
Remove( item );
1359 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1360 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1363 via->SetDrill( new_drill );
1371 wxCHECK( track, 0 );
1375 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1380 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1405 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1410 aCollector.
Remove( item );
1425 if( newLayer == origLayer )
1436 wxCHECK( track, 0 );
1444 commit.
Push(
_(
"Edit Track Layer" ) );
1461 static int filletRadius = 0;
1467 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1472 aCollector.
Remove( item );
1480 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1496 bool t1Start =
true;
1497 bool t2Start =
true;
1500 std::vector<FILLET_OP> filletOperations;
1501 bool operationPerformedOnAtLeastOne =
false;
1502 bool didOneAttemptFail =
false;
1503 std::set<PCB_TRACK*> processedTracks;
1505 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1507 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1509 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1513 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1519 if( processedTracks.find( trackOther ) == processedTracks.end() )
1521 if( itemsOnAnchor.size() == 1 )
1524 filletOp.t1 = aTrack;
1525 filletOp.t2 = trackOther;
1526 filletOp.t1Start = aStartPoint;
1527 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1528 filletOperations.push_back( filletOp );
1534 didOneAttemptFail =
true;
1548 processFilletOp( track,
true );
1549 processFilletOp( track,
false );
1551 processedTracks.insert( track );
1557 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1559 for( FILLET_OP filletOp : filletOperations )
1567 if( trackOnStart && trackOnEnd )
1570 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1578 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1581 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1583 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1588 aPointToSet.
x = aVecToTest.x;
1589 aPointToSet.
y = aVecToTest.y;
1597 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1598 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1600 didOneAttemptFail =
true;
1604 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1605 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1607 didOneAttemptFail =
true;
1619 itemsToAddToSelection.push_back( tArc );
1624 if( filletOp.t1Start )
1627 track1->
SetEnd( t1newPoint );
1629 if( filletOp.t2Start )
1632 track2->
SetEnd( t2newPoint );
1634 operationPerformedOnAtLeastOne =
true;
1638 commit.
Push(
_(
"Fillet Tracks" ) );
1641 for(
BOARD_ITEM* item : itemsToAddToSelection )
1644 if( !operationPerformedOnAtLeastOne )
1645 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1646 else if( didOneAttemptFail )
1647 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1667 return std::nullopt;
1671 return aPersitentRadius;
1683 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1690 _(
"Add slots in acute corners" ),
1692 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1699 return std::nullopt;
1701 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1702 wxCHECK( results.size() == 2, std::nullopt );
1706 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1707 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1709 catch(
const std::bad_variant_access& )
1712 return std::nullopt;
1715 return s_dogBoneParams;
1729 const int default_setback =
pcbIUScale.mmToIU( 1 );
1731 static CHAMFER_PARAMS params{ default_setback, default_setback };
1733 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1736 return std::nullopt;
1738 params.m_chamfer_setback_a = dlg.
GetValue();
1741 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1752 std::vector<VECTOR2I> pts;
1755 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1762 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1764 aCollector.
Remove( item );
1771 std::set<PCB_SHAPE*> lines_to_add;
1772 std::vector<PCB_SHAPE*> items_to_remove;
1776 std::vector<VECTOR2I> pts;
1783 items_to_remove.push_back( graphic );
1786 pts.emplace_back( start );
1788 pts.emplace_back(
end );
1794 items_to_remove.push_back( graphic );
1796 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1800 for(
size_t jj = 1; jj < pts.size(); ++jj )
1808 lines_to_add.insert( line );
1811 if( pts.size() > 1 )
1816 line->
SetEnd( pts.front() );
1819 lines_to_add.insert( line );
1827 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1834 else if( segmentCount < 2 )
1836 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1854 for(
PCB_SHAPE* item : items_to_remove )
1865 std::vector<BOARD_ITEM*> items_to_select_on_success;
1868 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1873 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1879 items_to_select_on_success.push_back( &aItem );
1883 bool any_items_created = !lines_to_add.empty();
1884 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1886 any_items_created =
true;
1887 items_to_select_on_success.push_back( aItem.get() );
1888 commit.
Add( aItem.release() );
1891 bool any_items_removed = !items_to_remove.empty();
1892 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1895 any_items_removed =
true;
1896 items_to_deselect_on_success.push_back( &aItem );
1902 item_removal_handler );
1905 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1909 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1910 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1912 if( filletRadiusIU.has_value() )
1914 pairwise_line_routine =
1915 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1922 if( dogboneParams.has_value() )
1924 pairwise_line_routine =
1925 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
1932 if( chamfer_params.has_value() )
1934 pairwise_line_routine =
1935 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
1940 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
1943 if( !pairwise_line_routine )
1954 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1956 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1957 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1959 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1964 for(
BOARD_ITEM* item : items_to_select_on_success )
1965 m_selectionTool->AddItemToSel( item,
true );
1968 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1969 m_selectionTool->RemoveItemFromSel( item,
true );
1971 if( any_items_removed )
1974 if( any_items_created )
1980 commit.Push( pairwise_line_routine->GetCommitDescription() );
1982 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
1983 frame()->ShowInfoBarMsg( *msg );
1994 std::vector<VECTOR2I> pts;
1997 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2001 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
2002 aCollector.
Remove( item );
2006 if( zone->IsTeardropArea() )
2007 aCollector.
Remove( item );
2015 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2024 if( s_toleranceValue <= 0 )
2029 std::vector<PCB_SHAPE*> shapeList;
2033 commit.Modify( item );
2047 zone->HatchBorder();
2051 commit.
Push(
_(
"Simplify Polygons" ) );
2065 std::vector<VECTOR2I> pts;
2068 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2075 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
2077 aCollector.
Remove( item );
2085 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
2094 if( s_toleranceValue <= 0 )
2099 std::vector<PCB_SHAPE*> shapeList;
2105 shapeList.push_back( shape );
2106 commit.Modify( shape );
2112 commit.Push(
_(
"Heal Shapes" ) );
2127 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2131 static const std::vector<KICAD_T> polygonBooleanTypes = {
2137 if( !item->
IsType( polygonBooleanTypes ) )
2138 aCollector.
Remove( item );
2147 std::vector<PCB_SHAPE*> items_to_process;
2151 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2156 if( item == last_item )
2157 std::swap( items_to_process.back(), items_to_process.front() );
2163 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2165 commit.Modify( &aItem );
2168 std::vector<BOARD_ITEM*> items_to_select_on_success;
2170 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2172 items_to_select_on_success.push_back( aItem.get() );
2173 commit.Add( aItem.release() );
2176 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2178 commit.Remove( &aItem );
2183 item_removal_handler );
2186 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2188 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2195 wxCHECK(
model,
nullptr );
2199 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2203 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2207 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2212 const auto run_routine = [&]()
2215 for(
PCB_SHAPE* shape : items_to_process )
2216 boolean_routine->ProcessShape( *shape );
2218 boolean_routine->Finalize();
2221 boolean_routine = create_routine();
2223 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2230 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2234 items_to_select_on_success.clear();
2236 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2238 for(
PCB_SHAPE* shape : items_to_process )
2241 items_area[shape] = area;
2250 std::sort( items_to_process.begin(), items_to_process.end(),
2253 return items_area[a] > items_area[b];
2257 boolean_routine = create_routine();
2262 for(
BOARD_ITEM* item : items_to_select_on_success )
2268 commit.Push( boolean_routine->GetCommitDescription() );
2270 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2271 frame()->ShowInfoBarMsg( *msg );
2293 std::vector<PCB_TABLECELL*> cells;
2344 for(
EDA_ITEM* eda_item : selCopy )
2346 if( !eda_item->IsBOARD_ITEM() )
2386 if( editFrame && item )
2406 commit = &localCommit;
2427 std::optional<VECTOR2I> oldRefPt;
2432 oldRefPt =
selection.GetReferencePoint();
2456 bool usePcbShapeCenter =
false;
2463 usePcbShapeCenter =
true;
2467 usePcbShapeCenter =
true;
2473 else if( usePcbShapeCenter )
2485 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2486 rotateAngle = -rotateAngle;
2492 viewBBox.
Merge( item->ViewBBox() );
2501 typedef std::numeric_limits<int> coord_limits;
2506 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2507 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2515 if( item->IsBOARD_ITEM() )
2519 board_item->
Rotate( refPt, rotateAngle );
2523 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2530 localCommit.
Push(
_(
"Rotate" ) );
2547 selection.SetReferencePoint( *oldRefPt );
2565 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2598 commit = &localCommit;
2626 switch( item->Type() )
2629 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2633 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2638 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2650 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2656 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2660 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2669 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2680 localCommit.
Push(
_(
"Mirror" ) );
2709 commit = &localCommit;
2721 auto setJustify = [&](
EDA_TEXT* aTextItem )
2736 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2745 if( !localCommit.
Empty() )
2748 localCommit.
Push(
_(
"Left Justify" ) );
2750 localCommit.
Push(
_(
"Center Justify" ) );
2752 localCommit.
Push(
_(
"Right Justify" ) );
2782 commit = &localCommit;
2797 std::optional<VECTOR2I> oldRefPt;
2800 oldRefPt =
selection.GetReferencePoint();
2826 if( !item->IsBOARD_ITEM() )
2833 boardItem->
Flip( refPt, flipDirection );
2837 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2843 localCommit.
Push(
_(
"Change Side / Flip" ) );
2859 selection.SetReferencePoint( *oldRefPt );
2871 int commitFlags = 0;
2876 int itemsDeleted = 0;
2877 int fieldsHidden = 0;
2878 int fieldsAlreadyHidden = 0;
2882 if( !item->IsBOARD_ITEM() )
2888 switch( item->Type() )
2894 wxASSERT( parentFP );
2895 commit.
Modify( parentFP );
2904 fieldsAlreadyHidden++;
2907 getView()->Update( parentFP );
2924 commit.
Remove( board_item );
2930 commit.
Modify( board_item );
2931 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2943 commit.
Remove( board_item );
2950 commit.
Remove( board_item );
2960 if( !aIsCut && aItems.
GetSize() == 1 )
2963 ZONE* zone =
static_cast<ZONE*
>( board_item );
2965 int outlineIdx, holeIdx;
2986 commit.
Remove( board_item );
2997 commit.Push(
_(
"Delete" ), commitFlags );
3005 commit.
Remove( board_item );
3013 commit.
Remove( board_item );
3022 if( enteredGroup && enteredGroup->
GetItems().empty() )
3027 commit.
Push(
_(
"Cut" ), commitFlags );
3029 else if( itemsDeleted == 0 )
3031 if( fieldsHidden == 1 )
3032 commit.
Push(
_(
"Hide Field" ), commitFlags );
3033 else if( fieldsHidden > 1 )
3034 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3035 else if( fieldsAlreadyHidden > 0 )
3036 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3040 commit.
Push(
_(
"Delete" ), commitFlags );
3051 std::vector<BOARD_ITEM*> lockedItems;
3143 if( ret == wxID_OK )
3151 selCenter += translation;
3153 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3154 rotation = -rotation;
3158 if( !item->IsBOARD_ITEM() )
3166 boardItem->
Move( translation );
3168 switch( rotationAnchor )
3174 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3179 getView()->Update( boardItem );
3182 commit.
Push(
_(
"Move Exactly" ) );
3238 std::vector<BOARD_ITEM*> new_items;
3245 if( !item->IsBOARD_ITEM() )
3257 switch( orig_item->
Type() )
3277 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3279 dupe_item = orig_item->
Duplicate(
true, &commit );
3285 new_items.push_back( dupe_item );
3286 commit.
Add( dupe_item );
3296 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3298 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3304 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3311 new_items.push_back( dupe_item );
3312 commit.
Add( dupe_item );
3321 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit );
3327 new_items.push_back( aItem );
3328 commit.
Add( aItem );
3333 new_items.push_back( dupe_item );
3334 commit.
Add( dupe_item );
3346 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3352 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3356 commit.
Push(
_(
"Duplicate" ) );
3374 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3376 switch( aCollector[i]->Type() )
3380 default: aCollector.
Remove( i );
break;
3403 commit = &localCommit;
3407 switch( item->Type() )
3417 if( !
pad.CanHaveNumber() )
3421 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3426 pad.SetNumber( *newNumber );
3435 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3440 text.SetText( *newText );
3452 commit->
Push(
_(
"Increment" ) );
3460 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3462 if( aCollector[i]->Type() !=
PCB_PAD_T )
3470 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3481 if( aSelection.
Empty() )
3505 BOX2I nonFieldsBBox;
3509 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3510 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3525 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3529 std::optional<VECTOR2I> pickedPoint;
3539 const auto setPickerLayerSet =
3546 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3554 setPickerLayerSet();
3557 [&](
const VECTOR2D& aPoint ) ->
bool
3559 pickedPoint = aPoint;
3561 if( !aSuccessMessage.empty() )
3583 if( !aCanceledMessage.empty() )
3595 [&](
const int& aFinalState )
3614 setPickerLayerSet();
3617 evt->SetPassEvent();
3628 canvas()->SetStatusPopup(
nullptr );
3632 aReferencePoint = *pickedPoint;
3634 return pickedPoint.has_value();
3642 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3645 frame()->PushTool( selectReferencePoint );
3660 std::vector<BOARD_ITEM*> items;
3664 if( item->IsBOARD_ITEM() )
3665 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3672 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3673 _(
"Copy canceled" ), refPoint ) )
3675 frame()->PopTool( selectReferencePoint );
3684 selection.SetReferencePoint( refPoint );
3688 frame()->SetStatusText(
_(
"Selection copied" ) );
3691 frame()->PopTool( selectReferencePoint );
3711 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3713 switch( aItem.Type() )
3725 return text.GetShownText(
true );
3739 for(
int row = 0; row <
table.GetRowCount(); ++row )
3741 for(
int col = 0; col <
table.GetColCount(); ++col )
3746 if( col <
table.GetColCount() - 1 )
3752 if( row <
table.GetRowCount() - 1 )
3763 return wxEmptyString;
3766 wxArrayString itemTexts;
3770 if( item->IsBOARD_ITEM() )
3773 wxString itemText = getItemText( *boardItem );
3775 itemText.Trim(
false ).Trim(
true );
3777 if( !itemText.IsEmpty() )
3779 itemTexts.Add( std::move( itemText ) );
3785 if( !itemTexts.empty() )
3787 SaveClipboard( wxJoin( itemTexts,
'\n',
'\0' ).ToStdString() );
3812 board()->BuildConnectivity();
3814 canvas()->RedrawRatsnest();
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION decrementPrimary
static TOOL_ACTION pickerSubTool
static TOOL_ACTION unselectAll
static TOOL_ACTION decrementSecondary
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
static TOOL_ACTION pasteSpecial
static TOOL_ACTION rightJustify
static TOOL_ACTION pageSettings
static TOOL_ACTION incrementSecondary
static TOOL_ACTION duplicate
static TOOL_ACTION incrementPrimary
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION increment
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION leftJustify
static TOOL_ACTION copyAsText
static TOOL_ACTION refreshPreview
static TOOL_ACTION selectAll
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
static TOOL_ACTION centerJustify
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual BOARD_ITEM * Duplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr) const
Create a copy of this BOARD_ITEM.
void SetLocked(bool aLocked) override
bool IsLocked() const override
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
BOARD_ITEM_CONTAINER * GetParent() const
virtual void Normalize()
Perform any normalization required after a user rotate and/or flip.
virtual void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
Flip this object, i.e.
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
const FOOTPRINTS & Footprints() const
constexpr const Vec & GetPosition() const
constexpr const Vec GetEnd() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr bool IsValid() const
Represent basic circle geometry with utility geometry functions.
VECTOR2I Center
Public to make access simpler.
int Radius
Public to make access simpler.
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Construct this circle such that it is tangent to the given segments and passes through the given poin...
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetBoard(BOARD *aBoard)
int GetCount() const
Return the number of objects in the list.
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Remove a new item from the model.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Add a new item to the model.
@ TABLECELL_PROPS_EDIT_TABLE
enum TABLECELL_PROPS_RETVALUE GetReturnValue()
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false, INFOBAR_MESSAGE_TYPE aType=INFOBAR_MESSAGE_TYPE::GENERIC)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
void DisplayToolMsg(const wxString &msg) override
std::unordered_set< EDA_ITEM * > & GetItems()
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetEnd(const VECTOR2I &aEnd)
void SetWidth(int aWidth)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual bool IsVisible() const
virtual void SetVisible(bool aVisible)
static const TOOL_EVENT SelectedEvent
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
static const TOOL_EVENT UnselectedEvent
Used when the right click button is pressed, or when the select tool is in effect.
static const std::vector< KICAD_T > DraggableItems
A scan list for items that can be dragged.
A handler that is based on a set of callbacks provided by the user of the ITEM_MODIFICATION_ROUTINE.
An interface for classes handling user events controlling the view behavior such as zooming,...
bool IsBOARD_ITEM() const
virtual wxString GetClass() const =0
Return the class name.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllLayersMask()
A collection of nets and the parameters used to route or test these nets.
int GetuViaDiameter() const
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
VECTOR2I GetPosition() const override
void SetDelta(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void FlipPrimitives(FLIP_DIRECTION aFlipDirection)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
void SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
void SetPosition(const VECTOR2I &aPos) override
const VECTOR2I & GetOffset(PCB_LAYER_ID aLayer) const
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
static TOOL_ACTION drag45Degree
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
static TOOL_ACTION layerPrev
static TOOL_ACTION changeTrackWidth
Update selected tracks & vias to the current track & via dimensions.
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
static TOOL_ACTION mirrorH
Mirroring of selected items.
static TOOL_ACTION updateFootprint
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
static TOOL_ACTION pointEditorMoveMidpoint
static TOOL_ACTION getAndPlace
Find an item and start moving.
static TOOL_ACTION routerRouteSelectedFromEnd
static TOOL_ACTION swapPadNets
Swap nets between selected pads/gates (and connected copper)
static TOOL_ACTION properties
Activation of the edit tool.
static TOOL_ACTION editFpInFpEditor
static TOOL_ACTION moveWithReference
move with a reference point
static TOOL_ACTION changeTrackLayerPrev
static TOOL_ACTION swap
Swapping of selected items.
static TOOL_ACTION routerAutorouteSelected
static TOOL_ACTION moveExact
Activation of the exact move tool.
static TOOL_ACTION intersectPolygons
Intersection of multiple polygons.
static TOOL_ACTION pointEditorMoveCorner
static TOOL_ACTION genRemove
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
static TOOL_ACTION assignNetClass
static TOOL_ACTION packAndMoveFootprints
Pack and start moving selected footprints.
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
static TOOL_ACTION healShapes
Connect selected shapes, possibly extending or cutting them, or adding extra geometry.
static TOOL_ACTION dragFreeAngle
static TOOL_ACTION inspectClearance
static TOOL_ACTION updateLocalRatsnest
static TOOL_ACTION updateFootprints
static TOOL_ACTION deleteFull
static TOOL_ACTION unrouteSegment
Removes track segment from the selected item to the next segment.
static TOOL_ACTION moveIndividually
move items one-by-one
static TOOL_ACTION changeFootprints
static TOOL_ACTION chamferLines
Chamfer (i.e. adds a straight line) all selected straight lines by a user defined setback.
static TOOL_ACTION dogboneCorners
Add "dogbone" corners to selected lines to allow routing with a cutter radius.
static TOOL_ACTION filletTracks
Fillet (i.e. adds an arc tangent to) all selected straight tracks by a user defined radius.
static TOOL_ACTION simplifyPolygons
Simplify polygon outlines.
static TOOL_ACTION interactiveOffsetTool
static TOOL_ACTION footprintProperties
static TOOL_ACTION pointEditorChamferCorner
static TOOL_ACTION filletLines
Fillet (i.e. adds an arc tangent to) all selected straight lines by a user defined radius.
static TOOL_ACTION changeFootprint
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
static TOOL_ACTION pointEditorRemoveCorner
static TOOL_ACTION positionRelative
static TOOL_ACTION move
move or drag an item
static TOOL_ACTION mirrorV
static TOOL_ACTION mergePolygons
Merge multiple polygons into a single polygon.
static TOOL_ACTION subtractPolygons
Subtract polygons from other polygons.
static TOOL_ACTION changeTrackLayerNext
static TOOL_ACTION flip
Flipping of selected objects.
static TOOL_ACTION pointEditorAddCorner
static TOOL_ACTION editVertices
Edit polygon vertices in a table.
static TOOL_ACTION swapGateNets
static TOOL_ACTION layerNext
static TOOL_ACTION extendLines
Extend selected lines to meet at a point.
static TOOL_ACTION routerRouteSelected
static TOOL_ACTION rotateCw
Rotation of selected objects.
static TOOL_ACTION rotateCcw
virtual double GetLength() const override
Return the length of the arc track.
void SetMid(const VECTOR2I &aMid)
EDA_ANGLE GetAngle() const
const VECTOR2I & GetMid() const
virtual VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Common, abstract interface for edit frames.
virtual void OnEditItemRequest(BOARD_ITEM *aItem)
Install the corresponding dialog editor for the given item.
void OpenVertexEditor(BOARD_ITEM *aItem)
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
static const TOOL_EVENT & SnappingModeChangedByKeyEvent()
Hotkey feedback.
A set of BOARD_ITEMs (i.e., without duplicates).
Tool that displays edit points allowing to modify items by dragging the points.
bool CanRemoveCorner(const SELECTION &aSelection)
Condition to display "Remove Corner" context menu entry.
static bool CanChamferCorner(const EDA_ITEM &aItem)
Check if a corner of the given item can be chamfered (zones, polys only).
static bool CanAddCorner(const EDA_ITEM &aItem)
Check if a corner can be added to the given item (zones, polys, segments, arcs).
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
int GetWidth() const override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
void SetHasSolderMask(bool aVal)
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
void SetEnd(const VECTOR2I &aEnd)
bool HasSolderMask() const
void SetStart(const VECTOR2I &aStart)
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
std::optional< int > GetLocalSolderMaskMargin() const
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Return STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if point if near (dist = m...
virtual void SetWidth(int aWidth)
virtual int GetWidth() const
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
SEG PerpendicularSeg(const VECTOR2I &aP) const
Compute a segment perpendicular to this one, passing through point aP.
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
EDA_ANGLE Angle(const SEG &aOther) const
Determine the smallest angle between two segments.
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
virtual unsigned int GetSize() const override
Return the number of stored items.
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
int Size() const
Returns the number of selected parts.
std::deque< EDA_ITEM * > & Items()
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
bool HasReferencePoint() const
size_t CountType(KICAD_T aType) const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void SimplifyOutlines(int aMaxError=0)
Simplifies the lines in the polyset.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Heuristically increment a string's n'th part from the right.
void SetSkipIOSQXZ(bool aSkip)
If a alphabetic part is found, skip the letters I, O, S, Q, X, Z.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
VECTOR2_TRAITS< int32_t >::extended_type extended_type
A dialog like WX_UNIT_ENTRY_DIALOG, but with multiple entries.
std::vector< RESULT > GetValues() const
Returns the values in the order they were added.
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
int GetValue()
Return the value in internal units.
Handle a list of polygons defining a copper zone.
bool UnFill()
Removes the zone filling.
bool HitTestCutout(const VECTOR2I &aRefPos, int *aOutlineIdx=nullptr, int *aHoleIdx=nullptr) const
Test if the given point is contained within a cutout of the zone.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
bool IsTeardropArea() const
bool SaveClipboard(const std::string &aTextUTF8)
Store information to the system clipboard.
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static constexpr EDA_ANGLE ANGLE_180
#define IS_NEW
New item, just created.
#define STRUCT_DELETED
flag indication structures to be erased
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
void ConnectBoardShapes(std::vector< PCB_SHAPE * > &aShapeList, int aChainingEpsilon)
Connects shapes to each other, making continious contours (adjacent shapes will have a common vertex)...
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
@ LAYER_SCHEMATIC_DRAWINGSHEET
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Class to handle a set of BOARD_ITEMs.
@ ID_POPUP_PCB_SWAP_UNIT_LAST
@ ID_POPUP_PCB_SWAP_UNIT_BASE
std::vector< EDA_ITEM * > EDA_ITEMS
std::optional< VECTOR2I > OPT_VECTOR2I
std::function< bool(const SELECTION &)> SELECTION_CONDITION
Functor type that checks a specific condition for selected items.
Parameters that define a simple chamfer operation.
const VECTOR2I CalcArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Return the middle point of an arc, half-way between aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
@ PCB_SHAPE_LOCATE_CIRCLE_T
@ PCB_SHAPE_LOCATE_SEGMENT_T
@ PCB_SHAPE_LOCATE_RECT_T
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_SHAPE_LOCATE_BEZIER_T
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_SHAPE_LOCATE_POLY_T
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_POINT_T
class PCB_POINT, a 0-dimensional point
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D