KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pad_tool.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2017-2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25#include "pad_tool.h"
26#include "pcb_painter.h"
27#include <kiplatform/ui.h>
28#include <macros.h>
30#include <view/view_controls.h>
31#include <tool/tool_manager.h>
33#include <board_item.h>
34#include <footprint.h>
35#include <pcb_shape.h>
36#include <pad.h>
37#include <pcbnew_settings.h>
38#include <board_commit.h>
40#include <tools/pcb_actions.h>
44#include <tools/edit_tool.h>
46#include <widgets/wx_infobar.h>
47
48
50
51
53 PCB_TOOL_BASE( "pcbnew.PadTool" ),
54 m_previousHighContrastMode( HIGH_CONTRAST_MODE::NORMAL ),
55 m_editPad( niluuid )
56{}
57
58
60{}
61
62
64{
65 if( aReason == MODEL_RELOAD )
66 m_lastPadNumber = wxT( "1" );
67
68 if( board() && board()->GetItem( m_editPad ) == DELETED_BOARD_ITEM::GetInstance() )
69 {
71
73 {
75 frame()->SetDisplayOptions( opts );
76 }
77
78 frame()->GetInfoBar()->Dismiss();
79
81 }
82}
83
84
86{
88
89 if( selTool )
90 {
91 // Add context menu entries that are displayed when selection tool is active
92 CONDITIONAL_MENU& menu = selTool->GetToolMenu().GetMenu();
93
97
98 auto explodeCondition =
99 [&]( const SELECTION& aSel )
100 {
101 return m_editPad == niluuid && aSel.Size() == 1 && aSel[0]->Type() == PCB_PAD_T;
102 };
103
104 auto recombineCondition =
105 [&]( const SELECTION& aSel )
106 {
107 return m_editPad != niluuid;
108 };
109
110 menu.AddSeparator( 400 );
111
113 {
115 menu.AddItem( PCB_ACTIONS::recombinePad, recombineCondition, 400 );
116 menu.AddItem( PCB_ACTIONS::explodePad, explodeCondition, 400 );
117 }
118
119 menu.AddItem( PCB_ACTIONS::copyPadSettings, singlePadSel, 400 );
120 menu.AddItem( PCB_ACTIONS::applyPadSettings, padSel, 400 );
121 menu.AddItem( PCB_ACTIONS::pushPadSettings, singlePadSel, 400 );
122 }
123
124 auto& ctxMenu = m_menu.GetMenu();
125
126 // cancel current tool goes in main context menu at the top if present
128 ctxMenu.AddSeparator( 1 );
129
136
137 // Finally, add the standard zoom/grid items
138 getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( m_menu );
139
140 return true;
141}
142
143
145{
147 const PCB_SELECTION& selection = selTool->GetSelection();
148 const PAD* masterPad = frame()->GetDesignSettings().m_Pad_Master.get();
149
150 BOARD_COMMIT commit( frame() );
151
152 // for every selected pad, paste global settings
153 for( EDA_ITEM* item : selection )
154 {
155 if( item->Type() == PCB_PAD_T )
156 {
157 commit.Modify( item );
158 static_cast<PAD&>( *item ).ImportSettingsFrom( *masterPad );
159 }
160 }
161
162 commit.Push( _( "Paste Pad Properties" ) );
163
165 frame()->Refresh();
166
167 return 0;
168}
169
170
172{
174 const PCB_SELECTION& selection = selTool->GetSelection();
175
176 // can only copy from a single pad
177 if( selection.Size() == 1 )
178 {
179 EDA_ITEM* item = selection[0];
180
181 if( item->Type() == PCB_PAD_T )
182 {
183 const PAD& selPad = static_cast<const PAD&>( *item );
184 frame()->GetDesignSettings().m_Pad_Master->ImportSettingsFrom( selPad );
185 }
186 }
187
188 return 0;
189}
190
191
192static void doPushPadProperties( BOARD& board, const PAD& aSrcPad, BOARD_COMMIT& commit,
193 bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter,
194 bool aPadLayerFilter, bool aPadTypeFilter )
195{
196 const FOOTPRINT* refFootprint = aSrcPad.GetParentFootprint();
197
198 EDA_ANGLE srcPadAngle = aSrcPad.GetOrientation() - refFootprint->GetOrientation();
199
200 for( FOOTPRINT* footprint : board.Footprints() )
201 {
202 if( !aSameFootprints && ( footprint != refFootprint ) )
203 continue;
204
205 if( footprint->GetFPID() != refFootprint->GetFPID() )
206 continue;
207
208 for( PAD* pad : footprint->Pads() )
209 {
210 if( aPadShapeFilter && ( pad->GetShape() != aSrcPad.GetShape() ) )
211 continue;
212
213 EDA_ANGLE padAngle = pad->GetOrientation() - footprint->GetOrientation();
214
215 if( aPadOrientFilter && ( padAngle != srcPadAngle ) )
216 continue;
217
218 if( aPadLayerFilter && ( pad->GetLayerSet() != aSrcPad.GetLayerSet() ) )
219 continue;
220
221 if( aPadTypeFilter && ( pad->GetAttribute() != aSrcPad.GetAttribute() ) )
222 continue;
223
224 // Special-case for aperture pads
225 if( aPadTypeFilter && pad->GetAttribute() == PAD_ATTRIB::CONN )
226 {
227 if( pad->IsAperturePad() != aSrcPad.IsAperturePad() )
228 continue;
229 }
230
231 commit.Modify( pad );
232
233 // Apply source pad settings to this pad
234 pad->ImportSettingsFrom( aSrcPad );
235 }
236 }
237}
238
239
241{
243 const PCB_SELECTION& selection = selTool->GetSelection();
244
245 if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
246 {
247 PAD* srcPad = static_cast<PAD*>( selection[0] );
248
249 if( FOOTPRINT* footprint = srcPad->GetParentFootprint() )
250 {
252
254 int dialogRet = dlg.ShowModal();
255
256 if( dialogRet == wxID_CANCEL )
257 return 0;
258
259 const bool edit_Same_Modules = (dialogRet == 1);
260
261 BOARD_COMMIT commit( frame() );
262
263 doPushPadProperties( *getModel<BOARD>(), *srcPad, commit, edit_Same_Modules,
268
269 commit.Push( _( "Push Pad Settings" ) );
270
272 frame()->Refresh();
273 }
274 }
275
276 return 0;
277}
278
279
286static std::optional<SEQUENTIAL_PAD_ENUMERATION_PARAMS>
288{
289 // Persistent settings for the pad enumeration dialog.
290 static SEQUENTIAL_PAD_ENUMERATION_PARAMS s_lastUsedParams;
291
292 DIALOG_ENUM_PADS settingsDlg( aFrame, s_lastUsedParams );
293
294 if( settingsDlg.ShowModal() != wxID_OK )
295 return std::nullopt;
296
297 return s_lastUsedParams;
298}
299
300
302{
304 return 0;
305
306 if( !board()->GetFirstFootprint() || board()->GetFirstFootprint()->Pads().empty() )
307 return 0;
308
309 GENERAL_COLLECTOR collector;
311 guide.SetIgnoreMTextsMarkedNoShow( true );
312 guide.SetIgnoreMTextsOnBack( true );
313 guide.SetIgnoreMTextsOnFront( true );
314 guide.SetIgnoreModulesVals( true );
315 guide.SetIgnoreModulesRefs( true );
316
317 const std::optional<SEQUENTIAL_PAD_ENUMERATION_PARAMS> params =
319
320 // Cancelled or otherwise failed to get any useful parameters
321 if( !params )
322 return 0;
323
324 int seqPadNum = params->m_start_number;
325
326 std::deque<int> storedPadNumbers;
327 std::map<wxString, std::pair<int, wxString>> oldNumbers;
328
330
331 frame()->PushTool( aEvent );
332
333 VECTOR2I oldCursorPos; // store the previous mouse cursor position, during mouse drag
334 std::list<PAD*> selectedPads;
335 BOARD_COMMIT commit( frame() );
336 bool isFirstPoint = true; // make sure oldCursorPos is initialized at least once
337 PADS pads = board()->GetFirstFootprint()->Pads();
338
339 MAGNETIC_SETTINGS mag_settings;
340 mag_settings.graphics = false;
341 mag_settings.tracks = MAGNETIC_OPTIONS::NO_EFFECT;
342 mag_settings.pads = MAGNETIC_OPTIONS::CAPTURE_ALWAYS;
343 PCB_GRID_HELPER grid( m_toolMgr, &mag_settings );
344
345 grid.SetSnap( true );
346 grid.SetUseGrid( false );
347
348 auto setCursor =
349 [&]()
350 {
351 canvas()->SetCurrentCursor( KICURSOR::BULLSEYE );
352 };
353
354 Activate();
355 // Must be done after Activate() so that it gets set into the correct context
356 getViewControls()->ShowCursor( true );
358 // Set initial cursor
359 setCursor();
360
361 STATUS_TEXT_POPUP statusPopup( frame() );
362
363 // Callable lambda to construct the pad number string for the given value
364 const auto constructPadNumber =
365 [&]( int aValue )
366 {
367 return wxString::Format( wxT( "%s%d" ), params->m_prefix.value_or( "" ), aValue );
368 };
369
370 // Callable lambda to set the popup text for the given pad value
371 const auto setPopupTextForValue =
372 [&]( int aValue )
373 {
374 const wxString msg = _( "Click on pad %s\n"
375 "Press <esc> to cancel all; double-click to finish" );
376 statusPopup.SetText( wxString::Format( msg, constructPadNumber( aValue ) ) );
377 };
378
379 setPopupTextForValue( seqPadNum );
380 statusPopup.Popup();
381 statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
382 canvas()->SetStatusPopup( statusPopup.GetPanel() );
383
384 while( TOOL_EVENT* evt = Wait() )
385 {
386 setCursor();
387
388 VECTOR2I cursorPos = grid.AlignToNearestPad( getViewControls()->GetMousePosition(), pads );
389 getViewControls()->ForceCursorPosition( true, cursorPos );
390
391 if( evt->IsCancelInteractive() )
392 {
394 commit.Revert();
395
396 frame()->PopTool( aEvent );
397 break;
398 }
399 else if( evt->IsActivate() )
400 {
401 commit.Push( _( "Renumber Pads" ) );
402
403 frame()->PopTool( aEvent );
404 break;
405 }
406 else if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
407 {
408 selectedPads.clear();
409
410 // Be sure the old cursor mouse position was initialized:
411 if( isFirstPoint )
412 {
413 oldCursorPos = cursorPos;
414 isFirstPoint = false;
415 }
416
417 // wxWidgets deliver mouse move events not frequently enough, resulting in skipping
418 // pads if the user moves cursor too fast. To solve it, create a line that approximates
419 // the mouse move and search pads that are on the line.
420 int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
421 // Search will be made every 0.1 mm:
422 int segments = distance / int( 0.1 * pcbIUScale.IU_PER_MM ) + 1;
423 const VECTOR2I line_step( ( cursorPos - oldCursorPos ) / segments );
424
425 collector.Empty();
426
427 for( int j = 0; j < segments; ++j )
428 {
429 VECTOR2I testpoint( cursorPos.x - j * line_step.x, cursorPos.y - j * line_step.y );
430 collector.Collect( board(), { PCB_PAD_T }, testpoint, guide );
431
432 for( int i = 0; i < collector.GetCount(); ++i )
433 {
434 PAD* pad = static_cast<PAD*>( collector[i] );
435
436 if( !pad->IsAperturePad() )
437 selectedPads.push_back( pad );
438 }
439 }
440
441 selectedPads.unique();
442
443 for( PAD* pad : selectedPads )
444 {
445 // If pad was not selected, then enumerate it
446 if( !pad->IsSelected() )
447 {
448 commit.Modify( pad );
449
450 // Rename pad and store the old name
451 int newval;
452
453 if( storedPadNumbers.size() > 0 )
454 {
455 newval = storedPadNumbers.front();
456 storedPadNumbers.pop_front();
457 }
458 else
459 {
460 newval = seqPadNum;
461 seqPadNum += params->m_step;
462 }
463
464 const wxString newNumber = constructPadNumber( newval );
465 oldNumbers[newNumber] = { newval, pad->GetNumber() };
466 pad->SetNumber( newNumber );
467 SetLastPadNumber( newNumber );
468 pad->SetSelected();
469 getView()->Update( pad );
470
471 // Ensure the popup text shows the correct next value
472 if( storedPadNumbers.size() > 0 )
473 newval = storedPadNumbers.front();
474 else
475 newval = seqPadNum;
476
477 setPopupTextForValue( newval );
478 }
479
480 // ... or restore the old name if it was enumerated and clicked again
481 else if( pad->IsSelected() && evt->IsClick( BUT_LEFT ) )
482 {
483 auto it = oldNumbers.find( pad->GetNumber() );
484 wxASSERT( it != oldNumbers.end() );
485
486 if( it != oldNumbers.end() )
487 {
488 storedPadNumbers.push_back( it->second.first );
489 pad->SetNumber( it->second.second );
490 SetLastPadNumber( it->second.second );
491 oldNumbers.erase( it );
492
493 const int newval = storedPadNumbers.front();
494 setPopupTextForValue( newval );
495 }
496
497 pad->ClearSelected();
498 getView()->Update( pad );
499 }
500 }
501 }
502 else if( evt->IsDblClick( BUT_LEFT ) )
503 {
504 commit.Push( _( "Renumber Pads" ) );
505 frame()->PopTool( aEvent );
506 break;
507 }
508 else if( evt->IsClick( BUT_RIGHT ) )
509 {
511 }
512 else
513 {
514 evt->SetPassEvent();
515 }
516
517 // Prepare the next loop by updating the old cursor mouse position
518 // to this last mouse cursor position
519 oldCursorPos = getViewControls()->GetCursorPosition();
520 statusPopup.Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
521 }
522
523 for( PAD* p : board()->GetFirstFootprint()->Pads() )
524 {
525 p->ClearSelected();
526 getView()->Update( p );
527 }
528
529 canvas()->SetStatusPopup( nullptr );
530 statusPopup.Hide();
531
532 canvas()->SetCurrentCursor( KICURSOR::ARROW );
534 return 0;
535}
536
537
538int PAD_TOOL::PlacePad( const TOOL_EVENT& aEvent )
539{
540 // When creating a new pad (in FP editor) we can use a new pad number
541 // or the last entered pad number
542 // neednewPadNumber = true to create a new pad number, false to use the last
543 // entered pad number
544 static bool neednewPadNumber;
545
547 return 0;
548
549 if( !board()->GetFirstFootprint() )
550 return 0;
551
552 struct PAD_PLACER : public INTERACTIVE_PLACER_BASE
553 {
554 PAD_PLACER( PAD_TOOL* aPadTool )
555 {
556 neednewPadNumber = true; // Use a new pad number when creatin a pad by default
557 m_padTool = aPadTool;
558 }
559
560 virtual ~PAD_PLACER()
561 {
562 }
563
564 std::unique_ptr<BOARD_ITEM> CreateItem() override
565 {
566 PAD* pad = new PAD( m_board->GetFirstFootprint() );
567 PAD* master = m_frame->GetDesignSettings().m_Pad_Master.get();
568
569 pad->ImportSettingsFrom( *master );
570
571 // If the footprint type and master pad type directly conflict then make some
572 // adjustments. Otherwise assume the user set what they wanted.
573 // Note also a HEATSINK pad (thermal via) is allowed in SMD footprint
574 if( ( m_board->GetFirstFootprint()->GetAttributes() & FP_SMD )
575 && master->GetAttribute() == PAD_ATTRIB::PTH )
576 {
577 if( pad->GetProperty() != PAD_PROP::HEATSINK )
578 {
579 pad->SetAttribute( PAD_ATTRIB::SMD );
580 pad->SetShape( PAD_SHAPE::ROUNDRECT );
581 pad->SetSizeX( 1.5 * pad->GetSizeY() );
582 pad->SetLayerSet( PAD::SMDMask() );
583 }
584 }
585 else if( ( m_board->GetFirstFootprint()->GetAttributes() & FP_THROUGH_HOLE )
586 && master->GetAttribute() == PAD_ATTRIB::SMD )
587 {
588 pad->SetAttribute( PAD_ATTRIB::PTH );
589 pad->SetShape( PAD_SHAPE::CIRCLE );
590 pad->SetSize( VECTOR2I( pad->GetSizeX(), pad->GetSizeX() ) );
591
592 // Gives an acceptable drill size: it cannot be 0, but from pad master
593 // it is currently 0, therefore change it:
594 pad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
595 int hole_size = pad->GetSizeX() / 2;
596 pad->SetDrillSize( VECTOR2I( hole_size, hole_size ) );
597
598 pad->SetLayerSet( PAD::PTHMask() );
599 }
600
601 if( pad->CanHaveNumber() )
602 {
603 wxString padNumber = m_padTool->GetLastPadNumber();
604
605 // Use the last entered pad number when recreating a pad without using the
606 // previously created pad, and a new number when creating a really new pad
607 if( neednewPadNumber )
608 padNumber = m_board->GetFirstFootprint()->GetNextPadNumber( padNumber );
609
610 pad->SetNumber( padNumber );
611 m_padTool->SetLastPadNumber( padNumber );
612
613 // If a pad is recreated and the previously created was not placed, use
614 // the last entered pad number
615 neednewPadNumber = false;
616 }
617
618 return std::unique_ptr<BOARD_ITEM>( pad );
619 }
620
621 bool PlaceItem( BOARD_ITEM *aItem, BOARD_COMMIT& aCommit ) override
622 {
623 PAD* pad = dynamic_cast<PAD*>( aItem );
624 // We are using this pad number.
625 // therefore use a new pad number for a newly created pad
626 neednewPadNumber = true;
627
628 if( pad )
629 {
630 m_frame->GetDesignSettings().m_Pad_Master->ImportSettingsFrom( *pad );
631 aCommit.Add( aItem );
632 return true;
633 }
634
635 return false;
636 }
637
638 PAD_TOOL* m_padTool;
639 };
640
641 PAD_PLACER placer( this );
642
643 doInteractiveItemPlacement( aEvent, &placer, _( "Place pad" ),
645
646 return 0;
647}
648
649
650int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent )
651{
653 return 0;
654
655 Activate();
656
657 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view()->GetPainter() );
658 PCB_RENDER_SETTINGS* settings = painter->GetSettings();
660
661 if( m_editPad != niluuid )
662 {
663 PAD* pad = dynamic_cast<PAD*>( frame()->GetItem( m_editPad ) );
664
665 if( pad )
666 {
667 BOARD_COMMIT commit( frame() );
668 commit.Modify( pad );
669
670 std::vector<PCB_SHAPE*> mergedShapes = RecombinePad( pad, false );
671
672 for( PCB_SHAPE* shape : mergedShapes )
673 commit.Remove( shape );
674
675 commit.Push( _( "Edit Pad" ) );
676 }
677
679 }
680 else if( selection.Size() == 1 && selection[0]->Type() == PCB_PAD_T )
681 {
682 PCB_LAYER_ID layer;
683 PAD* pad = static_cast<PAD*>( selection[0] );
684 BOARD_COMMIT commit( frame() );
685
686 commit.Modify( pad );
687 explodePad( pad, &layer, commit );
688 commit.Push( _( "Edit Pad" ) );
689
691 frame()->SetActiveLayer( layer );
692
693 settings->m_PadEditModePad = pad;
695 }
696
697 if( m_editPad == niluuid )
699
700 return 0;
701}
702
703
705{
706 PAD* flaggedPad = nullptr;
707 KIID flaggedPadId = niluuid;
708
709 for( FOOTPRINT* fp : board()->Footprints() )
710 {
711 for( PAD* pad : fp->Pads() )
712 {
713 if( pad->IsEntered() )
714 {
715 flaggedPad = pad;
716 flaggedPadId = pad->m_Uuid;
717 break;
718 }
719 }
720 }
721
722 if( flaggedPadId != m_editPad )
723 {
724 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view()->GetPainter() );
725 PCB_RENDER_SETTINGS* settings = painter->GetSettings();
726
727 m_editPad = flaggedPadId;
728 settings->m_PadEditModePad = flaggedPad;
729
730 if( flaggedPad )
732 else
734 }
735
736 return 0;
737}
738
739
741{
743 WX_INFOBAR* infoBar = frame()->GetInfoBar();
744 wxString msg;
745
747 [&]( KIGFX::VIEW_ITEM* aItem ) -> bool
748 {
749 return dynamic_cast<PAD*>( aItem ) != nullptr;
750 } );
751
753
754 if( opts.m_ContrastModeDisplay == HIGH_CONTRAST_MODE::NORMAL )
755 {
756 opts.m_ContrastModeDisplay = HIGH_CONTRAST_MODE::DIMMED;
757 frame()->SetDisplayOptions( opts );
758 }
759
760 if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() )
761 {
762 msg.Printf( _( "Pad Edit Mode. Press %s again to exit." ),
764 }
765 else
766 {
767 msg.Printf( _( "Pad Edit Mode. Press %s to exit." ),
769 }
770
771 infoBar->RemoveAllButtons();
772 infoBar->ShowMessage( msg, wxICON_INFORMATION );
773}
774
775
777{
778 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view()->GetPainter() );
779 PCB_RENDER_SETTINGS* settings = painter->GetSettings();
781
782 settings->m_PadEditModePad = nullptr;
783
785 {
787 frame()->SetDisplayOptions( opts );
788 }
789
790 // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as
791 // they won't be found in the view layer's itemset for re-painting.
793 [&]( KIGFX::VIEW_ITEM* aItem ) -> bool
794 {
795 return dynamic_cast<PAD*>( aItem ) != nullptr;
796 } );
797
798 // Refresh now (otherwise there's an uncomfortably long pause while the infoBar
799 // closes before refresh).
800 canvas()->ForceRefresh();
801
802 frame()->GetInfoBar()->Dismiss();
803}
804
805
806void PAD_TOOL::explodePad( PAD* aPad, PCB_LAYER_ID* aLayer, BOARD_COMMIT& aCommit )
807{
808 if( aPad->IsOnLayer( F_Cu ) )
809 *aLayer = F_Cu;
810 else if( aPad->IsOnLayer( B_Cu ) )
811 *aLayer = B_Cu;
812 else
813 *aLayer = *aPad->GetLayerSet().UIOrder();
814
815 if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
816 {
817 for( const std::shared_ptr<PCB_SHAPE>& primitive : aPad->GetPrimitives() )
818 {
819 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( primitive->Duplicate() );
820
821 shape->SetParent( board()->GetFirstFootprint() );
822 shape->Rotate( VECTOR2I( 0, 0 ), aPad->GetOrientation() );
823 shape->Move( aPad->ShapePos() );
824 shape->SetLayer( *aLayer );
825
826 if( shape->IsProxyItem() && shape->GetShape() == SHAPE_T::SEGMENT )
827 {
828 if( aPad->GetThermalSpokeWidth() )
829 shape->SetWidth( aPad->GetThermalSpokeWidth() );
830 else
832 }
833
834 aCommit.Add( shape );
835 }
836
837 aPad->SetShape( aPad->GetAnchorPadShape() );
838 aPad->DeletePrimitivesList();
839 }
840
841 aPad->SetFlags( ENTERED );
842 m_editPad = aPad->m_Uuid;
843}
844
845
846std::vector<PCB_SHAPE*> PAD_TOOL::RecombinePad( PAD* aPad, bool aIsDryRun )
847{
848 int maxError = board()->GetDesignSettings().m_MaxError;
850
851 // Don't leave an object in the point editor that might no longer exist after recombining.
853
854 for( BOARD_ITEM* item : footprint->GraphicalItems() )
855 item->ClearFlags( SKIP_STRUCT );
856
857 auto findNext =
858 [&]( PCB_LAYER_ID aLayer ) -> PCB_SHAPE*
859 {
860 SHAPE_POLY_SET padPoly;
861 aPad->TransformShapeToPolygon( padPoly, aLayer, 0, maxError, ERROR_INSIDE );
862
863 for( BOARD_ITEM* item : footprint->GraphicalItems() )
864 {
865 PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( item );
866
867 if( !shape || ( shape->GetFlags() & SKIP_STRUCT ) )
868 continue;
869
870 if( shape->GetLayer() != aLayer )
871 continue;
872
873 if( shape->IsProxyItem() ) // Pad number (and net name) box
874 return shape;
875
876 SHAPE_POLY_SET drawPoly;
877 shape->TransformShapeToPolygon( drawPoly, aLayer, 0, maxError, ERROR_INSIDE );
878 drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST );
879
880 if( !drawPoly.IsEmpty() )
881 return shape;
882 }
883
884 return nullptr;
885 };
886
887 auto findMatching =
888 [&]( PCB_SHAPE* aShape ) -> std::vector<PCB_SHAPE*>
889 {
890 std::vector<PCB_SHAPE*> matching;
891
892 for( BOARD_ITEM* item : footprint->GraphicalItems() )
893 {
894 PCB_SHAPE* other = dynamic_cast<PCB_SHAPE*>( item );
895
896 if( !other || ( other->GetFlags() & SKIP_STRUCT ) )
897 continue;
898
899 if( aPad->GetLayerSet().test( other->GetLayer() )
900 && aShape->Compare( other ) == 0 )
901 {
902 matching.push_back( other );
903 }
904 }
905
906 return matching;
907 };
908
909 PCB_LAYER_ID layer;
910 std::vector<PCB_SHAPE*> mergedShapes;
911
912 if( aPad->IsOnLayer( F_Cu ) )
913 layer = F_Cu;
914 else if( aPad->IsOnLayer( B_Cu ) )
915 layer = B_Cu;
916 else
917 layer = *aPad->GetLayerSet().UIOrder();
918
919 // If there are intersecting items to combine, we need to first make sure the pad is a
920 // custom-shape pad.
921 if( !aIsDryRun && findNext( layer ) && aPad->GetShape() != PAD_SHAPE::CUSTOM )
922 {
923 if( aPad->GetShape() == PAD_SHAPE::CIRCLE || aPad->GetShape() == PAD_SHAPE::RECTANGLE )
924 {
925 // Use the existing pad as an anchor
926 aPad->SetAnchorPadShape( aPad->GetShape() );
927 aPad->SetShape( PAD_SHAPE::CUSTOM );
928 }
929 else
930 {
931 // Create a new circular anchor and convert existing pad to a polygon primitive
932 SHAPE_POLY_SET existingOutline;
933 aPad->TransformShapeToPolygon( existingOutline, layer, 0, maxError, ERROR_INSIDE );
934
935 int minExtent = std::min( aPad->GetSize().x, aPad->GetSize().y );
936 aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE );
937 aPad->SetSize( VECTOR2I( minExtent, minExtent ) );
938 aPad->SetShape( PAD_SHAPE::CUSTOM );
939
940 PCB_SHAPE* shape = new PCB_SHAPE( nullptr, SHAPE_T::POLY );
941 shape->SetFilled( true );
942 shape->SetStroke( STROKE_PARAMS( 0, LINE_STYLE::SOLID ) );
943 shape->SetPolyShape( existingOutline );
944 shape->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() );
945 shape->Move( - aPad->ShapePos() );
946 aPad->AddPrimitive( shape );
947 }
948 }
949
950 while( PCB_SHAPE* fpShape = findNext( layer ) )
951 {
952 fpShape->SetFlags( SKIP_STRUCT );
953
954 mergedShapes.push_back( fpShape );
955
956 if( !aIsDryRun )
957 {
958 PCB_SHAPE* primitive = static_cast<PCB_SHAPE*>( fpShape->Duplicate() );
959
960 primitive->SetParent( nullptr );
961 primitive->Move( - aPad->ShapePos() );
962 primitive->Rotate( VECTOR2I( 0, 0 ), - aPad->GetOrientation() );
963
964 aPad->AddPrimitive( primitive );
965 }
966
967 // See if there are other shapes that match and mark them for delete. (KiCad won't
968 // produce these, but old footprints from other vendors have them.)
969 for( PCB_SHAPE* other : findMatching( fpShape ) )
970 {
971 other->SetFlags( SKIP_STRUCT );
972 mergedShapes.push_back( other );
973 }
974 }
975
976 for( BOARD_ITEM* item : footprint->GraphicalItems() )
977 item->ClearFlags( SKIP_STRUCT );
978
979 if( !aIsDryRun )
980 aPad->ClearFlags( ENTERED );
981
982 return mergedShapes;
983}
984
985
987{
991
994
997
999}
@ NORMAL
Use all material properties from model file.
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
HIGH_CONTRAST_MODE
Determine how inactive layers should be displayed.
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
virtual void Revert() override
std::unique_ptr< PAD > m_Pad_Master
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:248
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:414
FOOTPRINTS & Footprints()
Definition: board.h:318
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:806
void Empty()
Clear the list.
Definition: collector.h:89
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
COMMIT & Remove(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been removed.
Definition: commit.h:92
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
static DELETED_BOARD_ITEM * GetInstance()
Definition: board_item.h:427
Dialog for enumerating pads.
WX_INFOBAR * GetInfoBar()
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void ForceRefresh()
Force a redraw.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
void SetStatusPopup(wxWindow *aPopup)
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:125
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM_FLAGS GetFlags() const
Definition: eda_item.h:126
void SetFilled(bool aFlag)
Definition: eda_shape.h:95
SHAPE_T GetShape() const
Definition: eda_shape.h:119
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:271
void SetWidth(int aWidth)
Definition: eda_shape.h:108
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:264
static const TOOL_EVENT UndoRedoPostEvent
Definition: actions.h:281
EDA_ANGLE GetOrientation() const
Definition: footprint.h:209
PADS & Pads()
Definition: footprint.h:188
const LIB_ID & GetFPID() const
Definition: footprint.h:230
DRAWINGS & GraphicalItems()
Definition: footprint.h:191
A general implementation of a COLLECTORS_GUIDE.
Definition: collectors.h:323
void SetIgnoreMTextsMarkedNoShow(bool ignore)
Definition: collectors.h:409
void SetIgnoreModulesRefs(bool ignore)
Definition: collectors.h:463
void SetIgnoreModulesVals(bool ignore)
Definition: collectors.h:457
void SetIgnoreMTextsOnFront(bool ignore)
Definition: collectors.h:421
void SetIgnoreMTextsOnBack(bool ignore)
Definition: collectors.h:415
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:206
void Collect(BOARD_ITEM *aItem, const std::vector< KICAD_T > &aScanList, const VECTOR2I &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
Definition: collectors.cpp:481
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:164
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:169
PCB specific render settings.
Definition: pcb_painter.h:77
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
An abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:84
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1636
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
void UpdateAllItemsConditionally(int aUpdateFlags, std::function< bool(VIEW_ITEM *)> aCondition)
Update items in the view according to the given flags and condition.
Definition: view.cpp:1528
Definition: kiid.h:49
LSEQ UIOrder() const
Definition: lset.cpp:1012
Tool relating to pads and pad settings.
Definition: pad_tool.h:37
void Reset(RESET_REASON aReason) override
Basic initialization.
Definition: pad_tool.cpp:63
int OnUndoRedo(const TOOL_EVENT &aEvent)
Definition: pad_tool.cpp:704
HIGH_CONTRAST_MODE m_previousHighContrastMode
Definition: pad_tool.h:99
void explodePad(PAD *aPad, PCB_LAYER_ID *aLayer, BOARD_COMMIT &aCommit)
Definition: pad_tool.cpp:806
~PAD_TOOL()
React to model/view changes.
Definition: pad_tool.cpp:59
void setTransitions() override
< Bind handlers to corresponding TOOL_ACTIONs.
Definition: pad_tool.cpp:986
int EditPad(const TOOL_EVENT &aEvent)
Enter/exit WYSIWYG pad shape editing.
Definition: pad_tool.cpp:650
void ExitPadEditMode()
Definition: pad_tool.cpp:776
KIID m_editPad
Definition: pad_tool.h:100
int copyPadSettings(const TOOL_EVENT &aEvent)
Push pad settings from a pad to other pads on board or footprint.
Definition: pad_tool.cpp:171
void enterPadEditMode()
Definition: pad_tool.cpp:740
int pastePadProperties(const TOOL_EVENT &aEvent)
Copy pad settings from a pad to the board design settings.
Definition: pad_tool.cpp:144
int PlacePad(const TOOL_EVENT &aEvent)
Place a pad in footprint editor.
Definition: pad_tool.cpp:538
int EnumeratePads(const TOOL_EVENT &aEvent)
Tool for quick pad enumeration.
Definition: pad_tool.cpp:301
PAD_TOOL()
Definition: pad_tool.cpp:52
bool Init() override
Init() is called once upon a registration of the tool.
Definition: pad_tool.cpp:85
void SetLastPadNumber(const wxString &aPadNumber)
Definition: pad_tool.h:69
std::vector< PCB_SHAPE * > RecombinePad(PAD *aPad, bool aIsDryRun)
Recombine an exploded pad (or one produced with overlapping polygons in an older version).
Definition: pad_tool.cpp:846
wxString m_lastPadNumber
Definition: pad_tool.h:97
int pushPadSettings(const TOOL_EVENT &aEvent)
Definition: pad_tool.cpp:240
Definition: pad.h:59
bool IsAperturePad() const
Definition: pad.h:381
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:371
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pad.h:618
PAD_ATTRIB GetAttribute() const
Definition: pad.h:374
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:190
void DeletePrimitivesList()
Clear the basic shapes list.
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:301
VECTOR2I ShapePos() const
Definition: pad.cpp:757
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
Definition: pad.cpp:1596
void ImportSettingsFrom(const PAD &aMasterPad)
Import the pad settings from aMasterPad.
Definition: pad.cpp:1481
PAD_SHAPE GetShape() const
Definition: pad.h:190
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition: pad.h:342
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:197
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:181
int GetThermalSpokeWidth() const
Definition: pad.h:519
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:229
void AddPrimitive(PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
void SetSize(const VECTOR2I &aSize)
Definition: pad.h:243
const VECTOR2I & GetSize() const
Definition: pad.h:244
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:203
static TOOL_ACTION recombinePad
Definition: pcb_actions.h:475
static TOOL_ACTION enumeratePads
Tool for quick pad enumeration.
Definition: pcb_actions.h:478
static TOOL_ACTION pushPadSettings
Copy the current pad's settings to other pads in the footprint or on the board.
Definition: pcb_actions.h:498
static TOOL_ACTION mirrorH
Mirroring of selected items.
Definition: pcb_actions.h:139
static TOOL_ACTION copyPadSettings
Copy the selected pad's settings to the board design settings.
Definition: pcb_actions.h:492
static TOOL_ACTION placePad
Activation of the drawing tool (placing a PAD)
Definition: pcb_actions.h:472
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:174
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION explodePad
Definition: pcb_actions.h:474
static TOOL_ACTION applyPadSettings
Copy the default pad settings to the selected pad.
Definition: pcb_actions.h:495
static TOOL_ACTION mirrorV
Definition: pcb_actions.h:140
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:136
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:132
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:133
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
EDA_ITEM * GetItem(const KIID &aId) const override
Fetch an item by KIID.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Updates the current display options from the given options struct.
GENERAL_COLLECTORS_GUIDE GetCollectorsGuide()
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:306
bool IsProxyItem() const override
Definition: pcb_shape.h:107
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_shape.cpp:97
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
Definition: pcb_shape.cpp:568
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:235
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:83
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:67
KIGFX::PCB_VIEW * view() const
PCB_BASE_EDIT_FRAME * frame() const
BOARD * board() const
PCB_DRAW_PANEL_GAL * canvas() const
@ IPO_FLIP
Handle flip action in the loop by calling the item's flip method.
@ IPO_ROTATE
Handle the rotate action in the loop by calling the item's rotate method.
@ IPO_SINGLE_CLICK
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
@ IPO_REPEAT
Allow repeat placement of the item.
bool m_isFootprintEditor
void doInteractiveItemPlacement(const TOOL_EVENT &aTool, INTERACTIVE_PLACER_BASE *aPlacer, const wxString &aCommitMessage, int aOptions=IPO_ROTATE|IPO_FLIP|IPO_REPEAT)
Helper function for performing a common interactive idiom: wait for a left click, place an item there...
const PCB_SELECTION & selection() const
FOOTPRINT * footprint() const
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 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.
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
Represent a set of closed polygons.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
wxWindow * GetPanel()
Definition: status_popup.h:63
virtual void Popup(wxWindow *aFocus=nullptr)
virtual void Move(const wxPoint &aWhere)
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:84
void SetText(const wxString &aText)
Display a text.
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
@ MODEL_RELOAD
Model changes (the sheet for a schematic)
Definition: tool_base.h:80
Generic, UI-independent tool event.
Definition: tool_event.h:167
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
TOOL_MENU & GetToolMenu()
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:57
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
void RemoveAllButtons()
Remove all the buttons that have been added by the user.
Definition: wx_infobar.cpp:301
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:187
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:154
static PCB_SHAPE * findNext(PCB_SHAPE *aShape, const VECTOR2I &aPoint, const std::vector< PCB_SHAPE * > &aList, unsigned aLimit)
Search for a PCB_SHAPE matching a given end point or start point in a list.
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
#define ENTERED
indicates a group has been entered
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ FP_SMD
Definition: footprint.h:73
@ FP_THROUGH_HOLE
Definition: footprint.h:72
@ ERROR_INSIDE
wxString KeyNameFromKeyCode(int aKeycode, bool *aIsFound)
Return the key name from the key code.
KIID niluuid(0)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:96
@ F_Cu
Definition: layer_ids.h:65
This file contains miscellaneous commonly used macros and functions.
@ REPAINT
Item needs to be redrawn.
Definition: view_item.h:57
@ ALL
All except INITIAL_ADD.
Definition: view_item.h:58
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: gtk/ui.cpp:601
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
@ PAD_DRILL_SHAPE_CIRCLE
Definition: pad_shapes.h:70
static void doPushPadProperties(BOARD &board, const PAD &aSrcPad, BOARD_COMMIT &commit, bool aSameFootprints, bool aPadShapeFilter, bool aPadOrientFilter, bool aPadLayerFilter, bool aPadTypeFilter)
Definition: pad_tool.cpp:192
static std::optional< SEQUENTIAL_PAD_ENUMERATION_PARAMS > GetSequentialPadNumberingParams(wxWindow *aFrame)
Prompts the user for parameters for sequential pad numbering.
Definition: pad_tool.cpp:287
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
std::function< bool(const SELECTION &)> SELECTION_CONDITION
< Functor type that checks a specific condition for selected items.
const double IU_PER_MM
Definition: base_units.h:77
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
MAGNETIC_OPTIONS tracks
MAGNETIC_OPTIONS pads
Parameters for sequential pad numbering.
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_MM
Definition: zones.h:34