69using namespace std::placeholders;
71#include <wx/hyperlink.h>
97 ZONE* zone =
static_cast<ZONE*
>( aItem );
110 if( aSelection.
GetSize() != 1 )
166 else if( item->IsType( EDIT_TOOL::MirrorableItems ) )
196 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
199 menu->SetUntranslatedTitle(
_HKI(
"Mirror / Rotate" ) );
201 auto canMirror = [](
const SELECTION& aSelection )
220 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
223 menu->SetUntranslatedTitle(
_HKI(
"Routing" ) );
225 auto notMovingCondition = [](
const SELECTION& aSelection )
227 return aSelection.Empty() || !aSelection.Front()->IsMoving();
245 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
248 menu->SetUntranslatedTitle(
_HKI(
"Position" ) );
250 auto notMovingCondition = [](
const SELECTION& aSelection )
252 return aSelection.Empty() || !aSelection.Front()->IsMoving();
266 auto menu = std::make_shared<CONDITIONAL_MENU>( aTool );
268 menu->SetUntranslatedTitle(
_HKI(
"Shape Modification" ) );
283 auto hasCornerCondition = [aTool](
const SELECTION& aSelection )
290 auto hasMidpointCondition = [aTool](
const SELECTION& aSelection )
297 auto canAddCornerCondition = [](
const SELECTION& aSelection )
299 const EDA_ITEM* item = aSelection.Front();
304 auto canChamferCornerCondition = [](
const SELECTION& aSelection )
306 const EDA_ITEM* item = aSelection.Front();
311 auto canRemoveCornerCondition = [aTool](
const SELECTION& aSelection )
377 for(
const EDA_ITEM* it : aSelection )
390 if( units.size() < 2 )
393 const wxString& padNum =
pad->GetNumber();
394 bool inAnyUnit =
false;
396 for(
const auto& u : units )
398 for(
const auto& pnum : u.m_pins )
416 else if( single != fp )
427 std::unordered_set<wxString> padNums;
429 for(
const EDA_ITEM* it : aSelection )
436 if(
pad->GetParentFootprint() != aFootprint )
439 padNums.insert(
pad->GetNumber() );
448 const std::unordered_set<wxString>& aSelPadNums )
450 std::vector<int> indices;
454 for(
size_t i = 0; i < units.size(); ++i )
458 for(
const auto& pn : units[i].m_pins )
460 if( aSelPadNums.count( pn ) )
468 indices.push_back(
static_cast<int>( i ) );
478 if( aUnitIndices.empty() )
482 const size_t cnt = units[
static_cast<size_t>( aUnitIndices.front() )].m_pins.size();
484 for(
int idx : aUnitIndices )
486 if( units[
static_cast<size_t>( idx )].m_pins.size() != cnt )
497 std::vector<int> targets;
500 const size_t pinCount = units[
static_cast<size_t>( aSourceIdx )].m_pins.size();
502 for(
size_t i = 0; i < units.size(); ++i )
504 if(
static_cast<int>( i ) == aSourceIdx )
507 if( units[i].m_pins.size() != pinCount )
510 targets.push_back(
static_cast<int>( i ) );
540 if( unitsHit.size() != 1 )
543 const int sourceIdx = unitsHit.front();
546 for(
int idx : targets )
549 label.Printf(
_(
"Swap with %s" ), fp->
GetUnitInfo()[
static_cast<size_t>( idx )].m_unitName );
557 int id = aEvent.GetId();
572 if( targetIdx < 0 || targetIdx >=
static_cast<int>( units.size() ) )
588 auto menu = std::make_shared<GATE_SWAP_MENU>();
589 menu->SetTool( aTool );
603 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
609 m_selectionTool->GetToolMenu().RegisterSubMenu( shapeModificationSubMenu );
614 auto fpAttributesMenu = std::make_shared<CONDITIONAL_MENU>(
this );
615 fpAttributesMenu->SetUntranslatedTitle(
_HKI(
"Attributes" ) );
620 auto positioningToolsCondition = [
this](
const SELECTION& aSel )
623 subMenu->Evaluate( aSel );
624 return subMenu->GetMenuItemCount() > 0;
627 auto shapeModificationCondition = [
this](
const SELECTION& aSel )
630 subMenu->Evaluate( aSel );
631 return subMenu->GetMenuItemCount() > 0;
635 auto gateSwapSingleUnitOnOneFootprint = [](
const SELECTION& aSelection )
646 if( unitsHit.size() != 1 )
649 const int sourceIdx = unitsHit.front();
651 return !targets.empty();
655 auto gateSwapMultipleUnitsOnOneFootprint = [](
const SELECTION& aSelection )
666 if( unitsHit.size() < 2 )
672 auto propertiesCondition = [
this](
const SELECTION& aSel )
674 if( aSel.GetSize() == 0 )
688 if( aSel.GetSize() == 1 )
700 auto inFootprintEditor = [
this](
const SELECTION& aSelection )
705 auto canMirror = [
this](
const SELECTION& aSelection )
720 auto singleFootprintCondition =
723 auto multipleFootprintsCondition = [](
const SELECTION& aSelection )
725 bool foundFirst =
false;
741 auto excludeFromBOMCond = [
this](
const SELECTION& aSel )
743 wxString variantName;
744 int checked = 0, unchecked = 0;
747 variantName =
board->GetCurrentVariant();
753 if(
static_cast<const FOOTPRINT*
>( item )->GetExcludedFromBOMForVariant( variantName ) )
760 return checked > 0 && unchecked == 0;
763 auto excludeFromPosFilesCond = [
this](
const SELECTION& aSel )
765 wxString variantName;
766 int checked = 0, unchecked = 0;
769 variantName =
board->GetCurrentVariant();
775 if(
static_cast<const FOOTPRINT*
>( item )->GetExcludedFromPosFilesForVariant( variantName ) )
782 return checked > 0 && unchecked == 0;
785 auto noActiveToolCondition = [
this](
const SELECTION& aSelection )
787 return frame()->ToolStackIsEmpty();
790 auto notMovingCondition = [](
const SELECTION& aSelection )
792 return aSelection.Empty() || !aSelection.Front()->IsMoving();
795 auto noItemsCondition = [
this](
const SELECTION& aSelections ) ->
bool
797 return frame()->GetBoard() && !
frame()->GetBoard()->IsEmpty();
800 auto isSkippable = [
this](
const SELECTION& aSelection )
806 && notMovingCondition && !inFootprintEditor;
844 menu.AddMenu( gateSwapSubMenu.get(), gateSwapSingleUnitOnOneFootprint );
859 && !inFootprintEditor );
869 menu.AddMenu( fpAttributesMenu.get(), singleFootprintCondition || multipleFootprintsCondition );
872 menu.AddSeparator( 100 );
873 menu.AddMenu( routingSubMenu.get(), isRoutable, 100 );
874 menu.AddMenu( mirrorRotateSubMenu.get(), canMirror, 100 );
875 menu.AddMenu( shapeModificationSubMenu.get(), shapeModificationCondition, 100 );
876 menu.AddMenu( positioningToolsSubMenu.get(), positioningToolsCondition, 100 );
878 menu.AddSeparator( 150 );
891 menu.AddSeparator( 2000 );
910 wxString footprintName;
911 wxArrayString fplist;
916 fplist.Add( fp->GetReference() + wxT(
" ( " ) + fp->GetValue() + wxT(
" )" ) );
926 footprintName.Trim(
true );
927 footprintName.Trim(
false );
929 if( !footprintName.IsEmpty() )
933 if( fp->GetReference().CmpNoCase( footprintName ) == 0 )
1033 std::vector<PCB_TRACK*> tracks;
1034 std::vector<PCB_TRACK*> vias;
1035 std::vector<FOOTPRINT*> footprints;
1038 const auto gatherItemsByType = [&]()
1045 vias.push_back( track );
1047 tracks.push_back( track );
1057 gatherItemsByType();
1062 for(
int ii = aCollector.
GetCount() - 1; ii >= 0; --ii )
1068 else if( tracks.size() || vias.size() )
1082 gatherItemsByType();
1095 if( tracks.size() == 2 && vias.size() == 0 )
1097 if( connected( tracks[0], tracks[1]->GetStart() )
1098 || connected( tracks[0], tracks[1]->GetEnd() ) )
1100 aCollector.
Remove( tracks[1] );
1103 else if( tracks.size() == 2 && vias.size() == 1 )
1105 if( connected( tracks[0], vias[0]->GetPosition() )
1106 && connected( tracks[1], vias[0]->GetPosition() ) )
1108 aCollector.
Remove( tracks[0] );
1109 aCollector.
Remove( tracks[1] );
1135 wxString variantName;
1138 variantName =
board->GetCurrentVariant();
1140 bool new_state =
false;
1163 if( !variantName.IsEmpty() )
1187 if( !commit.
Empty() )
1188 commit.
Push(
_(
"Toggle Attribute" ) );
1203 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1208 aCollector.
Remove( item );
1238 new_width =
board()->GetDesignSettings().GetCurrentViaSize();
1239 new_drill =
board()->GetDesignSettings().GetCurrentViaDrill();
1242 via->SetDrill( new_drill );
1250 wxCHECK( track, 0 );
1254 int new_width =
board()->GetDesignSettings().GetCurrentTrackWidth();
1259 commit.
Push(
_(
"Edit Track Width/Via Size" ) );
1284 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1289 aCollector.
Remove( item );
1306 if( newLayer == origLayer )
1317 wxCHECK( track, 0 );
1325 commit.
Push(
_(
"Edit Track Layer" ) );
1342 static int filletRadius = 0;
1348 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1353 aCollector.
Remove( item );
1364 frame()->ShowInfoBarMsg(
_(
"At least two straight track segments must be selected." ) );
1380 bool t1Start =
true;
1381 bool t2Start =
true;
1384 std::vector<FILLET_OP> filletOperations;
1385 bool operationPerformedOnAtLeastOne =
false;
1386 bool didOneAttemptFail =
false;
1387 std::set<PCB_TRACK*> processedTracks;
1389 auto processFilletOp = [&](
PCB_TRACK* aTrack,
bool aStartPoint )
1391 std::shared_ptr<CONNECTIVITY_DATA> c =
board()->GetConnectivity();
1393 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
1397 if( itemsOnAnchor.size() > 0 &&
selection.Contains( itemsOnAnchor.at( 0 ) )
1403 if( processedTracks.find( trackOther ) == processedTracks.end() )
1405 if( itemsOnAnchor.size() == 1 )
1408 filletOp.t1 = aTrack;
1409 filletOp.t2 = trackOther;
1410 filletOp.t1Start = aStartPoint;
1411 filletOp.t2Start = aTrack->
IsPointOnEnds( filletOp.t2->GetStart() );
1412 filletOperations.push_back( filletOp );
1418 didOneAttemptFail =
true;
1432 processFilletOp( track,
true );
1433 processFilletOp( track,
false );
1435 processedTracks.insert( track );
1441 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1443 for( FILLET_OP filletOp : filletOperations )
1451 if( trackOnStart && trackOnEnd )
1454 if( ( trackOnStart || trackOnEnd ) && track1->
GetLayer() == track2->
GetLayer() )
1462 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadius );
1465 auto setIfPointOnSeg = [](
VECTOR2I& aPointToSet,
const SEG& aSegment,
const VECTOR2I& aVecToTest )
1467 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1472 aPointToSet.
x = aVecToTest.x;
1473 aPointToSet.
y = aVecToTest.y;
1481 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP0() )
1482 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP0() ) )
1484 didOneAttemptFail =
true;
1488 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.
GetP1() )
1489 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.
GetP1() ) )
1491 didOneAttemptFail =
true;
1503 itemsToAddToSelection.push_back( tArc );
1508 if( filletOp.t1Start )
1511 track1->
SetEnd( t1newPoint );
1513 if( filletOp.t2Start )
1516 track2->
SetEnd( t2newPoint );
1518 operationPerformedOnAtLeastOne =
true;
1522 commit.
Push(
_(
"Fillet Tracks" ) );
1525 for(
BOARD_ITEM* item : itemsToAddToSelection )
1528 if( !operationPerformedOnAtLeastOne )
1529 frame()->ShowInfoBarMsg(
_(
"Unable to fillet the selected track segments." ) );
1530 else if( didOneAttemptFail )
1531 frame()->ShowInfoBarMsg(
_(
"Some of the track segments could not be filleted." ) );
1551 return std::nullopt;
1555 return aPersitentRadius;
1567 std::vector<WX_MULTI_ENTRY_DIALOG::ENTRY> entries{
1574 _(
"Add slots in acute corners" ),
1576 _(
"Add slots in acute corners to allow access to a cutter of the given radius" ),
1583 return std::nullopt;
1585 std::vector<WX_MULTI_ENTRY_DIALOG::RESULT> results = dlg.
GetValues();
1586 wxCHECK( results.size() == 2, std::nullopt );
1590 s_dogBoneParams.DogboneRadiusIU = std::get<long long int>( results[0] );
1591 s_dogBoneParams.AddSlots = std::get<bool>( results[1] );
1593 catch(
const std::bad_variant_access& )
1596 return std::nullopt;
1599 return s_dogBoneParams;
1613 const int default_setback =
pcbIUScale.mmToIU( 1 );
1615 static CHAMFER_PARAMS params{ default_setback, default_setback };
1617 WX_UNIT_ENTRY_DIALOG dlg( &aFrame,
_(
"Chamfer Lines" ),
_(
"Chamfer setback:" ), params.m_chamfer_setback_a );
1620 return std::nullopt;
1622 params.m_chamfer_setback_a = dlg.
GetValue();
1625 params.m_chamfer_setback_b = params.m_chamfer_setback_a;
1636 std::vector<VECTOR2I> pts;
1639 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1646 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } ) )
1648 aCollector.
Remove( item );
1657 std::set<PCB_SHAPE*> lines_to_add;
1658 std::vector<PCB_SHAPE*> items_to_remove;
1662 std::vector<VECTOR2I> pts;
1669 items_to_remove.push_back( graphic );
1672 pts.emplace_back( start );
1674 pts.emplace_back(
end );
1680 items_to_remove.push_back( graphic );
1682 for(
int jj = 0; jj < graphic->
GetPolyShape().VertexCount(); ++jj )
1686 for(
size_t jj = 1; jj < pts.size(); ++jj )
1694 lines_to_add.insert( line );
1697 if( pts.size() > 1 )
1702 line->
SetEnd( pts.front() );
1705 lines_to_add.insert( line );
1713 frame()->ShowInfoBarMsg(
_(
"Exactly two lines must be selected to extend them." ) );
1720 else if( segmentCount < 2 )
1722 frame()->ShowInfoBarMsg(
_(
"A shape with at least two lines must be selected." ) );
1740 for(
PCB_SHAPE* item : items_to_remove )
1751 std::vector<BOARD_ITEM*> items_to_select_on_success;
1754 std::vector<BOARD_ITEM*> items_to_deselect_on_success;
1759 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
1765 items_to_select_on_success.push_back( &aItem );
1769 bool any_items_created = !lines_to_add.empty();
1770 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
1772 any_items_created =
true;
1773 items_to_select_on_success.push_back( aItem.get() );
1774 commit.
Add( aItem.release() );
1777 bool any_items_removed = !items_to_remove.empty();
1778 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
1781 any_items_removed =
true;
1782 items_to_deselect_on_success.push_back( &aItem );
1788 item_removal_handler );
1791 std::unique_ptr<PAIRWISE_LINE_ROUTINE> pairwise_line_routine;
1795 static int s_filletRadius =
pcbIUScale.mmToIU( 1 );
1796 std::optional<int> filletRadiusIU =
GetRadiusParams( *
frame(),
_(
"Fillet Lines" ), s_filletRadius );
1798 if( filletRadiusIU.has_value() )
1800 pairwise_line_routine =
1801 std::make_unique<LINE_FILLET_ROUTINE>(
frame()->GetModel(), change_handler, *filletRadiusIU );
1808 if( dogboneParams.has_value() )
1810 pairwise_line_routine =
1811 std::make_unique<DOGBONE_CORNER_ROUTINE>(
frame()->GetModel(), change_handler, *dogboneParams );
1818 if( chamfer_params.has_value() )
1820 pairwise_line_routine =
1821 std::make_unique<LINE_CHAMFER_ROUTINE>(
frame()->GetModel(), change_handler, *chamfer_params );
1826 pairwise_line_routine = std::make_unique<LINE_EXTENSION_ROUTINE>(
frame()->GetModel(), change_handler );
1829 if( !pairwise_line_routine )
1840 if( ( a->GetFlags() & STRUCT_DELETED ) == 0 && ( b->GetFlags() & STRUCT_DELETED ) == 0 )
1842 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1843 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1845 pairwise_line_routine->ProcessLinePair( *line_a, *line_b );
1850 for(
BOARD_ITEM* item : items_to_select_on_success )
1851 m_selectionTool->AddItemToSel( item,
true );
1854 for(
BOARD_ITEM* item : items_to_deselect_on_success )
1855 m_selectionTool->RemoveItemFromSel( item,
true );
1857 if( any_items_removed )
1860 if( any_items_created )
1866 commit.Push( pairwise_line_routine->GetCommitDescription() );
1868 if(
const std::optional<wxString> msg = pairwise_line_routine->GetStatusMessage( segmentCount ) )
1869 frame()->ShowInfoBarMsg( *msg );
1880 std::vector<VECTOR2I> pts;
1883 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1887 if( !item->
IsType( { PCB_SHAPE_LOCATE_POLY_T, PCB_ZONE_T } ) )
1888 aCollector.
Remove( item );
1892 if( zone->IsTeardropArea() )
1893 aCollector.
Remove( item );
1903 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
1912 if( s_toleranceValue <= 0 )
1917 std::vector<PCB_SHAPE*> shapeList;
1921 commit.Modify( item );
1935 zone->HatchBorder();
1939 commit.
Push(
_(
"Simplify Polygons" ) );
1953 std::vector<VECTOR2I> pts;
1956 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1963 { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T, PCB_SHAPE_LOCATE_BEZIER_T } ) )
1965 aCollector.
Remove( item );
1975 static int s_toleranceValue =
pcbIUScale.mmToIU( 3 );
1984 if( s_toleranceValue <= 0 )
1989 std::vector<PCB_SHAPE*> shapeList;
1995 shapeList.push_back( shape );
1996 commit.Modify( shape );
2002 commit.Push(
_(
"Heal Shapes" ) );
2017 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
2021 static const std::vector<KICAD_T> polygonBooleanTypes = {
2027 if( !item->
IsType( polygonBooleanTypes ) )
2028 aCollector.
Remove( item );
2039 std::vector<PCB_SHAPE*> items_to_process;
2043 items_to_process.push_back(
static_cast<PCB_SHAPE*
>( item ) );
2048 if( item == last_item )
2049 std::swap( items_to_process.back(), items_to_process.front() );
2055 auto item_modification_handler = [&](
BOARD_ITEM& aItem )
2057 commit.Modify( &aItem );
2060 std::vector<BOARD_ITEM*> items_to_select_on_success;
2062 auto item_creation_handler = [&]( std::unique_ptr<BOARD_ITEM> aItem )
2064 items_to_select_on_success.push_back( aItem.get() );
2065 commit.Add( aItem.release() );
2068 auto item_removal_handler = [&](
BOARD_ITEM& aItem )
2070 commit.Remove( &aItem );
2075 item_removal_handler );
2078 std::unique_ptr<POLYGON_BOOLEAN_ROUTINE> boolean_routine;
2080 const auto create_routine = [&]() -> std::unique_ptr<POLYGON_BOOLEAN_ROUTINE>
2087 wxCHECK(
model,
nullptr );
2091 return std::make_unique<POLYGON_MERGE_ROUTINE>(
model, change_handler );
2095 return std::make_unique<POLYGON_SUBTRACT_ROUTINE>(
model, change_handler );
2099 return std::make_unique<POLYGON_INTERSECT_ROUTINE>(
model, change_handler );
2104 const auto run_routine = [&]()
2107 for(
PCB_SHAPE* shape : items_to_process )
2108 boolean_routine->ProcessShape( *shape );
2110 boolean_routine->Finalize();
2113 boolean_routine = create_routine();
2115 wxCHECK_MSG( boolean_routine, 0,
"Could not find a polygon routine for this action" );
2122 if( !boolean_routine->IsCommutative() && items_to_select_on_success.empty() )
2126 items_to_select_on_success.clear();
2128 std::map<const PCB_SHAPE*, VECTOR2I::extended_type> items_area;
2130 for(
PCB_SHAPE* shape : items_to_process )
2133 items_area[shape] = area;
2142 std::sort( items_to_process.begin(), items_to_process.end(),
2145 return items_area[a] > items_area[b];
2149 boolean_routine = create_routine();
2154 for(
BOARD_ITEM* item : items_to_select_on_success )
2160 commit.Push( boolean_routine->GetCommitDescription() );
2162 if(
const std::optional<wxString> msg = boolean_routine->GetStatusMessage() )
2163 frame()->ShowInfoBarMsg( *msg );
2198 std::vector<PCB_TABLECELL*> cells;
2244 std::vector<PCB_SHAPE*> shapes;
2246 constraintTool->SolveAfterEdit( shapes );
2261 for(
EDA_ITEM* eda_item : selCopy )
2263 if( !eda_item->IsBOARD_ITEM() )
2305 if( editFrame && item )
2318 std::unordered_set<BOARD_ITEM*> visited;
2323 if( !aItem || !visited.insert( aItem ).second )
2327 aShapes.push_back(
static_cast<PCB_SHAPE*
>( aItem ) );
2334 if( item->IsBOARD_ITEM() )
2344 if( !constraintTool )
2347 std::vector<PCB_SHAPE*> shapes;
2367 commit = &localCommit;
2390 std::optional<VECTOR2I> oldRefPt;
2395 oldRefPt =
selection.GetReferencePoint();
2421 bool usePcbShapeCenter =
false;
2428 usePcbShapeCenter =
true;
2432 usePcbShapeCenter =
true;
2438 else if( usePcbShapeCenter )
2450 if(
frame()->GetCanvas()->GetView()->GetGAL()->IsFlippedX() )
2451 rotateAngle = -rotateAngle;
2457 viewBBox.
Merge( item->ViewBBox() );
2466 typedef std::numeric_limits<int> coord_limits;
2471 bool outOfBounds = rotPos.
x < min || rotPos.
x > max || rotPos.
y < min || rotPos.
y > max || rotEnd.
x < min
2472 || rotEnd.
x > max || rotEnd.
y < min || rotEnd.
y > max;
2480 if( item->IsBOARD_ITEM() )
2484 board_item->
Rotate( refPt, rotateAngle );
2488 static_cast<FOOTPRINT*
>( board_item )->InvalidateComponentClassCache();
2496 localCommit.
Push(
_(
"Rotate" ) );
2515 selection.SetReferencePoint( *oldRefPt );
2533 MIRROR( tmpPt, aMirrorPoint, aFlipDirection );
2566 commit = &localCommit;
2588 int skippedFootprints = 0;
2589 int skippedGroups = 0;
2596 skippedFootprints++;
2611 switch( item->Type() )
2614 static_cast<PCB_SHAPE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2618 static_cast<ZONE*
>( item )->
Mirror( mirrorPoint, flipDirection );
2623 static_cast<PCB_TEXT*
>( item )->
Mirror( mirrorPoint, flipDirection );
2633 mirrorPad( *
static_cast<PAD*
>( item ), mirrorPoint, flipDirection );
2639 static_cast<PCB_TRACK*
>( item )->
Mirror( mirrorPoint, flipDirection );
2643 static_cast<PCB_GROUP*
>( item )->
Mirror( mirrorPoint, flipDirection );
2652 static_cast<PCB_POINT*
>( item )->
Mirror( mirrorPoint, flipDirection );
break;
2664 localCommit.
Push(
_(
"Mirror" ) );
2670 frame()->ShowInfoBarMsg(
_(
"Footprints cannot be mirrored. Use Flip to move them to "
2671 "the other side of the board." ) );
2675 frame()->ShowInfoBarMsg(
_(
"Groups containing footprints or other items that cannot be "
2676 "mirrored were skipped." ) );
2706 commit = &localCommit;
2720 auto setJustify = [&](
EDA_TEXT* aTextItem )
2735 setJustify(
static_cast<PCB_TEXT*
>( item ) );
2744 if( !localCommit.
Empty() )
2747 localCommit.
Push(
_(
"Left Justify" ) );
2749 localCommit.
Push(
_(
"Center Justify" ) );
2751 localCommit.
Push(
_(
"Right Justify" ) );
2781 commit = &localCommit;
2798 std::optional<VECTOR2I> oldRefPt;
2801 oldRefPt =
selection.GetReferencePoint();
2831 if( !item->IsBOARD_ITEM() )
2838 boardItem->
Flip( refPt, flipDirection );
2842 static_cast<FOOTPRINT*
>( boardItem )->InvalidateComponentClassCache();
2849 localCommit.
Push(
_(
"Change Side / Flip" ) );
2867 selection.SetReferencePoint( *oldRefPt );
2879 int commitFlags = 0;
2884 int itemsDeleted = 0;
2885 int fieldsHidden = 0;
2886 int fieldsAlreadyHidden = 0;
2890 if( !item->IsBOARD_ITEM() )
2896 switch( item->Type() )
2902 wxASSERT( parentFP );
2903 commit.
Modify( parentFP );
2912 fieldsAlreadyHidden++;
2915 getView()->Update( parentFP );
2932 commit.
Remove( board_item );
2938 commit.
Modify( board_item );
2939 static_cast<PCB_TABLECELL*
>( board_item )->SetText( wxEmptyString );
2951 commit.
Remove( board_item );
2958 commit.
Remove( board_item );
2968 if( !aIsCut && aItems.
GetSize() == 1 )
2971 ZONE* zone =
static_cast<ZONE*
>( board_item );
2973 int outlineIdx, holeIdx;
2994 commit.
Remove( board_item );
3005 commit.Push(
_(
"Delete" ), commitFlags );
3013 commit.
Remove( board_item );
3021 commit.
Remove( board_item );
3030 if( enteredGroup && enteredGroup->
GetItems().empty() )
3035 commit.
Push(
_(
"Cut" ), commitFlags );
3037 else if( itemsDeleted == 0 )
3039 if( fieldsHidden == 1 )
3040 commit.
Push(
_(
"Hide Field" ), commitFlags );
3041 else if( fieldsHidden > 1 )
3042 commit.
Push(
_(
"Hide Fields" ), commitFlags );
3043 else if( fieldsAlreadyHidden > 0 )
3044 editFrame->
ShowInfoBarError(
_(
"Use the Footprint Properties dialog to remove fields." ) );
3048 commit.
Push(
_(
"Delete" ), commitFlags );
3073 std::vector<BOARD_ITEM*> lockedItems;
3090 const bool hadInitialSelection = !
m_selectionTool->GetSelection().Empty();
3105 if( hadInitialSelection && selectionCopy.
Empty() )
3135 if( selectionCopy.
Empty() )
3183 if( ret == wxID_OK )
3191 selCenter += translation;
3193 if( !
frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
3194 rotation = -rotation;
3198 if( !item->IsBOARD_ITEM() )
3206 boardItem->
Move( translation );
3208 switch( rotationAnchor )
3214 boardItem->
Rotate(
board()->GetDesignSettings().GetAuxOrigin(), angle );
3219 getView()->Update( boardItem );
3222 commit.
Push(
_(
"Move Exactly" ) );
3279 std::vector<BOARD_ITEM*> new_items;
3284 std::map<KIID, KIID> idMap;
3290 if( !item->IsBOARD_ITEM() )
3302 switch( orig_item->
Type() )
3322 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3324 dupe_item = orig_item->
Duplicate(
true, &commit );
3336 new_items.push_back( dupe_item );
3337 commit.
Add( dupe_item );
3347 dupe_item = parentFootprint->
DuplicateItem(
true, &commit, orig_item );
3349 if( increment &&
static_cast<PAD*
>( dupe_item )->CanHaveNumber() )
3355 static_cast<PAD*
>( dupe_item )->SetNumber( padNumber );
3363 new_items.push_back( dupe_item );
3364 commit.
Add( dupe_item );
3376 dupe_item =
static_cast<PCB_GROUP*
>( orig_item )->DeepDuplicate(
true, &commit, &idMap );
3382 new_items.push_back( aItem );
3383 commit.
Add( aItem );
3388 new_items.push_back( dupe_item );
3389 commit.
Add( dupe_item );
3401 :
board()->Constraints();
3404 commit.
Add( clone );
3410 EDA_ITEMS nItems( new_items.begin(), new_items.end() );
3416 editFrame->
DisplayToolMsg( wxString::Format(
_(
"Duplicated %d item(s)" ), (
int) new_items.size() ) );
3420 commit.
Push(
_(
"Duplicate" ) );
3438 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3440 switch( aCollector[i]->Type() )
3444 default: aCollector.
Remove( i );
break;
3469 commit = &localCommit;
3473 switch( item->Type() )
3483 if( !
pad.CanHaveNumber() )
3487 std::optional<wxString> newNumber = incrementer.Increment(
pad.GetNumber(), param.
Delta, param.
Index );
3492 pad.SetNumber( *newNumber );
3501 std::optional<wxString> newText = incrementer.Increment(
text.GetText(), param.
Delta, param.
Index );
3506 text.SetText( *newText );
3518 commit->
Push(
_(
"Increment" ) );
3526 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3528 if( aCollector[i]->Type() !=
PCB_PAD_T )
3536 for(
int i = aCollector.
GetCount() - 1; i >= 0; i-- )
3547 if( aSelection.
Empty() )
3571 BOX2I nonFieldsBBox;
3575 if( !item->IsType( { PCB_TEXT_T, PCB_FIELD_T } ) )
3576 nonFieldsBBox.
Merge( item->GetBoundingBox() );
3591 const wxString& aCanceledMessage,
VECTOR2I& aReferencePoint )
3595 std::optional<VECTOR2I> pickedPoint;
3605 const auto setPickerLayerSet =
3612 layerFilter =
LSET( { editFrame->GetActiveLayer() } );
3620 setPickerLayerSet();
3623 [&](
const VECTOR2D& aPoint ) ->
bool
3625 pickedPoint = aPoint;
3627 if( !aSuccessMessage.empty() )
3649 if( !aCanceledMessage.empty() )
3661 [&](
const int& aFinalState )
3680 setPickerLayerSet();
3683 evt->SetPassEvent();
3694 canvas()->SetStatusPopup(
nullptr );
3698 aReferencePoint = *pickedPoint;
3700 return pickedPoint.has_value();
3708 TOOL_EVENT selectReferencePoint( aEvent.
Category(), aEvent.
Action(),
"pcbnew.InteractiveEdit.selectReferencePoint",
3711 frame()->PushTool( selectReferencePoint );
3728 std::vector<BOARD_ITEM*> items;
3732 if( item->IsBOARD_ITEM() )
3733 items.push_back(
static_cast<BOARD_ITEM*
>( item ) );
3740 if( !
pickReferencePoint(
_(
"Select reference point for the copy..." ),
_(
"Selection copied" ),
3741 _(
"Copy canceled" ), refPoint ) )
3743 frame()->PopTool( selectReferencePoint );
3752 selection.SetReferencePoint( refPoint );
3756 frame()->SetStatusText(
_(
"Selection copied" ) );
3759 frame()->PopTool( selectReferencePoint );
3779 const auto getItemText = [&](
const BOARD_ITEM& aItem ) -> wxString
3781 switch( aItem.Type() )
3793 return text.GetShownText(
true );
3807 for(
int row = 0; row <
table.GetRowCount(); ++row )
3809 for(
int col = 0; col <
table.GetColCount(); ++col )
3814 if( col <
table.GetColCount() - 1 )
3820 if( row <
table.GetRowCount() - 1 )
3831 return wxEmptyString;
3834 wxArrayString itemTexts;
3838 if( item->IsBOARD_ITEM() )
3841 wxString itemText = getItemText( *boardItem );
3843 itemText.Trim(
false ).Trim(
true );
3845 if( !itemText.IsEmpty() )
3847 itemTexts.Add( std::move( itemText ) );
3853 if( !itemTexts.empty() )
3880 board()->BuildConnectivity();
3882 canvas()->RedrawRatsnest();
constexpr EDA_IU_SCALE pcbIUScale
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 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...
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
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...
virtual int GetUndoCommandCount() const
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.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
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.
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)
VECTOR2I GetOffset(PCB_LAYER_ID aLayer) const
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
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
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.
A geometric constraint between board items (issue #2329).
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
static const TOOL_EVENT & SnappingModeChangedByKeyEvent()
Hotkey feedback.
A set of BOARD_ITEMs (i.e., without duplicates).
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
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.
void SetWidth(int aWidth) override
int GetWidth() const override
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
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
bool ApproxCollinear(const SEG &aSeg, int aDistanceThreshold=1) const
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.
std::vector< PCB_CONSTRAINT * > CloneFullySelectedConstraints(const CONSTRAINTS &aSource, const std::map< KIID, KIID > &aIdMap)
Clone the constraints in aSource that a duplicate should carry.
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static std::string ToStdString(const wxString &aStr)
#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)
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
std::deque< PCB_CONSTRAINT * > CONSTRAINTS
@ ID_POPUP_PCB_SWAP_UNIT_LAST
@ ID_POPUP_PCB_SWAP_UNIT_BASE
std::vector< EDA_ITEM * > EDA_ITEMS
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.
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