KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_pad_properties.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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2013 Dick Hollenbeck, [email protected]
6 * Copyright (C) 2008-2013 Wayne Stambaugh <[email protected]>
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <drc/drc_item.h>
28#include <base_units.h>
29#include <bitmaps.h>
30#include <board_commit.h>
31#include <board.h>
33#include <footprint.h>
34#include <confirm.h>
35#include <core/arraydim.h>
36#include <convert_basic_shapes_to_polygon.h> // for enum RECT_CHAMFER_POSITIONS definition
41#include <macros.h>
42#include <pad.h>
43#include <pad_utils.h>
44#include <pcb_base_frame.h>
46#include <pcb_painter.h>
47#include <pcbnew_settings.h>
49#include <view/view_controls.h>
51#include <tool/tool_manager.h>
52#include <tools/pad_tool.h>
53#include <advanced_config.h> // for pad property feature management
54#include <wx/choicdlg.h>
55
56
57int DIALOG_PAD_PROPERTIES::m_page = 0; // remember the last open page during session
58
59
60// list of pad shapes, ordered like the pad shape wxChoice in dialog.
62{
69 PAD_SHAPE::CHAMFERED_RECT, // choice = CHOICE_SHAPE_CHAMFERED_ROUNDED_RECT
70 PAD_SHAPE::CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
71 PAD_SHAPE::CUSTOM // choice = PAD_SHAPE::CUSTOM_RECT_ANCHOR
72};
73
74
75// the ordered index of the pad shape wxChoice in dialog.
76// keep it consistent with code_shape[] and dialog strings
78{
88};
89
90
92{
97 PAD_ATTRIB::SMD // Aperture pad :type SMD with no copper layers,
98 // only on tech layers (usually only on paste layer
99};
100
101
102// These define have the same value as the m_PadType wxChoice GetSelected() return value
103#define PTH_DLG_TYPE 0
104#define SMD_DLG_TYPE 1
105#define CONN_DLG_TYPE 2
106#define NPTH_DLG_TYPE 3
107#define APERTURE_DLG_TYPE 4
108
109
111{
112 DIALOG_PAD_PROPERTIES dlg( this, aPad );
113
114 // QuasiModal required for NET_SELECTOR
115 dlg.ShowQuasiModal();
116}
117
118
121 m_parent( aParent ),
122 m_initialized( false ),
123 m_editLayer( F_Cu ),
124 m_posX( aParent, m_posXLabel, m_posXCtrl, m_posXUnits ),
125 m_posY( aParent, m_posYLabel, m_posYCtrl, m_posYUnits ),
126 m_sizeX( aParent, m_sizeXLabel, m_sizeXCtrl, m_sizeXUnits ),
127 m_sizeY( aParent, m_sizeYLabel, m_sizeYCtrl, m_sizeYUnits ),
128 m_offsetX( aParent, m_offsetXLabel, m_offsetXCtrl, m_offsetXUnits ),
129 m_offsetY( aParent, m_offsetYLabel, m_offsetYCtrl, m_offsetYUnits ),
130 m_padToDie( aParent, m_padToDieLabel, m_padToDieCtrl, m_padToDieUnits ),
131 m_trapDelta( aParent, m_trapDeltaLabel, m_trapDeltaCtrl, m_trapDeltaUnits ),
132 m_cornerRadius( aParent, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
133 m_cornerRatio( aParent, m_cornerRatioLabel, m_cornerRatioCtrl, m_cornerRatioUnits ),
134 m_chamferRatio( aParent, m_chamferRatioLabel, m_chamferRatioCtrl, m_chamferRatioUnits ),
135 m_mixedCornerRatio( aParent, m_mixedCornerRatioLabel, m_mixedCornerRatioCtrl,
136 m_mixedCornerRatioUnits ),
137 m_mixedChamferRatio( aParent, m_mixedChamferRatioLabel, m_mixedChamferRatioCtrl,
138 m_mixedChamferRatioUnits ),
139 m_holeX( aParent, m_holeXLabel, m_holeXCtrl, m_holeXUnits ),
140 m_holeY( aParent, m_holeYLabel, m_holeYCtrl, m_holeYUnits ),
141 m_clearance( aParent, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits ),
142 m_maskMargin( aParent, m_maskMarginLabel, m_maskMarginCtrl, m_maskMarginUnits ),
143 m_pasteMargin( aParent, m_pasteMarginLabel, m_pasteMarginCtrl, m_pasteMarginUnits ),
144 m_pasteMarginRatio( aParent, m_pasteMarginRatioLabel, m_pasteMarginRatioCtrl,
145 m_pasteMarginRatioUnits ),
146 m_thermalGap( aParent, m_thermalGapLabel, m_thermalGapCtrl, m_thermalGapUnits ),
147 m_spokeWidth( aParent, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ),
148 m_spokeAngle( aParent, m_spokeAngleLabel, m_spokeAngleCtrl, m_spokeAngleUnits ),
149 m_pad_orientation( aParent, m_PadOrientText, m_cb_padrotation, m_orientationUnits ),
150 m_teardropMaxLenSetting( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
151 m_teardropMaxHeightSetting( aParent, m_stTdMaxSize, m_tcMaxHeight, m_stMaxHeightUnits )
152{
153 SetName( PAD_PROPERTIES_DLG_NAME );
154 m_isFpEditor = dynamic_cast<FOOTPRINT_EDIT_FRAME*>( aParent ) != nullptr;
155
156 m_currentPad = aPad; // aPad can be NULL, if the dialog is called
157 // from the footprint editor to set default pad setup
158
160
161 // Configure display origin transforms
164
167
169
170 m_FlippedWarningIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
171 m_nonCopperWarningIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
172 m_legacyTeardropsIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
173
175 m_previewPad = new PAD( (FOOTPRINT*) nullptr );
176
177 if( aPad )
178 {
179 SetTitle( _( "Pad Properties" ) );
180
181 *m_previewPad = *aPad;
184 }
185 else
186 {
187 SetTitle( _( "Default Pad Properties for Add Pad Tool" ) );
188
191 }
192
193 // TODO(JE) padstacks: should this be re-run when pad mode changes?
194 // Pads have a hardcoded internal rounding ratio which is 0.25 by default, even if
195 // they're not a rounded shape. This makes it hard to detect an intentional 0.25
196 // ratio, or one that's only there because it's the PAD default.
197 // Zero it out here to mark that we should recompute a better ratio if the user
198 // selects a pad shape which would need a default rounding ratio computed for it
200 [&]( PCB_LAYER_ID aLayer )
201 {
204 } );
205
206 if( m_isFpEditor )
207 {
208 m_padNetLabel->Show( false );
209 m_padNetSelector->Show( false );
210 }
211
212 m_FlippedWarningSizer->Show( false );
213
214 // Pad needs to have a parent for painting; use the parent board for its design settings
215 if( !m_previewPad->GetParent() )
217
218 m_cornerRatio.SetUnits( EDA_UNITS::PERCENT );
219 m_chamferRatio.SetUnits( EDA_UNITS::PERCENT );
220 m_mixedCornerRatio.SetUnits( EDA_UNITS::PERCENT );
221 m_mixedChamferRatio.SetUnits( EDA_UNITS::PERCENT );
222 m_pad_orientation.SetUnits( EDA_UNITS::DEGREES );
224
225 m_spokeAngle.SetUnits( EDA_UNITS::DEGREES );
227
229
230 m_pasteMarginRatio.SetUnits( EDA_UNITS::PERCENT );
232
233 initValues();
234
235 wxFont infoFont = KIUI::GetInfoFont( this );
236 m_copperLayersLabel->SetFont( infoFont );
237 m_techLayersLabel->SetFont( infoFont );
238 m_parentInfo->SetFont( infoFont );
239 m_teardropShapeLabel->SetFont( infoFont );
240
241 infoFont.SetStyle( wxFONTSTYLE_ITALIC );
242 m_nonCopperNote->SetFont( infoFont );
243 m_staticTextInfoPaste->SetFont( infoFont );
244
247
248 // Usually, TransferDataToWindow is called by OnInitDialog
249 // calling it here fixes all widget sizes so FinishDialogSettings can safely fix minsizes
251
252 // Initialize canvas to be able to display the dummy pad:
254
255 m_notebook->SetSelection( m_page );
256
257 switch( m_page )
258 {
259 default:
260 case 0: SetInitialFocus( m_padNumCtrl ); break;
261 case 1: SetInitialFocus( m_thermalGapCtrl ); break;
262 case 2: SetInitialFocus( m_clearanceCtrl ); break;
263 }
264
266 m_initialized = true;
267
268 m_padNetSelector->Connect( FILTERED_ITEM_SELECTED,
269 wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ),
270 nullptr, this );
271
272 if( m_padType->GetSelection() != PTH_DLG_TYPE && m_padType->GetSelection() != NPTH_DLG_TYPE )
273 {
274 m_gbSizerHole->Show( false );
275 m_staticline6->Show( false );
276 }
277
278 // Now all widgets have the size fixed, call FinishDialogSettings
280
281 // Update widgets
282 wxUpdateUIEvent dummyUI;
283 OnUpdateUI( dummyUI );
284
285 // Post a dummy size event to force the pad preview panel to update the
286 // view: actual size, best zoom ... after the frame is shown
287 PostSizeEvent();
288}
289
290
292{
293 m_padNetSelector->Disconnect( FILTERED_ITEM_SELECTED,
294 wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ),
295 nullptr, this );
296
297 m_page = m_notebook->GetSelection();
298
299 // Remove the preview pad from the group of the actual pad before deletion
300 if( m_previewPad )
301 m_previewPad->SetParentGroup( nullptr );
302
303 delete m_previewPad;
304 delete m_axisOrigin;
305}
306
307
308// Store the pad draw option during a session.
310
311
312void DIALOG_PAD_PROPERTIES::OnInitDialog( wxInitDialogEvent& event )
313{
314 m_selectedColor = COLOR4D( 1.0, 1.0, 1.0, 0.7 );
315
316 // Needed on some WM to be sure the pad is redrawn according to the final size
317 // of the canvas, with the right zoom factor
318 redraw();
319}
320
321
322void DIALOG_PAD_PROPERTIES::OnCancel( wxCommandEvent& event )
323{
324 // Mandatory to avoid m_panelShowPadGal trying to draw something
325 // in a non valid context during closing process:
327
328 // Now call default handler for wxID_CANCEL command event
329 event.Skip();
330}
331
332
334{
336 COLOR_SETTINGS* colorSettings = m_parent->GetColorSettings();
337
338 opts.m_forceDisplayCursor = false;
339
340 // Initialize the canvas to display the pad
341 m_padPreviewGAL = new PCB_DRAW_PANEL_GAL( m_boardViewPanel, -1, wxDefaultPosition,
342 wxDefaultSize, opts,
344
345 m_padPreviewSizer->Add( m_padPreviewGAL, 12, wxEXPAND | wxALL, 5 );
346
347 // Show the X and Y axis. It is useful because pad shape can have an offset
348 // or be a complex shape.
353
356 m_padPreviewGAL->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
357
358 KIGFX::VIEW_CONTROLS* parentViewControls = m_parent->GetCanvas()->GetViewControls();
359 m_padPreviewGAL->GetViewControls()->ApplySettings( parentViewControls->GetSettings() );
360
361 m_padPreviewGAL->Show();
362
364
365 // fix the pad render mode (filled/not filled)
366 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
367
368 settings->m_ForcePadSketchModeOn = m_cbShowPadOutline->IsChecked();
369 settings->SetHighContrast( false );
370 settings->m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
371
372 // gives a non null grid size (0.001mm) because GAL layer does not like a 0 size grid:
373 double gridsize = 0.001 * pcbIUScale.IU_PER_MM;
374 view->GetGAL()->SetGridSize( VECTOR2D( gridsize, gridsize ) );
375
376 // And do not show the grid:
377 view->GetGAL()->SetGridVisibility( false );
378 view->GetGAL()->SetAxesEnabled( false );
379 view->Add( m_previewPad );
380 view->Add( m_axisOrigin );
381
383 Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
384}
385
386
388{
391 redraw();
392}
393
394
395void DIALOG_PAD_PROPERTIES::OnEditLayerChanged( wxCommandEvent& aEvent )
396{
397 // Save data from the previous layer
399
400 switch( m_previewPad->Padstack().Mode() )
401 {
402 default:
405 break;
406
408 switch( m_cbEditLayer->GetSelection() )
409 {
410 default:
411 case 0: m_editLayer = F_Cu; break;
412 case 1: m_editLayer = PADSTACK::INNER_LAYERS; break;
413 case 2: m_editLayer = B_Cu; break;
414 }
415 break;
416
418 {
419 int layer = m_cbEditLayer->GetSelection();
420
421 if( layer < 0 )
422 layer = 0;
423
424 if( m_editLayerCtrlMap.contains( layer ) )
425 m_editLayer = m_editLayerCtrlMap.at( layer );
426 else
428 }
429 }
430
431 // Load controls with the current layer
433
434 wxCommandEvent cmd_event;
435 OnPadShapeSelection( cmd_event );
436 OnOffsetCheckbox( cmd_event );
437
438 redraw();
439}
440
441
443{
444 // Note: use ChangeValue() to avoid generating a wxEVT_TEXT event
446
449
452}
453
454
456{
457 if( m_previewPad->GetShape( m_editLayer ) != PAD_SHAPE::ROUNDRECT
458 && m_previewPad->GetShape( m_editLayer ) != PAD_SHAPE::CHAMFERED_RECT )
459 {
460 return;
461 }
462
463 if( m_cornerRadius.GetValue() < 0 )
464 m_cornerRadiusCtrl->ChangeValue( "0" );
465
467 {
469
472
473 redraw();
474 }
475
476 if( m_initialized )
477 OnModify();
478}
479
480
482{
483 if( m_previewPad->GetShape( m_editLayer ) != PAD_SHAPE::ROUNDRECT
484 && m_previewPad->GetShape( m_editLayer ) != PAD_SHAPE::CHAMFERED_RECT )
485 {
486 return;
487 }
488
489 wxObject* ctrl = event.GetEventObject();
490 wxString value = event.GetString();
491 bool changed = false;
492
493 if( ctrl == m_cornerRatioCtrl || ctrl == m_mixedCornerRatioCtrl )
494 {
495 double ratioPercent;
496
497 if( value.ToDouble( &ratioPercent ) )
498 {
499 // Clamp ratioPercent to acceptable value (0.0 to 50.0)
500 if( ratioPercent < 0.0 )
501 {
504 }
505 else if( ratioPercent > 50.0 )
506 {
509 }
510
511 if( ctrl == m_cornerRatioCtrl )
512 m_mixedCornerRatioCtrl->ChangeValue( value );
513 else
514 m_cornerRatioCtrl->ChangeValue( value );
515
516 changed = true;
517 }
518 }
519 else if( ctrl == m_chamferRatioCtrl || ctrl == m_mixedChamferRatioCtrl )
520 {
521 double ratioPercent;
522
523 if( value.ToDouble( &ratioPercent ) )
524 {
525 // Clamp ratioPercent to acceptable value (0.0 to 50.0)
526 if( ratioPercent < 0.0 )
527 {
530 }
531 else if( ratioPercent > 50.0 )
532 {
535 }
536
537 if( ctrl == m_chamferRatioCtrl )
538 m_mixedChamferRatioCtrl->ChangeValue( value );
539 else
540 m_chamferRatioCtrl->ChangeValue( value );
541
542 changed = true;
543 }
544 }
545
546 if( changed && transferDataToPad( m_previewPad ) )
548
549 redraw();
550
551 if( m_initialized )
552 OnModify();
553}
554
555
557{
558 wxString msg;
559
560 // Disable pad net name wxTextCtrl if the caller is the footprint editor
561 // because nets are living only in the board managed by the board editor
563
572 m_layerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
573 m_layerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
575
576 VECTOR2I absPos;
577
578 if( m_currentPad )
579 {
580 absPos = m_currentPad->GetPosition();
581
582 if( FOOTPRINT* footprint = m_currentPad->GetParentFootprint() )
583 {
585
586 if( footprint->IsFlipped() )
587 {
588 // flip pad (up/down) around its position
589 m_previewPad->Flip( m_previewPad->GetPosition(), FLIP_DIRECTION::TOP_BOTTOM );
590 relPos.y = - relPos.y;
591 }
592
593 m_previewPad->SetPosition( relPos );
595
596 // Display parent footprint info
597 msg.Printf( _("Footprint %s (%s), %s, rotated %g deg"),
598 footprint->Reference().GetShownText( false ),
599 footprint->Value().GetShownText( false ),
600 footprint->IsFlipped() ? _( "back side (mirrored)" ) : _( "front side" ),
601 footprint->GetOrientation().AsDegrees() );
602
603 m_FlippedWarningSizer->Show( footprint->IsFlipped() );
604 m_parentInfo->SetLabel( msg );
605 }
606
607 m_padNumCtrl->SetValue( m_previewPad->GetNumber() );
608 }
609 else
610 {
612 m_padNumCtrl->SetValue( padTool->GetLastPadNumber() );
613
615 {
617 {
618 case FOOTPRINT_ATTR_T::FP_THROUGH_HOLE:
619 m_previewPad->SetAttribute( PAD_ATTRIB::PTH );
620
621 if( m_previewPad->GetDrillSizeX() == 0 )
623
624 break;
625
626 case FOOTPRINT_ATTR_T::FP_SMD:
628 m_previewPad->SetAttribute( PAD_ATTRIB::SMD );
629 break;
630 }
631 }
632 }
633
635
637
638 // Display current pad parameters units:
639 m_posX.ChangeValue( absPos.x );
640 m_posY.ChangeValue( absPos.y );
641
644
645 // TODO(JE) padstacks -- does this need to be saved/restored every time the layer changes?
646 // Store the initial thermal spoke angle to restore it, because some initializations
647 // can change this value (mainly after m_PadShapeSelector initializations)
648 EDA_ANGLE spokeInitialAngle = m_previewPad->GetThermalSpokeAngle();
649
651
652 m_padToDieOpt->SetValue( m_previewPad->GetPadToDieLength() != 0 );
654
655 if( m_previewPad->GetLocalClearance().has_value() )
657 else
658 m_clearance.ChangeValue( wxEmptyString );
659
660 if( m_previewPad->GetLocalSolderMaskMargin().has_value() )
662 else
663 m_maskMargin.ChangeValue( wxEmptyString );
664
665 if( m_previewPad->GetLocalSolderPasteMargin().has_value() )
667 else
668 m_pasteMargin.ChangeValue( wxEmptyString );
669
672 else
673 m_pasteMarginRatio.ChangeValue( wxEmptyString );
674
677 else
679
680 if( m_previewPad->GetLocalThermalGapOverride().has_value() )
682 else
684
687
697
699 {
700 default:
701 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
702 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
703 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
704 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
705 }
706
708 m_ZoneCustomPadShape->SetSelection( 1 );
709 else
710 m_ZoneCustomPadShape->SetSelection( 0 );
711
712 // Type of pad selection
713 bool aperture =
714 m_previewPad->GetAttribute() == PAD_ATTRIB::SMD && m_previewPad->IsAperturePad();
715
716 if( aperture )
717 {
718 m_padType->SetSelection( APERTURE_DLG_TYPE );
719 }
720 else
721 {
722 switch( m_previewPad->GetAttribute() )
723 {
724 case PAD_ATTRIB::PTH: m_padType->SetSelection( PTH_DLG_TYPE ); break;
725 case PAD_ATTRIB::SMD: m_padType->SetSelection( SMD_DLG_TYPE ); break;
726 case PAD_ATTRIB::CONN: m_padType->SetSelection( CONN_DLG_TYPE ); break;
727 case PAD_ATTRIB::NPTH: m_padType->SetSelection( NPTH_DLG_TYPE ); break;
728 }
729 }
730
731 switch( m_previewPad->GetProperty() )
732 {
733 case PAD_PROP::NONE: m_choiceFabProperty->SetSelection( 0 ); break;
734 case PAD_PROP::BGA: m_choiceFabProperty->SetSelection( 1 ); break;
735 case PAD_PROP::FIDUCIAL_LOCAL: m_choiceFabProperty->SetSelection( 2 ); break;
736 case PAD_PROP::FIDUCIAL_GLBL: m_choiceFabProperty->SetSelection( 3 ); break;
737 case PAD_PROP::TESTPOINT: m_choiceFabProperty->SetSelection( 4 ); break;
738 case PAD_PROP::HEATSINK: m_choiceFabProperty->SetSelection( 5 ); break;
739 case PAD_PROP::CASTELLATED: m_choiceFabProperty->SetSelection( 6 ); break;
740 case PAD_PROP::MECHANICAL: m_choiceFabProperty->SetSelection( 7 ); break;
741 }
742
743 // Ensure the pad property is compatible with the pad type
744 if( m_previewPad->GetAttribute() == PAD_ATTRIB::NPTH )
745 {
746 m_choiceFabProperty->SetSelection( 0 );
747 m_choiceFabProperty->Enable( false );
748 }
749
750 if( m_previewPad->GetDrillShape() != PAD_DRILL_SHAPE::OBLONG )
751 m_holeShapeCtrl->SetSelection( 0 );
752 else
753 m_holeShapeCtrl->SetSelection( 1 );
754
757
758 // Update some dialog widgets state (Enable/disable options):
759 wxCommandEvent cmd_event;
760 OnPadShapeSelection( cmd_event );
761 OnOffsetCheckbox( cmd_event );
762
763 // Restore thermal spoke angle to its initial value, because it can be modified
764 // by the call to OnPadShapeSelection()
765 m_previewPad->SetThermalSpokeAngle( spokeInitialAngle );
767}
768
769
771{
773
776
780
782 {
784 m_trapAxisCtrl->SetSelection( 0 );
785 }
786 else
787 {
789 m_trapAxisCtrl->SetSelection( 1 );
790 }
791
792 switch( m_previewPad->GetShape( m_editLayer ) )
793 {
794 default:
795 case PAD_SHAPE::CIRCLE: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_CIRCLE ); break;
796 case PAD_SHAPE::OVAL: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_OVAL ); break;
797 case PAD_SHAPE::RECTANGLE: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_RECT ); break;
798 case PAD_SHAPE::TRAPEZOID: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_TRAPEZOID ); break;
799 case PAD_SHAPE::ROUNDRECT: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_ROUNDRECT ); break;
800
801 case PAD_SHAPE::CHAMFERED_RECT:
804 else
806 break;
807
808 case PAD_SHAPE::CUSTOM:
809 if( m_previewPad->GetAnchorPadShape( m_editLayer ) == PAD_SHAPE::RECTANGLE )
811 else
813 break;
814 }
815
816 int chamferPositions = m_previewPad->GetChamferPositions( m_editLayer );
817
818 m_cbTopLeft->SetValue( chamferPositions & RECT_CHAMFER_TOP_LEFT );
819 m_cbTopLeft1->SetValue( chamferPositions & RECT_CHAMFER_TOP_LEFT );
820 m_cbTopRight->SetValue( chamferPositions & RECT_CHAMFER_TOP_RIGHT );
821 m_cbTopRight1->SetValue( chamferPositions & RECT_CHAMFER_TOP_RIGHT );
822 m_cbBottomLeft->SetValue( chamferPositions & RECT_CHAMFER_BOTTOM_LEFT );
823 m_cbBottomLeft1->SetValue( chamferPositions & RECT_CHAMFER_BOTTOM_LEFT );
824 m_cbBottomRight->SetValue( chamferPositions & RECT_CHAMFER_BOTTOM_RIGHT );
825 m_cbBottomRight1->SetValue( chamferPositions & RECT_CHAMFER_BOTTOM_RIGHT );
826
828}
829
830
832{
833 // NOTE: synchronize changes here with DIALOG_TRACK_VIA_PROPERTIES::afterPadstackModeChanged
834
835 wxCHECK_MSG( m_board, /* void */, "Expected valid board in afterPadstackModeChanged" );
836 m_cbEditLayer->Clear();
837
838 switch( m_previewPad->Padstack().Mode() )
839 {
841 m_cbPadstackMode->SetSelection( 0 );
842 m_cbEditLayer->Append( m_board->GetLayerName( F_Cu ) );
843 m_cbEditLayer->Disable();
845 m_editLayerCtrlMap = { { 0, F_Cu } };
846 break;
847
849 {
850 m_cbPadstackMode->SetSelection( 1 );
851 m_cbEditLayer->Enable();
852
853 std::vector choices = {
855 _( "Inner Layers" ),
857 };
858
859 m_cbEditLayer->Append( choices );
860
862 { 0, F_Cu },
864 { 2, B_Cu }
865 };
866
867 if( m_editLayer != F_Cu && m_editLayer != B_Cu )
869
870 break;
871 }
872
874 {
875 m_cbPadstackMode->SetSelection( 2 );
876 m_cbEditLayer->Enable();
878
879 for( PCB_LAYER_ID layer : layers.UIOrder() )
880 {
881 int idx = m_cbEditLayer->Append( m_board->GetLayerName( layer ) );
882 m_editLayerCtrlMap[idx] = layer;
883 }
884
885 break;
886 }
887 }
888
889 for( const auto& [idx, layer] : m_editLayerCtrlMap )
890 {
891 if( layer == m_editLayer )
892 {
893 m_cbEditLayer->SetSelection( idx );
894 break;
895 }
896 }
897}
898
899
900void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
901{
902 redraw();
903 event.Skip();
904}
905
906
907void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
908{
910
912
913 // fix the pad render mode (filled/not filled)
914 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
915
916 settings->m_ForcePadSketchModeOn = m_cbShowPadOutline->IsChecked();
917 settings->SetHighContrast( false );
918 settings->m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
919
920 redraw();
921}
922
923
925{
926 switch( m_PadShapeSelector->GetSelection() )
927 {
931 m_shapePropsBook->SetSelection( 0 );
932 break;
933
935 m_shapePropsBook->SetSelection( 1 );
936 break;
937
939 {
940 m_shapePropsBook->SetSelection( 2 );
941
942 // Reasonable defaults
944 {
945 const double ipcRadiusRatio =
947 m_cornerRatio.ChangeDoubleValue( ipcRadiusRatio * 100 );
948 }
949
950 break;
951 }
952
954 m_shapePropsBook->SetSelection( 3 );
955
956 // Reasonable default
959
960 // Ensure the displayed value is up to date:
962
963 // A reasonable default is one corner chamfered (usual for some SMD pads).
964 if( !m_cbTopLeft->GetValue() && !m_cbTopRight->GetValue()
965 && !m_cbBottomLeft->GetValue() && !m_cbBottomRight->GetValue() )
966 {
967 m_cbTopLeft->SetValue( true );
968 m_cbTopRight->SetValue( false );
969 m_cbBottomLeft->SetValue( false );
970 m_cbBottomRight->SetValue( false );
971 }
972
973 break;
974
976 m_shapePropsBook->SetSelection( 4 );
977
978 // Reasonable defaults
981 {
982 const double ipcRadiusRatio =
986 }
987
988 // Ensure the displayed values are up to date:
991 break;
992
993 case CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR: // PAD_SHAPE::CUSTOM, circular anchor
994 case CHOICE_SHAPE_CUSTOM_RECT_ANCHOR: // PAD_SHAPE::CUSTOM, rect anchor
995 m_shapePropsBook->SetSelection( 0 );
996 break;
997 }
998
999 // Note: must do this before enabling/disabling m_sizeY as we're using that as a flag to see
1000 // what the last shape was.
1001 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE )
1002 {
1003 if( m_sizeYCtrl->IsEnabled() && m_spokeAngle.GetAngleValue() == ANGLE_90 )
1005 }
1006 else
1007 {
1008 if( !m_sizeYCtrl->IsEnabled() && m_spokeAngle.GetAngleValue() == ANGLE_45 )
1010 }
1011
1012 // Readjust props book size
1013 wxSize size = m_shapePropsBook->GetSize();
1014 size.y = m_shapePropsBook->GetPage( m_shapePropsBook->GetSelection() )->GetBestSize().y;
1015 m_shapePropsBook->SetMaxSize( size );
1016
1019
1020 m_offsetShapeOpt->Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE );
1021
1022 if( !m_offsetShapeOpt->IsEnabled() )
1023 m_offsetShapeOpt->SetValue( false );
1024
1025 // Show/hide controls depending on m_offsetShapeOpt being enabled
1026 m_offsetCtrls->Show( m_offsetShapeOpt->GetValue() );
1027 m_offsetShapeOptLabel->Show( m_offsetShapeOpt->GetValue() );
1028
1031
1032 for( size_t i = 0; i < m_notebook->GetPageCount(); ++i )
1033 m_notebook->GetPage( i )->Layout();
1034
1035 // Resize the dialog if its height is too small to show all widgets:
1036 if( m_MainSizer->GetSize().y < m_MainSizer->GetMinSize().y )
1037 m_MainSizer->SetSizeHints( this );
1038
1040 redraw();
1041
1042 if( m_initialized )
1043 OnModify();
1044}
1045
1046
1048{
1051 redraw();
1052
1053 if( m_initialized )
1054 OnModify();
1055}
1056
1057
1058void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
1059{
1061 redraw();
1062
1063 if( m_initialized )
1064 OnModify();
1065}
1066
1067
1069{
1070 m_rbCopperLayersSel->Clear();
1071
1072 switch( m_padType->GetSelection() )
1073 {
1074 case PTH_DLG_TYPE:
1075 m_rbCopperLayersSel->Append( _( "All copper layers" ) );
1076 m_rbCopperLayersSel->Append( wxString::Format( _( "%s, %s and connected layers" ),
1078 m_board->GetLayerName( B_Cu ) ) );
1079 m_rbCopperLayersSel->Append( _( "Connected layers only" ) );
1080 m_rbCopperLayersSel->Append( _( "None" ) );
1081 break;
1082
1083 case NPTH_DLG_TYPE:
1084 m_rbCopperLayersSel->Append( wxString::Format( _( "%s and %s" ),
1086 m_board->GetLayerName( B_Cu ) ) );
1089 m_rbCopperLayersSel->Append( _( "None" ) );
1090 break;
1091
1092 case SMD_DLG_TYPE:
1093 case CONN_DLG_TYPE:
1096 break;
1097
1098 case APERTURE_DLG_TYPE:
1099 m_rbCopperLayersSel->Append( _( "None" ) );
1100 break;
1101 }
1102}
1103
1104
1105void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
1106{
1107 bool hasHole = true;
1108 bool hasConnection = true;
1109 bool hasProperty = true;
1110
1111 switch( m_padType->GetSelection() )
1112 {
1113 case PTH_DLG_TYPE: hasHole = true; hasConnection = true; hasProperty = true; break;
1114 case SMD_DLG_TYPE: hasHole = false; hasConnection = true; hasProperty = true; break;
1115 case CONN_DLG_TYPE: hasHole = false; hasConnection = true; hasProperty = true; break;
1116 case NPTH_DLG_TYPE: hasHole = true; hasConnection = false; hasProperty = false; break;
1117 case APERTURE_DLG_TYPE: hasHole = false; hasConnection = false; hasProperty = true; break;
1118 }
1119
1120 // Update Layers dropdown list and selects the "best" layer set for the new pad type:
1123
1124 m_gbSizerHole->Show( hasHole );
1125 m_staticline6->Show( hasHole );
1126
1127 if( !hasHole )
1128 {
1129 m_holeX.ChangeValue( 0 );
1130 m_holeY.ChangeValue( 0 );
1131 }
1132 else if( m_holeX.GetValue() == 0 )
1133 {
1134 if( m_currentPad )
1135 {
1138 }
1139 else
1140 {
1142 }
1143 }
1144
1145 if( !hasConnection )
1146 {
1147 m_padNumCtrl->ChangeValue( wxEmptyString );
1149 m_padToDieOpt->SetValue( false );
1150 }
1151 else if( m_padNumCtrl->GetValue().IsEmpty() && m_currentPad )
1152 {
1153 m_padNumCtrl->ChangeValue( m_currentPad->GetNumber() );
1155 }
1156
1157 if( !hasProperty )
1158 m_choiceFabProperty->SetSelection( 0 );
1159
1160 m_choiceFabProperty->Enable( hasProperty );
1161
1163
1164 // For now, padstack controls only enabled for PTH pads
1165 bool enablePadstack = m_padType->GetSelection() == PTH_DLG_TYPE;
1166 m_padstackControls->Show( enablePadstack );
1167
1168 if( !enablePadstack )
1169 {
1170 m_editLayer = F_Cu;
1172 }
1173
1174 // Layout adjustment is needed if the hole details got shown/hidden
1175 m_LeftBoxSizer->Layout();
1176 redraw();
1177
1178 if( m_initialized )
1179 OnModify();
1180}
1181
1182
1183void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1184{
1185 bool hasHole = true;
1186 bool hasConnection = true;
1187
1188 switch( m_padType->GetSelection() )
1189 {
1190 case PTH_DLG_TYPE: /* PTH */ hasHole = true; hasConnection = true; break;
1191 case SMD_DLG_TYPE: /* SMD */ hasHole = false; hasConnection = true; break;
1192 case CONN_DLG_TYPE: /* CONN */ hasHole = false; hasConnection = true; break;
1193 case NPTH_DLG_TYPE: /* NPTH */ hasHole = true; hasConnection = false; break;
1194 case APERTURE_DLG_TYPE: /* Aperture */ hasHole = false; hasConnection = false; break;
1195 }
1196
1197 // Enable/disable hole controls
1198 m_holeShapeLabel->Enable( hasHole );
1199 m_holeShapeCtrl->Enable( hasHole );
1200 m_holeX.Enable( hasHole );
1201 m_holeY.Enable( hasHole && m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_OVAL );
1202
1203 // Enable/disable number and net
1204 m_padNumLabel->Enable( hasConnection );
1205 m_padNumCtrl->Enable( hasConnection );
1206
1207 if( m_padNetLabel->IsShown() )
1208 {
1209 m_padNetLabel->Enable( hasConnection && m_canEditNetName && m_currentPad );
1210 m_padNetSelector->Enable( hasConnection && m_canEditNetName && m_currentPad );
1211 }
1212
1213 // Enable/disable pad length-to-die
1214 m_padToDieOpt->Enable( hasConnection );
1215
1216 if( !m_padToDieOpt->IsEnabled() )
1217 m_padToDieOpt->SetValue( false );
1218
1219 // We can show/hide this here because it doesn't require the layout to be refreshed.
1220 // All the others have to be done in their event handlers because doing a layout here
1221 // causes infinite looping on MSW.
1222 m_padToDie.Show( m_padToDieOpt->GetValue() );
1223
1224 // Enable/disable Copper Layers control
1225 m_rbCopperLayersSel->Enable( m_padType->GetSelection() != APERTURE_DLG_TYPE );
1226
1228
1229 switch( m_padType->GetSelection() )
1230 {
1231 case PTH_DLG_TYPE:
1232 if( !cu_set.any() )
1233 m_stackupImagesBook->SetSelection( 3 );
1234 else if( !m_previewPad->GetRemoveUnconnected() )
1235 m_stackupImagesBook->SetSelection( 0 );
1236 else if( m_previewPad->GetKeepTopBottom() )
1237 m_stackupImagesBook->SetSelection( 1 );
1238 else
1239 m_stackupImagesBook->SetSelection( 2 );
1240
1241 break;
1242
1243 case NPTH_DLG_TYPE:
1244 if( cu_set.test( F_Cu ) && cu_set.test( B_Cu ) )
1245 m_stackupImagesBook->SetSelection( 4 );
1246 else if( cu_set.test( F_Cu ) )
1247 m_stackupImagesBook->SetSelection( 5 );
1248 else if( cu_set.test( B_Cu ) )
1249 m_stackupImagesBook->SetSelection( 6 );
1250 else
1251 m_stackupImagesBook->SetSelection( 7 );
1252
1253 break;
1254
1255 case SMD_DLG_TYPE:
1256 case CONN_DLG_TYPE:
1257 case APERTURE_DLG_TYPE:
1258 m_stackupImagesBook->ChangeSelection( 3 );
1259 break;
1260 }
1261
1263}
1264
1265
1267{
1268 event.Enable( !m_board->LegacyTeardrops() );
1269}
1270
1271
1273{
1274 bool isOnCopperLayer = ( m_previewPad->GetLayerSet() & LSET::AllCuMask() ).any();
1275 m_nonCopperWarningBook->ChangeSelection( isOnCopperLayer ? 0 : 1 );
1276}
1277
1278
1279void DIALOG_PAD_PROPERTIES::updatePadLayersList( LSET layer_mask, bool remove_unconnected,
1280 bool keep_top_bottom )
1281{
1283
1284 switch( m_padType->GetSelection() )
1285 {
1286 case PTH_DLG_TYPE:
1287 if( !layer_mask.any() )
1288 layer_mask = PAD::PTHMask();
1289
1290 if( !( layer_mask & LSET::AllCuMask() ).any() )
1291 m_rbCopperLayersSel->SetSelection( 3 );
1292 else if( !remove_unconnected )
1293 m_rbCopperLayersSel->SetSelection( 0 );
1294 else if( keep_top_bottom )
1295 m_rbCopperLayersSel->SetSelection( 1 );
1296 else
1297 m_rbCopperLayersSel->SetSelection( 2 );
1298
1299 break;
1300
1301 case SMD_DLG_TYPE:
1302 if( !layer_mask.any() )
1303 layer_mask = PAD::SMDMask();
1304
1305 if( layer_mask.test( F_Cu ) )
1306 m_rbCopperLayersSel->SetSelection( 0 );
1307 else
1308 m_rbCopperLayersSel->SetSelection( 1 );
1309
1310 break;
1311
1312 case CONN_DLG_TYPE:
1313 if( !layer_mask.any() )
1314 layer_mask = PAD::ConnSMDMask();
1315
1316 if( layer_mask.test( F_Cu ) )
1317 m_rbCopperLayersSel->SetSelection( 0 );
1318 else
1319 m_rbCopperLayersSel->SetSelection( 1 );
1320
1321 break;
1322
1323 case NPTH_DLG_TYPE:
1324 if( !layer_mask.any() )
1325 layer_mask = PAD::UnplatedHoleMask();
1326
1327 if( layer_mask.test( F_Cu ) && layer_mask.test( B_Cu ) )
1328 m_rbCopperLayersSel->SetSelection( 0 );
1329 else if( layer_mask.test( F_Cu ) )
1330 m_rbCopperLayersSel->SetSelection( 1 );
1331 else if( layer_mask.test( B_Cu ) )
1332 m_rbCopperLayersSel->SetSelection( 2 );
1333 else
1334 m_rbCopperLayersSel->SetSelection( 3 );
1335
1336 break;
1337
1338 case APERTURE_DLG_TYPE:
1339 if( !layer_mask.any() )
1340 layer_mask = PAD::ApertureMask();
1341
1342 m_rbCopperLayersSel->SetSelection( 0 );
1343 break;
1344 }
1345
1346 m_layerFrontAdhesive->SetValue( layer_mask[F_Adhes] );
1347 m_layerBackAdhesive->SetValue( layer_mask[B_Adhes] );
1348
1349 m_layerFrontPaste->SetValue( layer_mask[F_Paste] );
1350 m_layerBackPaste->SetValue( layer_mask[B_Paste] );
1351
1352 m_layerFrontSilk->SetValue( layer_mask[F_SilkS] );
1353 m_layerBackSilk->SetValue( layer_mask[B_SilkS] );
1354
1355 m_layerFrontMask->SetValue( layer_mask[F_Mask] );
1356 m_layerBackMask->SetValue( layer_mask[B_Mask] );
1357
1358 m_layerECO1->SetValue( layer_mask[Eco1_User] );
1359 m_layerECO2->SetValue( layer_mask[Eco2_User] );
1360
1361 m_layerUserDwgs->SetValue( layer_mask[Dwgs_User] );
1362}
1363
1364
1366{
1367 bool retVal = DIALOG_SHIM::Show( aShow );
1368
1369 if( aShow )
1370 {
1371 // It *should* work to set the stackup bitmap in the constructor, but it doesn't.
1372 // wxWidgets needs to have these set when the panel is visible for some reason.
1373 // https://gitlab.com/kicad/code/kicad/-/issues/5534
1374 m_stackupImage0->SetBitmap( KiBitmapBundle( BITMAPS::pads_reset_unused ) );
1375 m_stackupImage1->SetBitmap( KiBitmapBundle( BITMAPS::pads_remove_unused_keep_bottom ) );
1376 m_stackupImage2->SetBitmap( KiBitmapBundle( BITMAPS::pads_remove_unused ) );
1377 m_stackupImage4->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_top_bottom ) );
1378 m_stackupImage5->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_top ) );
1379 m_stackupImage6->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_bottom ) );
1380 m_stackupImage7->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth ) );
1381
1382 Layout();
1383 }
1384
1385 return retVal;
1386}
1387
1388
1389void DIALOG_PAD_PROPERTIES::OnSetCopperLayers( wxCommandEvent& event )
1390{
1392 redraw();
1393
1394 if( m_initialized )
1395 OnModify();
1396}
1397
1398
1399void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
1400{
1402 redraw();
1403
1404 if( m_initialized )
1405 OnModify();
1406}
1407
1408
1410{
1412
1413 wxArrayString error_msgs;
1414 wxArrayString warning_msgs;
1415
1417 [&]( int errorCode, const wxString& msg )
1418 {
1419 if( errorCode == DRCE_PADSTACK_INVALID )
1420 error_msgs.Add( _( "Error: " ) + msg );
1421 else if( errorCode == DRCE_PADSTACK )
1422 warning_msgs.Add( _( "Warning: " ) + msg );
1423 else if( errorCode == DRCE_PAD_TH_WITH_NO_HOLE )
1424 error_msgs.Add( _( "Error: Through hole pad has no hole." ) );
1425 } );
1426
1427 if( error_msgs.GetCount() || warning_msgs.GetCount() )
1428 {
1429 wxString title = error_msgs.GetCount() ? _( "Pad Properties Errors" )
1430 : _( "Pad Properties Warnings" );
1431 HTML_MESSAGE_BOX dlg( this, title );
1432
1433 wxArrayString msgs = error_msgs;
1434
1435 for( const wxString& msg : warning_msgs )
1436 msgs.Add( msg );
1437
1438 dlg.ListSet( msgs );
1439
1440 dlg.ShowModal();
1441 }
1442
1443 return error_msgs.GetCount() == 0;
1444}
1445
1446
1448{
1449 if( !m_initialized )
1450 return;
1451
1453 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view->GetPainter() );
1454 KIGFX::PCB_RENDER_SETTINGS* settings = painter->GetSettings();
1455
1457
1458 // The layer used to place primitive items selected when editing custom pad shapes
1459 // we use here a layer never used in a pad:
1460 #define SELECTED_ITEMS_LAYER Dwgs_User
1461
1462 view->ClearTopLayers();
1464 view->SetTopLayer( m_editLayer );
1466
1467 static const std::vector<int> topLayers = {
1472 };
1473
1474 for( int layer : topLayers )
1475 view->SetTopLayer( layer );
1476
1478
1479 view->Update( m_previewPad );
1480
1481 // delete previous items if highlight list
1482 while( m_highlight.size() )
1483 {
1484 delete m_highlight.back(); // the dtor also removes item from view
1485 m_highlight.pop_back();
1486 }
1487
1488 BOX2I bbox = m_previewPad->ViewBBox();
1489
1490 if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
1491 {
1492 // The origin always goes in the middle of the canvas; we want offsetting the pad
1493 // shape to move the pad, not the hole
1494 bbox.Move( -m_previewPad->GetPosition() );
1495 int maxXExtent = std::max( abs( bbox.GetLeft() ), abs( bbox.GetRight() ) );
1496 int maxYExtent = std::max( abs( bbox.GetTop() ), abs( bbox.GetBottom() ) );
1497
1498 // Don't blow up the GAL on too-large numbers
1499 if( maxXExtent > INT_MAX / 4 )
1500 maxXExtent = INT_MAX / 4;
1501
1502 if( maxYExtent > INT_MAX / 4 )
1503 maxYExtent = INT_MAX / 4;
1504
1505 BOX2D viewBox( m_previewPad->GetPosition(), {0, 0} );
1506 BOX2D canvasBox( m_previewPad->GetPosition(), {0, 0} );
1507 viewBox.Inflate( maxXExtent * 1.4, maxYExtent * 1.4 ); // add a margin
1508 canvasBox.Inflate( maxXExtent * 2.0, maxYExtent * 2.0 );
1509
1510 view->SetBoundary( canvasBox );
1511
1512 // Autozoom
1513 view->SetViewport( viewBox );
1514
1517 }
1518}
1519
1520
1522{
1523 if( !wxDialog::TransferDataToWindow() )
1524 return false;
1525
1526 if( !m_panelGeneral->TransferDataToWindow() )
1527 return false;
1528
1529 if( !m_localSettingsPanel->TransferDataToWindow() )
1530 return false;
1531
1532 return true;
1533}
1534
1535
1537{
1538 BOARD_COMMIT commit( m_parent );
1539
1540 if( !wxDialog::TransferDataFromWindow() )
1541 return false;
1542
1543 if( !m_panelGeneral->TransferDataFromWindow() )
1544 return false;
1545
1546 if( !m_localSettingsPanel->TransferDataFromWindow() )
1547 return false;
1548
1549 if( !padValuesOK() )
1550 return false;
1551
1553 return false;
1554
1556
1558 padTool->SetLastPadNumber( m_masterPad->GetNumber() );
1559
1560 // m_masterPad is a pattern: ensure there is no net for this pad:
1562
1563 if( !m_currentPad ) // Set current Pad parameters
1564 return true;
1565
1566 commit.Modify( m_currentPad );
1567
1568 // Update values
1569
1570 // transferDataToPad only handles the current edit layer, so m_masterPad isn't accurate
1571 // TODO(JE) this could be cleaner
1573
1579
1580 int padNetcode = NETINFO_LIST::UNCONNECTED;
1581
1582 // For PAD_ATTRIB::NPTH, ensure there is no net name selected
1583 if( m_masterPad->GetAttribute() != PAD_ATTRIB::NPTH )
1584 padNetcode = m_padNetSelector->GetSelectedNetcode();
1585
1586 m_currentPad->SetNetCode( padNetcode );
1587
1589
1590 // Set the fabrication property:
1592
1593 // define the way the clearance area is defined in zones
1595
1597 {
1598 // flip pad (up/down) around its position
1599 m_currentPad->Flip( m_currentPad->GetPosition(), FLIP_DIRECTION::TOP_BOTTOM );
1600 }
1601
1603
1605
1606 // redraw the area where the pad was
1608
1609 commit.Push( _( "Edit Pad Properties" ) );
1610
1611 return true;
1612}
1613
1614
1616{
1617 PAD_PROP prop = PAD_PROP::NONE;
1618
1619 switch( m_choiceFabProperty->GetSelection() )
1620 {
1621 case 0: prop = PAD_PROP::NONE; break;
1622 case 1: prop = PAD_PROP::BGA; break;
1623 case 2: prop = PAD_PROP::FIDUCIAL_LOCAL; break;
1624 case 3: prop = PAD_PROP::FIDUCIAL_GLBL; break;
1625 case 4: prop = PAD_PROP::TESTPOINT; break;
1626 case 5: prop = PAD_PROP::HEATSINK; break;
1627 case 6: prop = PAD_PROP::CASTELLATED; break;
1628 case 7: prop = PAD_PROP::MECHANICAL; break;
1629 }
1630
1631 return prop;
1632}
1633
1634
1636{
1637 if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
1638 {
1639 m_holeXLabel->SetLabel( _( "Diameter:" ) );
1640 m_holeY.Show( false );
1641 }
1642 else
1643 {
1644 m_holeXLabel->SetLabel( _( "Hole size X:" ) );
1645 m_holeY.Show( true );
1646 }
1647
1648 m_holeXLabel->GetParent()->Layout();
1649}
1650
1651
1653{
1654 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE
1656 {
1657 m_sizeXLabel->SetLabel( _( "Diameter:" ) );
1658 m_sizeY.Show( false );
1659 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
1660 m_minTrackWidthHint->SetLabel( _( "d" ) );
1661 m_stLenPercentHint->SetLabel( _( "d" ) );
1662 m_stWidthPercentHint->SetLabel( _( "d" ) );
1663 }
1664 else
1665 {
1666 m_sizeXLabel->SetLabel( _( "Pad size X:" ) );
1667 m_sizeY.Show( true );
1668 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_rect_sizes ) );
1669 m_minTrackWidthHint->SetLabel( _( "w" ) );
1670 m_stLenPercentHint->SetLabel( _( "w" ) );
1671 m_stWidthPercentHint->SetLabel( _( "w" ) );
1672 }
1673
1674 m_sizeXLabel->GetParent()->Layout();
1675 resetSize();
1676 Layout();
1677 m_MainSizer->Fit( this );
1678}
1679
1680
1682{
1683 if( !Validate() )
1684 return false;
1685
1686 if( !m_panelGeneral->Validate() )
1687 return false;
1688
1689 if( !m_localSettingsPanel->Validate() )
1690 return false;
1691
1692 if( !m_spokeWidth.Validate( 0, INT_MAX ) )
1693 return false;
1694
1695 switch( m_cbPadstackMode->GetSelection() )
1696 {
1697 default:
1698 case 0: aPad->Padstack().SetMode( PADSTACK::MODE::NORMAL ); break;
1699 case 1: aPad->Padstack().SetMode( PADSTACK::MODE::FRONT_INNER_BACK ); break;
1700 case 2: aPad->Padstack().SetMode( PADSTACK::MODE::CUSTOM ); break;
1701 }
1702
1703 aPad->SetAttribute( code_type[m_padType->GetSelection()] );
1704 aPad->SetShape( m_editLayer, code_shape[m_PadShapeSelector->GetSelection()] );
1705
1707 aPad->SetAnchorPadShape( m_editLayer, PAD_SHAPE::RECTANGLE );
1708 else
1709 aPad->SetAnchorPadShape( m_editLayer, PAD_SHAPE::CIRCLE );
1710
1711 if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::CUSTOM )
1713
1714 aPad->GetTeardropParams().m_Enabled = m_cbTeardrops->GetValue();
1721 aPad->GetTeardropParams().m_CurvedEdges = m_curvedEdges->GetValue();
1723
1724 // Read pad clearances values:
1725 if( m_clearance.IsNull() )
1726 aPad->SetLocalClearance( {} );
1727 else
1729
1730 if( m_maskMargin.IsNull() )
1731 aPad->SetLocalSolderMaskMargin( {} );
1732 else
1734
1735 if( m_pasteMargin.IsNull() )
1736 aPad->SetLocalSolderPasteMargin( {} );
1737 else
1739
1742 else
1744
1745 if( !m_spokeWidth.IsNull() )
1747
1748 if( !m_thermalGap.IsNull() )
1750
1752
1753 // And rotation
1755
1756 switch( m_ZoneConnectionChoice->GetSelection() )
1757 {
1758 default:
1759 case 0: aPad->SetLocalZoneConnection( ZONE_CONNECTION::INHERITED ); break;
1760 case 1: aPad->SetLocalZoneConnection( ZONE_CONNECTION::FULL ); break;
1761 case 2: aPad->SetLocalZoneConnection( ZONE_CONNECTION::THERMAL ); break;
1762 case 3: aPad->SetLocalZoneConnection( ZONE_CONNECTION::NONE ); break;
1763 }
1764
1766
1767 if( FOOTPRINT* fp = aPad->GetParentFootprint() )
1768 {
1769 pos -= fp->GetPosition();
1770 RotatePoint( pos, -fp->GetOrientation() );
1771 }
1772
1773 aPad->SetPosition( pos );
1774
1775 if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
1776 {
1777 aPad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
1779 }
1780 else
1781 {
1782 aPad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
1784 }
1785
1786 if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::CIRCLE )
1788 else
1790
1791 // For a trapezoid, test delta value (be sure delta is not too large for pad size)
1792 // remember DeltaSize.x is the Y size variation
1793 bool error = false;
1794 VECTOR2I delta( 0, 0 );
1795
1796 if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::TRAPEZOID )
1797 {
1798 // For a trapezoid, only one of delta.x or delta.y is not 0, depending on axis.
1799 if( m_trapAxisCtrl->GetSelection() == 0 )
1801 else
1803
1804 if( delta.x < 0 && delta.x < -aPad->GetSize( m_editLayer ).y )
1805 {
1806 delta.x = -aPad->GetSize( m_editLayer ).y + 2;
1807 error = true;
1808 }
1809
1810 if( delta.x > 0 && delta.x > aPad->GetSize( m_editLayer ).y )
1811 {
1812 delta.x = aPad->GetSize( m_editLayer ).y - 2;
1813 error = true;
1814 }
1815
1816 if( delta.y < 0 && delta.y < -aPad->GetSize( m_editLayer ).x )
1817 {
1818 delta.y = -aPad->GetSize( m_editLayer ).x + 2;
1819 error = true;
1820 }
1821
1822 if( delta.y > 0 && delta.y > aPad->GetSize( m_editLayer ).x )
1823 {
1824 delta.y = aPad->GetSize( m_editLayer ).x - 2;
1825 error = true;
1826 }
1827 }
1828
1829 aPad->SetDelta( m_editLayer, delta );
1830
1831 if( m_offsetShapeOpt->GetValue() )
1833 else
1834 aPad->SetOffset( m_editLayer, VECTOR2I() );
1835
1836 // Read pad length die
1837 if( m_padToDieOpt->GetValue() )
1839 else
1840 aPad->SetPadToDieLength( 0 );
1841
1842 aPad->SetNumber( m_padNumCtrl->GetValue() );
1844
1845 int chamfers = 0;
1846
1847 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CHAMFERED_RECT )
1848 {
1849 if( m_cbTopLeft->GetValue() )
1850 chamfers |= RECT_CHAMFER_TOP_LEFT;
1851
1852 if( m_cbTopRight->GetValue() )
1853 chamfers |= RECT_CHAMFER_TOP_RIGHT;
1854
1855 if( m_cbBottomLeft->GetValue() )
1856 chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
1857
1858 if( m_cbBottomRight->GetValue() )
1859 chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
1860 }
1861 else if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CHAMFERED_ROUNDED_RECT )
1862 {
1863 if( m_cbTopLeft1->GetValue() )
1864 chamfers |= RECT_CHAMFER_TOP_LEFT;
1865
1866 if( m_cbTopRight1->GetValue() )
1867 chamfers |= RECT_CHAMFER_TOP_RIGHT;
1868
1869 if( m_cbBottomLeft1->GetValue() )
1870 chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
1871
1872 if( m_cbBottomRight1->GetValue() )
1873 chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
1874 }
1875
1876 aPad->SetChamferPositions( m_editLayer, chamfers );
1877
1878 if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::CUSTOM )
1879 {
1880 // The pad custom has a "anchor pad" (a basic shape: round or rect pad)
1881 // that is the minimal area of this pad, and is useful to ensure a hole
1882 // diameter is acceptable, and is used in Gerber files as flashed area
1883 // reference
1884 if( aPad->GetAnchorPadShape( m_editLayer ) == PAD_SHAPE::CIRCLE )
1886 }
1887
1888 // Define the way the clearance area is defined in zones. Since all non-custom pad
1889 // shapes are convex to begin with, this really only makes any difference for custom
1890 // pad shapes.
1891 aPad->SetCustomShapeInZoneOpt( m_ZoneCustomPadShape->GetSelection() == 0 ?
1894
1895 switch( aPad->GetAttribute() )
1896 {
1897 case PAD_ATTRIB::PTH:
1898 break;
1899
1900 case PAD_ATTRIB::CONN:
1901 case PAD_ATTRIB::SMD:
1902 // SMD and PAD_ATTRIB::CONN has no hole.
1903 // basically, SMD and PAD_ATTRIB::CONN are same type of pads
1904 // PAD_ATTRIB::CONN has just a default non technical layers that differs from SMD
1905 // and are intended to be used in virtual edge board connectors
1906 // However we can accept a non null offset,
1907 // mainly to allow complex pads build from a set of basic pad shapes
1908 aPad->SetDrillSize( VECTOR2I( 0, 0 ) );
1909 break;
1910
1911 case PAD_ATTRIB::NPTH:
1912 // Mechanical purpose only:
1913 // no net name, no pad name allowed
1914 aPad->SetNumber( wxEmptyString );
1916 break;
1917
1918 default:
1919 wxFAIL_MSG( wxT( "DIALOG_PAD_PROPERTIES::transferDataToPad: unknown pad type" ) );
1920 break;
1921 }
1922
1923 if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::ROUNDRECT )
1924 {
1926 }
1927 else if( aPad->GetShape( m_editLayer ) == PAD_SHAPE::CHAMFERED_RECT )
1928 {
1930 {
1933 }
1934 else // Choice is CHOICE_SHAPE_CHAMFERED_RECT, no rounded corner
1935 {
1938 }
1939 }
1940
1942
1943 LSET padLayerMask = LSET();
1944 int copperLayersChoice = m_rbCopperLayersSel->GetSelection();
1945
1947
1948 switch( m_padType->GetSelection() )
1949 {
1950 case PTH_DLG_TYPE:
1951 switch( copperLayersChoice )
1952 {
1953 case 0:
1954 // All copper layers
1955 padLayerMask |= LSET::AllCuMask();
1956 break;
1957
1958 case 1:
1959 // Front, back and connected
1960 padLayerMask |= LSET::AllCuMask();
1963 break;
1964
1965 case 2:
1966 // Connected only
1967 padLayerMask |= LSET::AllCuMask();
1969 break;
1970
1971 case 3:
1972 // No copper layers
1973 break;
1974 }
1975
1976 break;
1977
1978 case NPTH_DLG_TYPE:
1979 switch( copperLayersChoice )
1980 {
1981 case 0: padLayerMask.set( F_Cu ).set( B_Cu ); break;
1982 case 1: padLayerMask.set( F_Cu ); break;
1983 case 2: padLayerMask.set( B_Cu ); break;
1984 default: break;
1985 }
1986
1987 break;
1988
1989 case SMD_DLG_TYPE:
1990 case CONN_DLG_TYPE:
1991 switch( copperLayersChoice )
1992 {
1993 case 0: padLayerMask.set( F_Cu ); break;
1994 case 1: padLayerMask.set( B_Cu ); break;
1995 }
1996
1997 break;
1998
1999 case APERTURE_DLG_TYPE:
2000 // no copper layers
2001 break;
2002 }
2003
2004 if( m_layerFrontAdhesive->GetValue() )
2005 padLayerMask.set( F_Adhes );
2006
2007 if( m_layerBackAdhesive->GetValue() )
2008 padLayerMask.set( B_Adhes );
2009
2010 if( m_layerFrontPaste->GetValue() )
2011 padLayerMask.set( F_Paste );
2012
2013 if( m_layerBackPaste->GetValue() )
2014 padLayerMask.set( B_Paste );
2015
2016 if( m_layerFrontSilk->GetValue() )
2017 padLayerMask.set( F_SilkS );
2018
2019 if( m_layerBackSilk->GetValue() )
2020 padLayerMask.set( B_SilkS );
2021
2022 if( m_layerFrontMask->GetValue() )
2023 padLayerMask.set( F_Mask );
2024
2025 if( m_layerBackMask->GetValue() )
2026 padLayerMask.set( B_Mask );
2027
2028 if( m_layerECO1->GetValue() )
2029 padLayerMask.set( Eco1_User );
2030
2031 if( m_layerECO2->GetValue() )
2032 padLayerMask.set( Eco2_User );
2033
2034 if( m_layerUserDwgs->GetValue() )
2035 padLayerMask.set( Dwgs_User );
2036
2037 aPad->SetLayerSet( padLayerMask );
2038
2039 return !error;
2040}
2041
2042
2043void DIALOG_PAD_PROPERTIES::OnOffsetCheckbox( wxCommandEvent& event )
2044{
2045 if( m_offsetShapeOpt->GetValue() )
2046 {
2049 }
2050
2051 // Show/hide controls depending on m_offsetShapeOpt being enabled
2052 m_offsetCtrls->Show( m_offsetShapeOpt->GetValue() );
2053 m_offsetShapeOptLabel->Show( m_offsetShapeOpt->GetValue() );
2054
2055 for( size_t i = 0; i < m_notebook->GetPageCount(); ++i )
2056 m_notebook->GetPage( i )->Layout();
2057
2058 OnValuesChanged( event );
2059}
2060
2061
2063{
2064 if( m_padToDieOpt->GetValue() && m_currentPad )
2066
2067 OnValuesChanged( event );
2068}
2069
2070
2071void DIALOG_PAD_PROPERTIES::onModify( wxSpinDoubleEvent& aEvent )
2072{
2073 if( m_initialized )
2074 OnModify();
2075}
2076
2077
2078void DIALOG_PAD_PROPERTIES::onModify( wxCommandEvent& aEvent )
2079{
2080 if( m_initialized )
2081 OnModify();
2082}
2083
2084
2085void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
2086{
2087 if( m_initialized )
2088 {
2090 return;
2091
2092 // If the pad size has changed, update the displayed values for rounded rect pads.
2094
2095 redraw();
2096 OnModify();
2097 }
2098}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
#define DEFAULT_PAD_DRILL_DIAMETER_MM
BASE_SET & set(size_t pos)
Definition: base_set.h:116
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
TEARDROP_PARAMETERS & GetTeardropParams()
std::unique_ptr< PAD > m_Pad_Master
void SetParentGroup(PCB_GROUP *aGroup)
Definition: board_item.h:89
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:298
VECTOR2I GetFPRelativePosition() const
Definition: board_item.cpp:327
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:217
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:879
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:817
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:456
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:613
bool LegacyTeardrops() const
Definition: board.h:1269
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:934
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
constexpr coord_type GetLeft() const
Definition: box2.h:228
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:138
constexpr coord_type GetRight() const
Definition: box2.h:217
constexpr const SizeVec & GetSize() const
Definition: box2.h:206
constexpr coord_type GetTop() const
Definition: box2.h:229
constexpr coord_type GetBottom() const
Definition: box2.h:222
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
Class DIALOG_PAD_PROPERTIES_BASE.
void OnUpdateUINonCopperWarning(wxUpdateUIEvent &event) override
void OnInitDialog(wxInitDialogEvent &event) override
void PadTypeSelected(wxCommandEvent &event) override
void OnPadShapeSelection(wxCommandEvent &event) override
bool transferDataToPad(PAD *aPad)
Copy values from dialog field to aPad's members.
bool TransferDataFromWindow() override
Updates the different parameters for the component being edited.
std::map< int, PCB_LAYER_ID > m_editLayerCtrlMap
bool Show(bool aShow) override
void OnEditLayerChanged(wxCommandEvent &event) override
std::vector< std::shared_ptr< PCB_SHAPE > > m_primitives
bool padValuesOK()
test if all values are acceptable for the pad
void PadOrientEvent(wxCommandEvent &event) override
void OnResize(wxSizeEvent &event)
void OnOffsetCheckbox(wxCommandEvent &event) override
PCB_DRAW_PANEL_GAL * m_padPreviewGAL
void OnValuesChanged(wxCommandEvent &event) override
Called when a dimension has changed.
DIALOG_PAD_PROPERTIES(PCB_BASE_FRAME *aParent, PAD *aPad)
void onTeardropsUpdateUi(wxUpdateUIEvent &event) override
void onChangePadMode(wxCommandEvent &event) override
std::vector< PCB_SHAPE * > m_highlight
void OnPadstackModeChanged(wxCommandEvent &event) override
KIGFX::ORIGIN_VIEWITEM * m_axisOrigin
void OnSetCopperLayers(wxCommandEvent &event) override
void OnCancel(wxCommandEvent &event) override
void onCornerRadiusChange(wxCommandEvent &event) override
void updatePadLayersList(LSET layer_mask, bool remove_unconnected, bool keep_top_bottom)
Updates the CheckBox states in pad layers list, based on the layer_mask (if non-empty) or the default...
PAD_PROP getSelectedProperty()
Return the pad property currently selected.
void OnSetLayers(wxCommandEvent &event) override
void onCornerSizePercentChange(wxCommandEvent &event) override
void OnPadToDieCheckbox(wxCommandEvent &event) override
void OnDrillShapeSelected(wxCommandEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) override
void onModify(wxCommandEvent &aEvent) override
bool Show(bool show) override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
void resetSize()
Clear the existing dialog size and position.
void OnModify()
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:248
int ShowModal() override
bool IsType(FRAME_T aType) const
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
GAL_DISPLAY_OPTIONS_IMPL & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
GAL_TYPE GetBackend() const
Return the type of backend currently used by GAL canvas.
void StopDrawing()
Prevent the GAL canvas from further drawing until it is recreated or StartDrawing() is called.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Return a pointer to the #VIEW_CONTROLS instance used in the panel.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
void StartDrawing()
Begin drawing if it was stopped previously.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:129
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
int GetAttributes() const
Definition: footprint.h:288
bool IsFlipped() const
Definition: footprint.h:389
void ListSet(const wxString &aList)
Add a list of items.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
bool m_forceDisplayCursor
The pixel scale factor (>1 for hi-DPI scaled displays)
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
void SetGridSize(const VECTOR2D &aGridSize)
Set the grid size.
void SetGridVisibility(bool aVisibility)
Set the visibility setting of the grid.
void SetPosition(const VECTOR2I &aPosition) override
void SetDrawAtZero(bool aDrawFlag)
Set the draw at zero flag.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:180
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:185
PCB specific render settings.
Definition: pcb_painter.h:78
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color used to draw a layer.
An interface for classes handling user events controlling the view behavior such as zooming,...
void ApplySettings(const VC_SETTINGS &aSettings)
Apply VIEW_CONTROLS settings from an object.
const VC_SETTINGS & GetSettings() const
Return the current VIEW_CONTROLS settings.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
void SetViewport(const BOX2D &aViewport)
Set the visible area of the VIEW.
Definition: view.cpp:532
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:297
void SetBoundary(const BOX2D &aBoundary)
Set limits for view area.
Definition: view.h:282
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:1673
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:198
void ClearTopLayers()
Remove all layers from the on-the-top set (they are no longer displayed over the rest of layers).
Definition: view.cpp:881
virtual void SetTopLayer(int aLayer, bool aEnabled=true)
Set given layer to be displayed on the top or sets back the default order of layers.
Definition: view.cpp:829
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:216
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:688
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:562
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:381
void SetNetInfo(const NETINFO_LIST *aNetInfoList)
void SetBoard(BOARD *aBoard)
int GetSelectedNetcode()
void SetSelectedNetcode(int aNetcode)
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
Definition: padstack.cpp:879
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
Definition: padstack.h:307
void SetMode(MODE aMode)
Definition: padstack.cpp:830
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
MODE Mode() const
Definition: padstack.h:287
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
Definition: padstack.h:147
Tool relating to pads and pad settings.
Definition: pad_tool.h:37
void SetLastPadNumber(const wxString &aPadNumber)
Definition: pad_tool.h:69
wxString GetLastPadNumber() const
Definition: pad_tool.h:68
Definition: pad.h:54
void SetAnchorPadShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:240
bool IsAperturePad() const
Definition: pad.h:445
void SetAttribute(PAD_ATTRIB aAttribute)
Definition: pad.cpp:835
void CheckPad(UNITS_PROVIDER *aUnitsProvider, bool aForPadProperties, const std::function< void(int aErrorCode, const wxString &aMsg)> &aErrorHandler) const
Definition: pad.cpp:2162
PAD_PROP GetProperty() const
Definition: pad.h:441
bool GetRemoveUnconnected() const
Definition: pad.h:726
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:435
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives(PCB_LAYER_ID aLayer) const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:363
int GetRoundRectCornerRadius(PCB_LAYER_ID aLayer) const
Definition: pad.cpp:442
void SetLocalThermalGapOverride(const std::optional< int > &aOverride)
Definition: pad.h:641
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition: pad.h:468
const VECTOR2I & GetDrillSize() const
Definition: pad.h:303
PAD_ATTRIB GetAttribute() const
Definition: pad.h:438
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:270
void SetThermalSpokeAngle(const EDA_ANGLE &aAngle)
The orientation of the thermal spokes.
Definition: pad.h:613
const wxString & GetNumber() const
Definition: pad.h:134
const VECTOR2I & GetDelta(PCB_LAYER_ID aLayer) const
Definition: pad.h:297
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition: pad.h:472
void SetLocalThermalSpokeWidthOverride(std::optional< int > aWidth)
Set the width of the thermal spokes connecting the pad to a zone.
Definition: pad.h:597
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:184
VECTOR2I GetPosition() const override
Definition: pad.h:206
void SetProperty(PAD_PROP aProperty)
Definition: pad.cpp:902
EDA_ANGLE GetThermalSpokeAngle() const
Definition: pad.h:617
void Flip(const VECTOR2I &VECTOR2I, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
Definition: pad.cpp:935
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:291
void SetDelta(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
Definition: pad.h:291
int GetDrillSizeX() const
Definition: pad.h:305
double GetRoundRectRadiusRatio(PCB_LAYER_ID aLayer) const
Definition: pad.h:663
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
Definition: pad.h:193
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
Definition: pad.h:133
void SetDrillShape(PAD_DRILL_SHAPE aShape)
Definition: pad.cpp:431
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pad.h:457
void SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
Definition: pad.h:309
bool GetKeepTopBottom() const
Definition: pad.h:742
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition: pad.h:477
void SetChamferRectRatio(PCB_LAYER_ID aLayer, double aChamferScale)
Has meaning only for chamfered rectangular pads.
Definition: pad.cpp:492
std::optional< int > GetLocalClearance() const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: pad.h:453
void SetPadstack(const PADSTACK &aPadstack)
Definition: pad.h:321
void SetPosition(const VECTOR2I &aPos) override
Definition: pad.h:200
const PADSTACK & Padstack() const
Definition: pad.h:319
const VECTOR2I & GetOffset(PCB_LAYER_ID aLayer) const
Definition: pad.h:315
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: pad.cpp:284
void SetDrillSize(const VECTOR2I &aSize)
Definition: pad.h:302
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition: pad.h:406
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
Definition: pad.h:257
PADSTACK::CUSTOM_SHAPE_ZONE_MODE GetCustomShapeInZoneOpt() const
Definition: pad.h:219
PAD_DRILL_SHAPE GetDrillShape() const
Definition: pad.h:420
void ReplacePrimitives(PCB_LAYER_ID aLayer, const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
int GetChamferPositions(PCB_LAYER_ID aLayer) const
Definition: pad.h:703
static LSET ApertureMask()
layer set for an aperture pad
Definition: pad.cpp:298
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pad.cpp:1786
void SetRoundRectCornerRadius(PCB_LAYER_ID aLayer, double aRadius)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:448
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:277
std::optional< int > GetLocalSolderPasteMargin() const
Definition: pad.h:462
void SetChamferPositions(PCB_LAYER_ID aLayer, int aPositions)
Has meaning only for chamfered rectangular pads.
Definition: pad.h:698
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pad.h:456
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition: pad.h:463
EDA_ANGLE GetFPRelativeOrientation() const
Definition: pad.cpp:926
double GetChamferRectRatio(PCB_LAYER_ID aLayer) const
Definition: pad.h:686
void SetFPRelativeOrientation(const EDA_ANGLE &aAngle)
Definition: pad.cpp:917
void SetCustomShapeInZoneOpt(PADSTACK::CUSTOM_SHAPE_ZONE_MODE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
Definition: pad.h:229
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
Definition: pad.cpp:910
std::optional< int > GetLocalThermalSpokeWidthOverride() const
Definition: pad.h:601
void SetLocalClearance(std::optional< int > aClearance)
Definition: pad.h:454
ZONE_CONNECTION GetLocalZoneConnection() const
Definition: pad.h:478
int GetLocalThermalGapOverride(wxString *aSource) const
Definition: pad.cpp:1263
void SetLayerSet(const LSET &aLayers) override
Definition: pad.h:434
PAD_SHAPE GetAnchorPadShape(PCB_LAYER_ID aLayer) const
Definition: pad.h:211
void SetRoundRectRadiusRatio(PCB_LAYER_ID aLayer, double aRadiusScale)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:454
void SetPadToDieLength(int aLength)
Definition: pad.h:450
int GetPadToDieLength() const
Definition: pad.h:451
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
Definition: pad.h:262
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void ShowPadPropertiesDialog(PAD *aPad)
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
virtual COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Helper to retrieve the current color settings.
void UpdateColors()
Update the color settings in the painter and GAL.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
int GetIntValue()
Definition: unit_binder.h:129
virtual void ChangeDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetPrecision(int aLength)
Normally not needed, but can be used to set the precision when using internal units that are floats (...
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual EDA_ANGLE GetAngleValue()
virtual void SetNegativeZero()
Definition: unit_binder.h:73
virtual double GetDoubleValue()
Return the current value in Internal Units.
virtual void SetAngleValue(const EDA_ANGLE &aValue)
virtual void ChangeAngleValue(const EDA_ANGLE &aValue)
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetNull()
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:200
bool IsNull() const
Return true if the control holds no value (ie: empty string, not 0).
This file is part of the common library.
#define APERTURE_DLG_TYPE
#define CONN_DLG_TYPE
static PAD_ATTRIB code_type[]
#define SELECTED_ITEMS_LAYER
static PAD_SHAPE code_shape[]
#define SMD_DLG_TYPE
@ CHOICE_SHAPE_CIRCLE
@ CHOICE_SHAPE_ROUNDRECT
@ CHOICE_SHAPE_CUSTOM_RECT_ANCHOR
@ CHOICE_SHAPE_CHAMFERED_RECT
@ CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
@ CHOICE_SHAPE_RECT
@ CHOICE_SHAPE_OVAL
@ CHOICE_SHAPE_TRAPEZOID
@ CHOICE_SHAPE_CHAMFERED_ROUNDED_RECT
#define NPTH_DLG_TYPE
#define PTH_DLG_TYPE
#define PAD_PROPERTIES_DLG_NAME
DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, created by wxFormBuilder.
@ DRCE_PADSTACK
Definition: drc_item.h:62
@ DRCE_PADSTACK_INVALID
Definition: drc_item.h:63
@ DRCE_PAD_TH_WITH_NO_HOLE
Definition: drc_item.h:84
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
static constexpr EDA_ANGLE ANGLE_45
Definition: eda_angle.h:402
#define BRIGHTENED
item is drawn with a bright contour
#define SELECTED
Item was manually selected by the user.
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
@ LAYER_PAD_NETNAMES
Definition: layer_ids.h:165
@ LAYER_GRID
Definition: layer_ids.h:216
@ LAYER_NON_PLATEDHOLES
Draw usual through hole vias.
Definition: layer_ids.h:201
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
Definition: layer_ids.h:233
@ LAYER_PAD_HOLEWALLS
Definition: layer_ids.h:259
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Adhes
Definition: layer_ids.h:103
@ Dwgs_User
Definition: layer_ids.h:107
@ F_Paste
Definition: layer_ids.h:104
@ F_Adhes
Definition: layer_ids.h:102
@ B_Mask
Definition: layer_ids.h:98
@ B_Cu
Definition: layer_ids.h:65
@ Eco1_User
Definition: layer_ids.h:109
@ F_Mask
Definition: layer_ids.h:97
@ B_Paste
Definition: layer_ids.h:105
@ F_SilkS
Definition: layer_ids.h:100
@ Eco2_User
Definition: layer_ids.h:110
@ B_SilkS
Definition: layer_ids.h:101
@ F_Cu
Definition: layer_ids.h:64
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:155
bool PadHasMeaningfulRoundingRadius(const PAD &aPad, PCB_LAYER_ID aLayer)
Returns true if the pad's rounding ratio is valid (i.e.
Definition: pad_utils.cpp:44
double GetDefaultIpcRoundingRatio(const PAD &aPad, PCB_LAYER_ID aLayer)
Get a sensible default for a rounded rectangle pad's rounding ratio.
Definition: pad_utils.cpp:27
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition: padstack.h:81
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
Definition: padstack.h:52
PAD_PROP
The set of pad properties used in Gerber files (Draw files, and P&P files) to define some properties ...
Definition: padstack.h:98
const double IU_PER_MM
Definition: base_units.h:76
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
constexpr int delta
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.
Definition: trigo.cpp:229
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
VECTOR2< double > VECTOR2D
Definition: vector2d.h:694