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 (C) 1992-2024 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 <pcb_base_frame.h>
45#include <pcb_painter.h>
46#include <pcbnew_settings.h>
48#include <view/view_controls.h>
50#include <tool/tool_manager.h>
51#include <tools/pad_tool.h>
52#include <advanced_config.h> // for pad property feature management
53#include <wx/choicdlg.h>
54
55
56int DIALOG_PAD_PROPERTIES::m_page = 0; // remember the last open page during session
57
58
59// list of pad shapes, ordered like the pad shape wxChoice in dialog.
61{
68 PAD_SHAPE::CHAMFERED_RECT, // choice = CHOICE_SHAPE_CHAMFERED_ROUNDED_RECT
69 PAD_SHAPE::CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
70 PAD_SHAPE::CUSTOM // choice = PAD_SHAPE::CUSTOM_RECT_ANCHOR
71};
72
73
74// the ordered index of the pad shape wxChoice in dialog.
75// keep it consistent with code_shape[] and dialog strings
77{
87};
88
89
91{
96 PAD_ATTRIB::SMD // Aperture pad :type SMD with no copper layers,
97 // only on tech layers (usually only on paste layer
98};
99
100
101// These define have the same value as the m_PadType wxChoice GetSelected() return value
102#define PTH_DLG_TYPE 0
103#define SMD_DLG_TYPE 1
104#define CONN_DLG_TYPE 2
105#define NPTH_DLG_TYPE 3
106#define APERTURE_DLG_TYPE 4
107
108
113static bool PadHasMeaningfulRoundingRadius( const PAD& aPad )
114{
115 const PAD_SHAPE shape = aPad.GetShape();
116 return shape == PAD_SHAPE::ROUNDRECT || shape == PAD_SHAPE::CHAMFERED_RECT;
117}
118
119
125static double GetDefaultIpcRoundingRatio( const PAD& aPad )
126{
127 const double defaultProportion = 0.25;
128 const double minimumSizeIU = pcbIUScale.mmToIU( 0.25 );
129
130 const int padMinSizeIU = std::min( aPad.GetSizeX(), aPad.GetSizeY() );
131 const double defaultRadiusIU = std::min( minimumSizeIU, padMinSizeIU * defaultProportion );
132
133 // Convert back to a ratio
134 return defaultRadiusIU / padMinSizeIU;
135}
136
137
139{
140 DIALOG_PAD_PROPERTIES dlg( this, aPad );
141
142 // QuasiModal required for NET_SELECTOR
143 dlg.ShowQuasiModal();
144}
145
146
149 m_parent( aParent ),
150 m_canUpdate( false ),
151 m_posX( aParent, m_posXLabel, m_posXCtrl, m_posXUnits ),
152 m_posY( aParent, m_posYLabel, m_posYCtrl, m_posYUnits ),
153 m_sizeX( aParent, m_sizeXLabel, m_sizeXCtrl, m_sizeXUnits ),
154 m_sizeY( aParent, m_sizeYLabel, m_sizeYCtrl, m_sizeYUnits ),
155 m_offsetX( aParent, m_offsetXLabel, m_offsetXCtrl, m_offsetXUnits ),
156 m_offsetY( aParent, m_offsetYLabel, m_offsetYCtrl, m_offsetYUnits ),
157 m_padToDie( aParent, m_padToDieLabel, m_padToDieCtrl, m_padToDieUnits ),
158 m_trapDelta( aParent, m_trapDeltaLabel, m_trapDeltaCtrl, m_trapDeltaUnits ),
159 m_cornerRadius( aParent, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ),
160 m_cornerRatio( aParent, m_cornerRatioLabel, m_cornerRatioCtrl, m_cornerRatioUnits ),
161 m_chamferRatio( aParent, m_chamferRatioLabel, m_chamferRatioCtrl, m_chamferRatioUnits ),
162 m_mixedCornerRatio( aParent, m_mixedCornerRatioLabel, m_mixedCornerRatioCtrl,
163 m_mixedCornerRatioUnits ),
164 m_mixedChamferRatio( aParent, m_mixedChamferRatioLabel, m_mixedChamferRatioCtrl,
165 m_mixedChamferRatioUnits ),
166 m_holeX( aParent, m_holeXLabel, m_holeXCtrl, m_holeXUnits ),
167 m_holeY( aParent, m_holeYLabel, m_holeYCtrl, m_holeYUnits ),
168 m_clearance( aParent, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits ),
169 m_maskMargin( aParent, m_maskMarginLabel, m_maskMarginCtrl, m_maskMarginUnits ),
170 m_pasteMargin( aParent, m_pasteMarginLabel, m_pasteMarginCtrl, m_pasteMarginUnits ),
171 m_pasteMarginRatio( aParent, m_pasteMarginRatioLabel, m_pasteMarginRatioCtrl,
172 m_pasteMarginRatioUnits ),
173 m_thermalGap( aParent, m_thermalGapLabel, m_thermalGapCtrl, m_thermalGapUnits ),
174 m_spokeWidth( aParent, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ),
175 m_spokeAngle( aParent, m_spokeAngleLabel, m_spokeAngleCtrl, m_spokeAngleUnits ),
176 m_pad_orientation( aParent, m_PadOrientText, m_cb_padrotation, m_orientationUnits ),
177 m_teardropMaxLenSetting( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
178 m_teardropMaxHeightSetting( aParent, m_stTdMaxSize, m_tcMaxHeight, m_stMaxHeightUnits )
179{
180 SetName( PAD_PROPERTIES_DLG_NAME );
181 m_isFpEditor = dynamic_cast<FOOTPRINT_EDIT_FRAME*>( aParent ) != nullptr;
182
183 m_currentPad = aPad; // aPad can be NULL, if the dialog is called
184 // from the footprint editor to set default pad setup
185
187
188 // Configure display origin transforms
191
194
196
197 m_FlippedWarningIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
198 m_nonCopperWarningIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
199 m_legacyTeardropsIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
200
202 m_previewPad = new PAD( (FOOTPRINT*) nullptr );
203
204 if( aPad )
205 {
206 SetTitle( _( "Pad Properties" ) );
207
208 *m_previewPad = *aPad;
211 }
212 else
213 {
214 SetTitle( _( "Default Pad Properties for Add Pad Tool" ) );
215
218 }
219
220 // Pads have a hardcoded internal rounding ratio which is 0.25 by default, even if
221 // they're not a rounded shape. This makes it hard to detect an intentional 0.25
222 // ratio, or one that's only there because it's the PAD default.
223 // Zero it out here to mark that we should recompute a better ratio if the user
224 // selects a pad shape which would need a default rounding ratio computed for it
227
228 if( m_isFpEditor )
229 {
230 m_padNetLabel->Show( false );
231 m_padNetSelector->Show( false );
232 }
233
234 m_FlippedWarningSizer->Show( false );
235
236 // Pad needs to have a parent for painting; use the parent board for its design settings
237 if( !m_previewPad->GetParent() )
239
240 m_cornerRatio.SetUnits( EDA_UNITS::PERCENT );
241 m_chamferRatio.SetUnits( EDA_UNITS::PERCENT );
242 m_mixedCornerRatio.SetUnits( EDA_UNITS::PERCENT );
243 m_mixedChamferRatio.SetUnits( EDA_UNITS::PERCENT );
244 m_pad_orientation.SetUnits( EDA_UNITS::DEGREES );
246
247 m_spokeAngle.SetUnits( EDA_UNITS::DEGREES );
249
251
252 m_pasteMarginRatio.SetUnits( EDA_UNITS::PERCENT );
254
255 initValues();
256
257 wxFont infoFont = KIUI::GetInfoFont( this );
258 m_copperLayersLabel->SetFont( infoFont );
259 m_techLayersLabel->SetFont( infoFont );
260 m_parentInfo->SetFont( infoFont );
261 m_teardropShapeLabel->SetFont( infoFont );
262
263 infoFont.SetStyle( wxFONTSTYLE_ITALIC );
264 m_nonCopperNote->SetFont( infoFont );
265 m_staticTextInfoPaste->SetFont( infoFont );
266
269
270 // Usually, TransferDataToWindow is called by OnInitDialog
271 // calling it here fixes all widget sizes so FinishDialogSettings can safely fix minsizes
273
274 // Initialize canvas to be able to display the dummy pad:
276
277 m_notebook->SetSelection( m_page );
278
279 switch( m_page )
280 {
281 case 0: SetInitialFocus( m_padNumCtrl ); break;
282 case 1: SetInitialFocus( m_thermalGapCtrl ); break;
283 case 2: SetInitialFocus( m_clearanceCtrl ); break;
284 }
285
288 m_canUpdate = true;
289
290 m_padNetSelector->Connect( NET_SELECTED,
291 wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ),
292 nullptr, this );
293
294 if( m_padType->GetSelection() != PTH_DLG_TYPE && m_padType->GetSelection() != NPTH_DLG_TYPE )
295 {
296 m_gbSizerHole->Show( false );
297 m_staticline6->Show( false );
298 }
299
300 // Now all widgets have the size fixed, call FinishDialogSettings
302
303 // Update widgets
304 wxUpdateUIEvent dummyUI;
305 OnUpdateUI( dummyUI );
306
307 // Post a dummy size event to force the pad preview panel to update the
308 // view: actual size, best zoom ... after the frame is shown
309 PostSizeEvent();
310}
311
312
314{
315 m_padNetSelector->Disconnect( NET_SELECTED,
316 wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ),
317 nullptr, this );
318
319 m_page = m_notebook->GetSelection();
320
321 // Remove the preview pad from the group of the actual pad before deletion
322 if( m_previewPad )
323 m_previewPad->SetParentGroup( nullptr );
324
325 delete m_previewPad;
326 delete m_axisOrigin;
327}
328
329
330// Store the pad draw option during a session.
332
333
334void DIALOG_PAD_PROPERTIES::OnInitDialog( wxInitDialogEvent& event )
335{
336 m_selectedColor = COLOR4D( 1.0, 1.0, 1.0, 0.7 );
337
338 // Needed on some WM to be sure the pad is redrawn according to the final size
339 // of the canvas, with the right zoom factor
340 redraw();
341}
342
343
344void DIALOG_PAD_PROPERTIES::OnCancel( wxCommandEvent& event )
345{
346 // Mandatory to avoid m_panelShowPadGal trying to draw something
347 // in a non valid context during closing process:
349
350 // Now call default handler for wxID_CANCEL command event
351 event.Skip();
352}
353
354
356{
358 COLOR_SETTINGS* colorSettings = m_parent->GetColorSettings();
359
360 opts.m_forceDisplayCursor = false;
361
362 // Initialize the canvas to display the pad
363 m_padPreviewGAL = new PCB_DRAW_PANEL_GAL( m_boardViewPanel, -1, wxDefaultPosition,
364 wxDefaultSize, opts,
366
367 m_padPreviewSizer->Add( m_padPreviewGAL, 12, wxEXPAND | wxALL, 5 );
368
369 // Show the X and Y axis. It is useful because pad shape can have an offset
370 // or be a complex shape.
375
378 m_padPreviewGAL->ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
379
380 KIGFX::VIEW_CONTROLS* parentViewControls = m_parent->GetCanvas()->GetViewControls();
381 m_padPreviewGAL->GetViewControls()->ApplySettings( parentViewControls->GetSettings() );
382
383 m_padPreviewGAL->Show();
384
386
387 // fix the pad render mode (filled/not filled)
388 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
389
390 settings->m_ForcePadSketchModeOn = m_cbShowPadOutline->IsChecked();
391 settings->SetHighContrast( false );
392 settings->m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
393
394 // gives a non null grid size (0.001mm) because GAL layer does not like a 0 size grid:
395 double gridsize = 0.001 * pcbIUScale.IU_PER_MM;
396 view->GetGAL()->SetGridSize( VECTOR2D( gridsize, gridsize ) );
397
398 // And do not show the grid:
399 view->GetGAL()->SetGridVisibility( false );
400 view->GetGAL()->SetAxesEnabled( false );
401 view->Add( m_previewPad );
402 view->Add( m_axisOrigin );
403
405 Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
406}
407
408
410{
411 // Note: use ChangeValue() to avoid generating a wxEVT_TEXT event
413
416
419}
420
421
423{
424 if( m_previewPad->GetShape() != PAD_SHAPE::ROUNDRECT
425 && m_previewPad->GetShape() != PAD_SHAPE::CHAMFERED_RECT )
426 {
427 return;
428 }
429
430 if( m_cornerRadius.GetValue() < 0 )
431 m_cornerRadiusCtrl->ChangeValue( "0" );
432
434 {
436
439
440 redraw();
441 }
442}
443
444
446{
447 if( m_previewPad->GetShape() != PAD_SHAPE::ROUNDRECT
448 && m_previewPad->GetShape() != PAD_SHAPE::CHAMFERED_RECT )
449 {
450 return;
451 }
452
453 wxObject* ctrl = event.GetEventObject();
454 wxString value = event.GetString();
455 bool changed = false;
456
457 if( ctrl == m_cornerRatioCtrl || ctrl == m_mixedCornerRatioCtrl )
458 {
459 double ratioPercent;
460
461 if( value.ToDouble( &ratioPercent ) )
462 {
463 // Clamp ratioPercent to acceptable value (0.0 to 50.0)
464 if( ratioPercent < 0.0 )
465 {
468 }
469 else if( ratioPercent > 50.0 )
470 {
473 }
474
475 if( ctrl == m_cornerRatioCtrl )
476 m_mixedCornerRatioCtrl->ChangeValue( value );
477 else
478 m_cornerRatioCtrl->ChangeValue( value );
479
480 changed = true;
481 }
482 }
483 else if( ctrl == m_chamferRatioCtrl || ctrl == m_mixedChamferRatioCtrl )
484 {
485 double ratioPercent;
486
487 if( value.ToDouble( &ratioPercent ) )
488 {
489 // Clamp ratioPercent to acceptable value (0.0 to 50.0)
490 if( ratioPercent < 0.0 )
491 {
494 }
495 else if( ratioPercent > 50.0 )
496 {
499 }
500
501 if( ctrl == m_chamferRatioCtrl )
502 m_mixedChamferRatioCtrl->ChangeValue( value );
503 else
504 m_chamferRatioCtrl->ChangeValue( value );
505
506 changed = true;
507 }
508 }
509
510 if( changed && transferDataToPad( m_previewPad ) )
512
513 redraw();
514}
515
516
518{
519 wxString msg;
520
521 // Disable pad net name wxTextCtrl if the caller is the footprint editor
522 // because nets are living only in the board managed by the board editor
524
533 m_layerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
534 m_layerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
536
537 VECTOR2I absPos;
538
539 if( m_currentPad )
540 {
541 absPos = m_currentPad->GetPosition();
542
543 if( FOOTPRINT* footprint = m_currentPad->GetParentFootprint() )
544 {
546
547 if( footprint->IsFlipped() )
548 {
549 // flip pad (up/down) around its position
551 relPos.y = - relPos.y;
552 }
553
554 m_previewPad->SetPosition( relPos );
556
557 // Display parent footprint info
558 msg.Printf( _("Footprint %s (%s), %s, rotated %g deg"),
559 footprint->Reference().GetShownText( false ),
560 footprint->Value().GetShownText( false ),
561 footprint->IsFlipped() ? _( "back side (mirrored)" ) : _( "front side" ),
562 footprint->GetOrientation().AsDegrees() );
563
564 m_FlippedWarningSizer->Show( footprint->IsFlipped() );
565 m_parentInfo->SetLabel( msg );
566 }
567
568 m_padNumCtrl->SetValue( m_previewPad->GetNumber() );
569 }
570 else
571 {
573 m_padNumCtrl->SetValue( padTool->GetLastPadNumber() );
574
576 {
578 {
579 case FOOTPRINT_ATTR_T::FP_THROUGH_HOLE:
580 m_previewPad->SetAttribute( PAD_ATTRIB::PTH );
581
582 if( m_previewPad->GetDrillSizeX() == 0 )
584
585 break;
586
587 case FOOTPRINT_ATTR_T::FP_SMD:
589 m_previewPad->SetAttribute( PAD_ATTRIB::SMD );
590 break;
591 }
592 }
593 }
594
596
598
599 // Display current pad parameters units:
600 m_posX.ChangeValue( absPos.x );
601 m_posY.ChangeValue( absPos.y );
602
605
608
609 m_offsetShapeOpt->SetValue( m_previewPad->GetOffset() != VECTOR2I() );
612
613 if( m_previewPad->GetDelta().x )
614 {
616 m_trapAxisCtrl->SetSelection( 0 );
617 }
618 else
619 {
621 m_trapAxisCtrl->SetSelection( 1 );
622 }
623
624 // Store the initial thermal spoke angle to restore it, because some initializations
625 // can change this value (mainly after m_PadShapeSelector initializations)
626 EDA_ANGLE spokeInitialAngle = m_previewPad->GetThermalSpokeAngle();
627
628 m_padToDieOpt->SetValue( m_previewPad->GetPadToDieLength() != 0 );
630
631 if( m_previewPad->GetLocalClearance().has_value() )
633 else
634 m_clearance.ChangeValue( wxEmptyString );
635
636 if( m_previewPad->GetLocalSolderMaskMargin().has_value() )
638 else
639 m_maskMargin.ChangeValue( wxEmptyString );
640
641 if( m_previewPad->GetLocalSolderPasteMargin().has_value() )
643 else
644 m_pasteMargin.ChangeValue( wxEmptyString );
645
648 else
649 m_pasteMarginRatio.ChangeValue( wxEmptyString );
650
655
664
666
668 {
669 default:
670 case ZONE_CONNECTION::INHERITED: m_ZoneConnectionChoice->SetSelection( 0 ); break;
671 case ZONE_CONNECTION::FULL: m_ZoneConnectionChoice->SetSelection( 1 ); break;
672 case ZONE_CONNECTION::THERMAL: m_ZoneConnectionChoice->SetSelection( 2 ); break;
673 case ZONE_CONNECTION::NONE: m_ZoneConnectionChoice->SetSelection( 3 ); break;
674 }
675
677 m_ZoneCustomPadShape->SetSelection( 1 );
678 else
679 m_ZoneCustomPadShape->SetSelection( 0 );
680
681 switch( m_previewPad->GetShape() )
682 {
683 default:
684 case PAD_SHAPE::CIRCLE: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_CIRCLE ); break;
685 case PAD_SHAPE::OVAL: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_OVAL ); break;
686 case PAD_SHAPE::RECTANGLE: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_RECT ); break;
687 case PAD_SHAPE::TRAPEZOID: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_TRAPEZOID ); break;
688 case PAD_SHAPE::ROUNDRECT: m_PadShapeSelector->SetSelection( CHOICE_SHAPE_ROUNDRECT ); break;
689
690 case PAD_SHAPE::CHAMFERED_RECT:
693 else
695 break;
696
697 case PAD_SHAPE::CUSTOM:
698 if( m_previewPad->GetAnchorPadShape() == PAD_SHAPE::RECTANGLE )
700 else
702 break;
703 }
704
713
715
716 // Type of pad selection
717 bool aperture =
718 m_previewPad->GetAttribute() == PAD_ATTRIB::SMD && m_previewPad->IsAperturePad();
719
720 if( aperture )
721 {
722 m_padType->SetSelection( APERTURE_DLG_TYPE );
723 }
724 else
725 {
726 switch( m_previewPad->GetAttribute() )
727 {
728 case PAD_ATTRIB::PTH: m_padType->SetSelection( PTH_DLG_TYPE ); break;
729 case PAD_ATTRIB::SMD: m_padType->SetSelection( SMD_DLG_TYPE ); break;
730 case PAD_ATTRIB::CONN: m_padType->SetSelection( CONN_DLG_TYPE ); break;
731 case PAD_ATTRIB::NPTH: m_padType->SetSelection( NPTH_DLG_TYPE ); break;
732 }
733 }
734
735 switch( m_previewPad->GetProperty() )
736 {
737 case PAD_PROP::NONE: m_choiceFabProperty->SetSelection( 0 ); break;
738 case PAD_PROP::BGA: m_choiceFabProperty->SetSelection( 1 ); break;
739 case PAD_PROP::FIDUCIAL_LOCAL: m_choiceFabProperty->SetSelection( 2 ); break;
740 case PAD_PROP::FIDUCIAL_GLBL: m_choiceFabProperty->SetSelection( 3 ); break;
741 case PAD_PROP::TESTPOINT: m_choiceFabProperty->SetSelection( 4 ); break;
742 case PAD_PROP::HEATSINK: m_choiceFabProperty->SetSelection( 5 ); break;
743 case PAD_PROP::CASTELLATED: m_choiceFabProperty->SetSelection( 6 ); break;
744 case PAD_PROP::MECHANICAL: m_choiceFabProperty->SetSelection( 7 ); break;
745 }
746
747 // Ensure the pad property is compatible with the pad type
748 if( m_previewPad->GetAttribute() == PAD_ATTRIB::NPTH )
749 {
750 m_choiceFabProperty->SetSelection( 0 );
751 m_choiceFabProperty->Enable( false );
752 }
753
754 if( m_previewPad->GetDrillShape() != PAD_DRILL_SHAPE::OBLONG )
755 m_holeShapeCtrl->SetSelection( 0 );
756 else
757 m_holeShapeCtrl->SetSelection( 1 );
758
761
762 // Update some dialog widgets state (Enable/disable options):
763 wxCommandEvent cmd_event;
764 OnPadShapeSelection( cmd_event );
765 OnOffsetCheckbox( cmd_event );
766
767 // Restore thermal spoke angle to its initial value, because it can be modified
768 // by the call to OnPadShapeSelection()
769 m_previewPad->SetThermalSpokeAngle( spokeInitialAngle );
771}
772
773
774void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
775{
776 redraw();
777 event.Skip();
778}
779
780
781void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
782{
784
786
787 // fix the pad render mode (filled/not filled)
788 auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
789
790 settings->m_ForcePadSketchModeOn = m_cbShowPadOutline->IsChecked();
791 settings->SetHighContrast( false );
792 settings->m_ContrastModeDisplay = HIGH_CONTRAST_MODE::NORMAL;
793
794 redraw();
795}
796
797
799{
800 switch( m_PadShapeSelector->GetSelection() )
801 {
805 m_shapePropsBook->SetSelection( 0 );
806 break;
807
809 m_shapePropsBook->SetSelection( 1 );
810 break;
811
813 {
814 m_shapePropsBook->SetSelection( 2 );
815
816 // Reasonable defaults
819
820 break;
821 }
822
824 m_shapePropsBook->SetSelection( 3 );
825
826 // Reasonable default
827 if( m_previewPad->GetChamferRectRatio() == 0.0 )
829
830 // Ensure the displayed value is up to date:
832
833 // A reasonable default is one corner chamfered (usual for some SMD pads).
834 if( !m_cbTopLeft->GetValue() && !m_cbTopRight->GetValue()
835 && !m_cbBottomLeft->GetValue() && !m_cbBottomRight->GetValue() )
836 {
837 m_cbTopLeft->SetValue( true );
838 m_cbTopRight->SetValue( false );
839 m_cbBottomLeft->SetValue( false );
840 m_cbBottomRight->SetValue( false );
841 }
842
843 break;
844
846 m_shapePropsBook->SetSelection( 4 );
847
848 // Reasonable defaults
850 && m_previewPad->GetChamferRectRatio() == 0.0 )
851 {
855 }
856
857 // Ensure the displayed values are up to date:
860 break;
861
862 case CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR: // PAD_SHAPE::CUSTOM, circular anchor
863 case CHOICE_SHAPE_CUSTOM_RECT_ANCHOR: // PAD_SHAPE::CUSTOM, rect anchor
864 m_shapePropsBook->SetSelection( 0 );
865 break;
866 }
867
868 // Note: must do this before enabling/disabling m_sizeY as we're using that as a flag to see
869 // what the last shape was.
870 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE )
871 {
872 if( m_sizeYCtrl->IsEnabled() && m_spokeAngle.GetAngleValue() == ANGLE_90 )
874 }
875 else
876 {
877 if( !m_sizeYCtrl->IsEnabled() && m_spokeAngle.GetAngleValue() == ANGLE_45 )
879 }
880
881 // Readjust props book size
882 wxSize size = m_shapePropsBook->GetSize();
883 size.y = m_shapePropsBook->GetPage( m_shapePropsBook->GetSelection() )->GetBestSize().y;
884 m_shapePropsBook->SetMaxSize( size );
885
888
889 m_offsetShapeOpt->Enable( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE );
890
891 if( !m_offsetShapeOpt->IsEnabled() )
892 m_offsetShapeOpt->SetValue( false );
893
894 // Show/hide controls depending on m_offsetShapeOpt being enabled
895 m_offsetCtrls->Show( m_offsetShapeOpt->GetValue() );
896 m_offsetShapeOptLabel->Show( m_offsetShapeOpt->GetValue() );
897
900
901 for( size_t i = 0; i < m_notebook->GetPageCount(); ++i )
902 m_notebook->GetPage( i )->Layout();
903
904 // Resize the dialog if its height is too small to show all widgets:
905 if( m_MainSizer->GetSize().y < m_MainSizer->GetMinSize().y )
906 m_MainSizer->SetSizeHints( this );
907
909 redraw();
910}
911
912
914{
917 redraw();
918}
919
920
921void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
922{
924 redraw();
925}
926
927
929{
930 m_rbCopperLayersSel->Clear();
931
932 switch( m_padType->GetSelection() )
933 {
934 case PTH_DLG_TYPE:
935 m_rbCopperLayersSel->Append( _( "All copper layers" ) );
936 m_rbCopperLayersSel->Append( wxString::Format( _( "%s, %s and connected layers" ),
938 m_board->GetLayerName( B_Cu ) ) );
939 m_rbCopperLayersSel->Append( _( "Connected layers only" ) );
940 m_rbCopperLayersSel->Append( _( "None" ) );
941 break;
942
943 case NPTH_DLG_TYPE:
944 m_rbCopperLayersSel->Append( wxString::Format( _( "%s and %s" ),
946 m_board->GetLayerName( B_Cu ) ) );
949 m_rbCopperLayersSel->Append( _( "None" ) );
950 break;
951
952 case SMD_DLG_TYPE:
953 case CONN_DLG_TYPE:
956 break;
957
959 m_rbCopperLayersSel->Append( _( "None" ) );
960 break;
961 }
962}
963
964
965void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
966{
967 bool hasHole = true;
968 bool hasConnection = true;
969 bool hasProperty = true;
970
971 switch( m_padType->GetSelection() )
972 {
973 case PTH_DLG_TYPE: hasHole = true; hasConnection = true; hasProperty = true; break;
974 case SMD_DLG_TYPE: hasHole = false; hasConnection = true; hasProperty = true; break;
975 case CONN_DLG_TYPE: hasHole = false; hasConnection = true; hasProperty = true; break;
976 case NPTH_DLG_TYPE: hasHole = true; hasConnection = false; hasProperty = false; break;
977 case APERTURE_DLG_TYPE: hasHole = false; hasConnection = false; hasProperty = true; break;
978 }
979
980 // Update Layers dropdown list and selects the "best" layer set for the new pad type:
983
984 m_gbSizerHole->Show( hasHole );
985 m_staticline6->Show( hasHole );
986
987 if( !hasHole )
988 {
989 m_holeX.ChangeValue( 0 );
990 m_holeY.ChangeValue( 0 );
991 }
992 else if( m_holeX.GetValue() == 0 )
993 {
994 if( m_currentPad )
995 {
998 }
999 else
1000 {
1002 }
1003 }
1004
1005 if( !hasConnection )
1006 {
1007 m_padNumCtrl->ChangeValue( wxEmptyString );
1009 m_padToDieOpt->SetValue( false );
1010 }
1011 else if( m_padNumCtrl->GetValue().IsEmpty() && m_currentPad )
1012 {
1013 m_padNumCtrl->ChangeValue( m_currentPad->GetNumber() );
1015 }
1016
1017 if( !hasProperty )
1018 m_choiceFabProperty->SetSelection( 0 );
1019
1020 m_choiceFabProperty->Enable( hasProperty );
1021
1023
1024 // Layout adjustment is needed if the hole details got shown/hidden
1025 m_LeftBoxSizer->Layout();
1026 redraw();
1027}
1028
1029
1030void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1031{
1032 bool hasHole = true;
1033 bool hasConnection = true;
1034
1035 switch( m_padType->GetSelection() )
1036 {
1037 case PTH_DLG_TYPE: /* PTH */ hasHole = true; hasConnection = true; break;
1038 case SMD_DLG_TYPE: /* SMD */ hasHole = false; hasConnection = true; break;
1039 case CONN_DLG_TYPE: /* CONN */ hasHole = false; hasConnection = true; break;
1040 case NPTH_DLG_TYPE: /* NPTH */ hasHole = true; hasConnection = false; break;
1041 case APERTURE_DLG_TYPE: /* Aperture */ hasHole = false; hasConnection = false; break;
1042 }
1043
1044 // Enable/disable hole controls
1045 m_holeShapeLabel->Enable( hasHole );
1046 m_holeShapeCtrl->Enable( hasHole );
1047 m_holeX.Enable( hasHole );
1048 m_holeY.Enable( hasHole && m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_OVAL );
1049
1050 // Enable/disable number and net
1051 m_padNumLabel->Enable( hasConnection );
1052 m_padNumCtrl->Enable( hasConnection );
1053
1054 if( m_padNetLabel->IsShown() )
1055 {
1056 m_padNetLabel->Enable( hasConnection && m_canEditNetName && m_currentPad );
1057 m_padNetSelector->Enable( hasConnection && m_canEditNetName && m_currentPad );
1058 }
1059
1060 // Enable/disable pad length-to-die
1061 m_padToDieOpt->Enable( hasConnection );
1062
1063 if( !m_padToDieOpt->IsEnabled() )
1064 m_padToDieOpt->SetValue( false );
1065
1066 // We can show/hide this here because it doesn't require the layout to be refreshed.
1067 // All the others have to be done in their event handlers because doing a layout here
1068 // causes infinite looping on MSW.
1069 m_padToDie.Show( m_padToDieOpt->GetValue() );
1070
1071 // Enable/disable Copper Layers control
1072 m_rbCopperLayersSel->Enable( m_padType->GetSelection() != APERTURE_DLG_TYPE );
1073
1075
1076 switch( m_padType->GetSelection() )
1077 {
1078 case PTH_DLG_TYPE:
1079 if( !cu_set.any() )
1080 m_stackupImagesBook->SetSelection( 3 );
1081 else if( !m_previewPad->GetRemoveUnconnected() )
1082 m_stackupImagesBook->SetSelection( 0 );
1083 else if( m_previewPad->GetKeepTopBottom() )
1084 m_stackupImagesBook->SetSelection( 1 );
1085 else
1086 m_stackupImagesBook->SetSelection( 2 );
1087
1088 break;
1089
1090 case NPTH_DLG_TYPE:
1091 if( cu_set.test( F_Cu ) && cu_set.test( B_Cu ) )
1092 m_stackupImagesBook->SetSelection( 4 );
1093 else if( cu_set.test( F_Cu ) )
1094 m_stackupImagesBook->SetSelection( 5 );
1095 else if( cu_set.test( B_Cu ) )
1096 m_stackupImagesBook->SetSelection( 6 );
1097 else
1098 m_stackupImagesBook->SetSelection( 7 );
1099
1100 break;
1101
1102 case SMD_DLG_TYPE:
1103 case CONN_DLG_TYPE:
1104 case APERTURE_DLG_TYPE:
1105 m_stackupImagesBook->ChangeSelection( 3 );
1106 break;
1107 }
1108
1110}
1111
1112
1114{
1115 event.Enable( !m_board->LegacyTeardrops() );
1116}
1117
1118
1120{
1121 event.Enable( !m_board->LegacyTeardrops() && m_curvedEdges->GetValue() );
1122}
1123
1124
1126{
1127 bool isOnCopperLayer = ( m_previewPad->GetLayerSet() & LSET::AllCuMask() ).any();
1128 m_nonCopperWarningBook->ChangeSelection( isOnCopperLayer ? 0 : 1 );
1129}
1130
1131
1132void DIALOG_PAD_PROPERTIES::updatePadLayersList( LSET layer_mask, bool remove_unconnected,
1133 bool keep_top_bottom )
1134{
1136
1137 switch( m_padType->GetSelection() )
1138 {
1139 case PTH_DLG_TYPE:
1140 if( !layer_mask.any() )
1141 layer_mask = PAD::PTHMask();
1142
1143 if( !( layer_mask & LSET::AllCuMask() ).any() )
1144 m_rbCopperLayersSel->SetSelection( 3 );
1145 else if( !remove_unconnected )
1146 m_rbCopperLayersSel->SetSelection( 0 );
1147 else if( keep_top_bottom )
1148 m_rbCopperLayersSel->SetSelection( 1 );
1149 else
1150 m_rbCopperLayersSel->SetSelection( 2 );
1151
1152 break;
1153
1154 case SMD_DLG_TYPE:
1155 if( !layer_mask.any() )
1156 layer_mask = PAD::SMDMask();
1157
1158 if( layer_mask.test( F_Cu ) )
1159 m_rbCopperLayersSel->SetSelection( 0 );
1160 else
1161 m_rbCopperLayersSel->SetSelection( 1 );
1162
1163 break;
1164
1165 case CONN_DLG_TYPE:
1166 if( !layer_mask.any() )
1167 layer_mask = PAD::ConnSMDMask();
1168
1169 if( layer_mask.test( F_Cu ) )
1170 m_rbCopperLayersSel->SetSelection( 0 );
1171 else
1172 m_rbCopperLayersSel->SetSelection( 1 );
1173
1174 break;
1175
1176 case NPTH_DLG_TYPE:
1177 if( !layer_mask.any() )
1178 layer_mask = PAD::UnplatedHoleMask();
1179
1180 if( layer_mask.test( F_Cu ) && layer_mask.test( B_Cu ) )
1181 m_rbCopperLayersSel->SetSelection( 0 );
1182 else if( layer_mask.test( F_Cu ) )
1183 m_rbCopperLayersSel->SetSelection( 1 );
1184 else if( layer_mask.test( B_Cu ) )
1185 m_rbCopperLayersSel->SetSelection( 2 );
1186 else
1187 m_rbCopperLayersSel->SetSelection( 3 );
1188
1189 break;
1190
1191 case APERTURE_DLG_TYPE:
1192 if( !layer_mask.any() )
1193 layer_mask = PAD::ApertureMask();
1194
1195 m_rbCopperLayersSel->SetSelection( 0 );
1196 break;
1197 }
1198
1199 m_layerFrontAdhesive->SetValue( layer_mask[F_Adhes] );
1200 m_layerBackAdhesive->SetValue( layer_mask[B_Adhes] );
1201
1202 m_layerFrontPaste->SetValue( layer_mask[F_Paste] );
1203 m_layerBackPaste->SetValue( layer_mask[B_Paste] );
1204
1205 m_layerFrontSilk->SetValue( layer_mask[F_SilkS] );
1206 m_layerBackSilk->SetValue( layer_mask[B_SilkS] );
1207
1208 m_layerFrontMask->SetValue( layer_mask[F_Mask] );
1209 m_layerBackMask->SetValue( layer_mask[B_Mask] );
1210
1211 m_layerECO1->SetValue( layer_mask[Eco1_User] );
1212 m_layerECO2->SetValue( layer_mask[Eco2_User] );
1213
1214 m_layerUserDwgs->SetValue( layer_mask[Dwgs_User] );
1215}
1216
1217
1219{
1220 bool retVal = DIALOG_SHIM::Show( aShow );
1221
1222 if( aShow )
1223 {
1224 // It *should* work to set the stackup bitmap in the constructor, but it doesn't.
1225 // wxWidgets needs to have these set when the panel is visible for some reason.
1226 // https://gitlab.com/kicad/code/kicad/-/issues/5534
1227 m_stackupImage0->SetBitmap( KiBitmapBundle( BITMAPS::pads_reset_unused ) );
1228 m_stackupImage1->SetBitmap( KiBitmapBundle( BITMAPS::pads_remove_unused_keep_bottom ) );
1229 m_stackupImage2->SetBitmap( KiBitmapBundle( BITMAPS::pads_remove_unused ) );
1230 m_stackupImage4->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_top_bottom ) );
1231 m_stackupImage5->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_top ) );
1232 m_stackupImage6->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth_bottom ) );
1233 m_stackupImage7->SetBitmap( KiBitmapBundle( BITMAPS::pads_npth ) );
1234
1235 Layout();
1236 }
1237
1238 return retVal;
1239}
1240
1241
1242void DIALOG_PAD_PROPERTIES::OnSetCopperLayers( wxCommandEvent& event )
1243{
1245 redraw();
1246}
1247
1248
1249void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
1250{
1252 redraw();
1253}
1254
1255
1257{
1259
1260 wxArrayString error_msgs;
1261 wxArrayString warning_msgs;
1262
1264 [&]( int errorCode, const wxString& msg )
1265 {
1266 if( errorCode == DRCE_PADSTACK_INVALID )
1267 error_msgs.Add( _( "Error: " ) + msg );
1268 else if( errorCode == DRCE_PADSTACK )
1269 warning_msgs.Add( _( "Warning: " ) + msg );
1270 else if( errorCode == DRCE_PAD_TH_WITH_NO_HOLE )
1271 error_msgs.Add( _( "Error: Through hole pad has no hole." ) );
1272 } );
1273
1274 if( error_msgs.GetCount() || warning_msgs.GetCount() )
1275 {
1276 wxString title = error_msgs.GetCount() ? _( "Pad Properties Errors" )
1277 : _( "Pad Properties Warnings" );
1278 HTML_MESSAGE_BOX dlg( this, title );
1279
1280 wxArrayString msgs = error_msgs;
1281
1282 for( const wxString& msg : warning_msgs )
1283 msgs.Add( msg );
1284
1285 dlg.ListSet( msgs );
1286
1287 dlg.ShowModal();
1288 }
1289
1290 return error_msgs.GetCount() == 0;
1291}
1292
1293
1295{
1296 if( !m_canUpdate )
1297 return;
1298
1300 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( view->GetPainter() );
1301 KIGFX::PCB_RENDER_SETTINGS* settings = painter->GetSettings();
1302
1304
1305 // The layer used to place primitive items selected when editing custom pad shapes
1306 // we use here a layer never used in a pad:
1307 #define SELECTED_ITEMS_LAYER Dwgs_User
1308
1311
1313
1314 view->Update( m_previewPad );
1315
1316 // delete previous items if highlight list
1317 while( m_highlight.size() )
1318 {
1319 delete m_highlight.back(); // the dtor also removes item from view
1320 m_highlight.pop_back();
1321 }
1322
1323 BOX2I bbox = m_previewPad->ViewBBox();
1324
1325 if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
1326 {
1327 // The origin always goes in the middle of the canvas; we want offsetting the pad
1328 // shape to move the pad, not the hole
1329 bbox.Move( -m_previewPad->GetPosition() );
1330 int maxXExtent = std::max( abs( bbox.GetLeft() ), abs( bbox.GetRight() ) );
1331 int maxYExtent = std::max( abs( bbox.GetTop() ), abs( bbox.GetBottom() ) );
1332
1333 // Don't blow up the GAL on too-large numbers
1334 if( maxXExtent > INT_MAX / 4 )
1335 maxXExtent = INT_MAX / 4;
1336
1337 if( maxYExtent > INT_MAX / 4 )
1338 maxYExtent = INT_MAX / 4;
1339
1340 BOX2D viewBox( m_previewPad->GetPosition(), {0, 0} );
1341 BOX2D canvasBox( m_previewPad->GetPosition(), {0, 0} );
1342 viewBox.Inflate( maxXExtent * 1.4, maxYExtent * 1.4 ); // add a margin
1343 canvasBox.Inflate( maxXExtent * 2.0, maxYExtent * 2.0 );
1344
1345 view->SetBoundary( canvasBox );
1346
1347 // Autozoom
1348 view->SetViewport( viewBox );
1349
1352 }
1353}
1354
1355
1357{
1358 if( !wxDialog::TransferDataToWindow() )
1359 return false;
1360
1361 if( !m_panelGeneral->TransferDataToWindow() )
1362 return false;
1363
1364 if( !m_localSettingsPanel->TransferDataToWindow() )
1365 return false;
1366
1367 return true;
1368}
1369
1370
1372{
1373 BOARD_COMMIT commit( m_parent );
1374
1375 if( !wxDialog::TransferDataFromWindow() )
1376 return false;
1377
1378 if( !m_panelGeneral->TransferDataFromWindow() )
1379 return false;
1380
1381 if( !m_localSettingsPanel->TransferDataFromWindow() )
1382 return false;
1383
1384 if( !padValuesOK() )
1385 return false;
1386
1388 return false;
1389
1391 padTool->SetLastPadNumber( m_masterPad->GetNumber() );
1392
1393 // m_masterPad is a pattern: ensure there is no net for this pad:
1395
1396 if( !m_currentPad ) // Set current Pad parameters
1397 return true;
1398
1399 commit.Modify( m_currentPad );
1400
1401 // Update values
1405
1407
1408 VECTOR2I size = m_masterPad->GetDelta();
1409 m_currentPad->SetDelta( size );
1410
1413
1414 VECTOR2I offset = m_masterPad->GetOffset();
1415 m_currentPad->SetOffset( offset );
1416
1418
1419 if( m_masterPad->GetShape() != PAD_SHAPE::CUSTOM )
1421
1424
1427
1429
1430 int padNetcode = NETINFO_LIST::UNCONNECTED;
1431
1432 // For PAD_ATTRIB::NPTH, ensure there is no net name selected
1433 if( m_masterPad->GetAttribute() != PAD_ATTRIB::NPTH )
1434 padNetcode = m_padNetSelector->GetSelectedNetcode();
1435
1436 m_currentPad->SetNetCode( padNetcode );
1448
1450
1451 // rounded rect pads with radius ratio = 0 are in fact rect pads.
1452 // So set the right shape (and perhaps issues with a radius = 0)
1453 if( m_currentPad->GetShape() == PAD_SHAPE::ROUNDRECT &&
1455 {
1456 m_currentPad->SetShape( PAD_SHAPE::RECTANGLE );
1457 }
1458
1459 // Set the fabrication property:
1461
1462 // define the way the clearance area is defined in zones
1464
1466 {
1467 // flip pad (up/down) around its position
1469 }
1470
1472
1474
1475 // redraw the area where the pad was
1477
1478 commit.Push( _( "Edit Pad Properties" ) );
1479
1480 return true;
1481}
1482
1483
1485{
1486 PAD_PROP prop = PAD_PROP::NONE;
1487
1488 switch( m_choiceFabProperty->GetSelection() )
1489 {
1490 case 0: prop = PAD_PROP::NONE; break;
1491 case 1: prop = PAD_PROP::BGA; break;
1492 case 2: prop = PAD_PROP::FIDUCIAL_LOCAL; break;
1493 case 3: prop = PAD_PROP::FIDUCIAL_GLBL; break;
1494 case 4: prop = PAD_PROP::TESTPOINT; break;
1495 case 5: prop = PAD_PROP::HEATSINK; break;
1496 case 6: prop = PAD_PROP::CASTELLATED; break;
1497 case 7: prop = PAD_PROP::MECHANICAL; break;
1498 }
1499
1500 return prop;
1501}
1502
1504{
1505 if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
1506 {
1507 m_holeXLabel->SetLabel( _( "Diameter:" ) );
1508 m_holeY.Show( false );
1509 }
1510 else
1511 {
1512 m_holeXLabel->SetLabel( _( "Hole size X:" ) );
1513 m_holeY.Show( true );
1514 }
1515
1516 m_holeXLabel->GetParent()->Layout();
1517}
1518
1520{
1521 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE
1523 {
1524 m_sizeXLabel->SetLabel( _( "Diameter:" ) );
1525 m_sizeY.Show( false );
1526 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
1527 m_minTrackWidthHint->SetLabel( _( "d" ) );
1528 m_stLenPercentHint->SetLabel( _( "d" ) );
1529 m_stWidthPercentHint->SetLabel( _( "d" ) );
1530 }
1531 else
1532 {
1533 m_sizeXLabel->SetLabel( _( "Pad size X:" ) );
1534 m_sizeY.Show( true );
1535 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_rect_sizes ) );
1536 m_minTrackWidthHint->SetLabel( _( "w" ) );
1537 m_stLenPercentHint->SetLabel( _( "w" ) );
1538 m_stWidthPercentHint->SetLabel( _( "w" ) );
1539 }
1540
1541 m_sizeXLabel->GetParent()->Layout();
1542 resetSize();
1543 Layout();
1544 m_MainSizer->Fit( this );
1545}
1546
1547
1549{
1550 if( !Validate() )
1551 return false;
1552
1553 if( !m_panelGeneral->Validate() )
1554 return false;
1555
1556 if( !m_localSettingsPanel->Validate() )
1557 return false;
1558
1559 if( !m_spokeWidth.Validate( 0, INT_MAX ) )
1560 return false;
1561
1562 aPad->SetAttribute( code_type[m_padType->GetSelection()] );
1563 aPad->SetShape( code_shape[m_PadShapeSelector->GetSelection()] );
1564
1566 aPad->SetAnchorPadShape( PAD_SHAPE::RECTANGLE );
1567 else
1568 aPad->SetAnchorPadShape( PAD_SHAPE::CIRCLE );
1569
1570 if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
1572
1573 aPad->GetTeardropParams().m_Enabled = m_cbTeardrops->GetValue();
1580
1581 if( m_curvedEdges->GetValue() )
1583 else
1585
1587
1588 // Read pad clearances values:
1589 if( m_clearance.IsNull() )
1590 aPad->SetLocalClearance( {} );
1591 else
1593
1594 if( m_maskMargin.IsNull() )
1595 aPad->SetLocalSolderMaskMargin( {} );
1596 else
1598
1599 if( m_pasteMargin.IsNull() )
1600 aPad->SetLocalSolderPasteMargin( {} );
1601 else
1603
1606 else
1608
1612
1613 // And rotation
1615
1616 switch( m_ZoneConnectionChoice->GetSelection() )
1617 {
1618 default:
1619 case 0: aPad->SetLocalZoneConnection( ZONE_CONNECTION::INHERITED ); break;
1620 case 1: aPad->SetLocalZoneConnection( ZONE_CONNECTION::FULL ); break;
1621 case 2: aPad->SetLocalZoneConnection( ZONE_CONNECTION::THERMAL ); break;
1622 case 3: aPad->SetLocalZoneConnection( ZONE_CONNECTION::NONE ); break;
1623 }
1624
1626
1627 if( FOOTPRINT* fp = aPad->GetParentFootprint() )
1628 {
1629 pos -= fp->GetPosition();
1630 RotatePoint( pos, -fp->GetOrientation() );
1631 }
1632
1633 aPad->SetPosition( pos );
1634
1635 if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
1636 {
1637 aPad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
1639 }
1640 else
1641 {
1642 aPad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
1644 }
1645
1646 if( aPad->GetShape() == PAD_SHAPE::CIRCLE )
1648 else
1650
1651 // For a trapezoid, test delta value (be sure delta is not too large for pad size)
1652 // remember DeltaSize.x is the Y size variation
1653 bool error = false;
1654 VECTOR2I delta( 0, 0 );
1655
1656 if( aPad->GetShape() == PAD_SHAPE::TRAPEZOID )
1657 {
1658 // For a trapezoid, only one of delta.x or delta.y is not 0, depending on axis.
1659 if( m_trapAxisCtrl->GetSelection() == 0 )
1661 else
1663
1664 if( delta.x < 0 && delta.x < -aPad->GetSize().y )
1665 {
1666 delta.x = -aPad->GetSize().y + 2;
1667 error = true;
1668 }
1669
1670 if( delta.x > 0 && delta.x > aPad->GetSize().y )
1671 {
1672 delta.x = aPad->GetSize().y - 2;
1673 error = true;
1674 }
1675
1676 if( delta.y < 0 && delta.y < -aPad->GetSize().x )
1677 {
1678 delta.y = -aPad->GetSize().x + 2;
1679 error = true;
1680 }
1681
1682 if( delta.y > 0 && delta.y > aPad->GetSize().x )
1683 {
1684 delta.y = aPad->GetSize().x - 2;
1685 error = true;
1686 }
1687 }
1688
1689 aPad->SetDelta( delta );
1690
1691 if( m_offsetShapeOpt->GetValue() )
1693 else
1694 aPad->SetOffset( VECTOR2I() );
1695
1696 // Read pad length die
1697 if( m_padToDieOpt->GetValue() )
1699 else
1700 aPad->SetPadToDieLength( 0 );
1701
1702 aPad->SetNumber( m_padNumCtrl->GetValue() );
1704
1705 int chamfers = 0;
1706
1707 if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CHAMFERED_RECT )
1708 {
1709 if( m_cbTopLeft->GetValue() )
1710 chamfers |= RECT_CHAMFER_TOP_LEFT;
1711
1712 if( m_cbTopRight->GetValue() )
1713 chamfers |= RECT_CHAMFER_TOP_RIGHT;
1714
1715 if( m_cbBottomLeft->GetValue() )
1716 chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
1717
1718 if( m_cbBottomRight->GetValue() )
1719 chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
1720 }
1721 else if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CHAMFERED_ROUNDED_RECT )
1722 {
1723 if( m_cbTopLeft1->GetValue() )
1724 chamfers |= RECT_CHAMFER_TOP_LEFT;
1725
1726 if( m_cbTopRight1->GetValue() )
1727 chamfers |= RECT_CHAMFER_TOP_RIGHT;
1728
1729 if( m_cbBottomLeft1->GetValue() )
1730 chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
1731
1732 if( m_cbBottomRight1->GetValue() )
1733 chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
1734 }
1735 aPad->SetChamferPositions( chamfers );
1736
1737 if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
1738 {
1739 // The pad custom has a "anchor pad" (a basic shape: round or rect pad)
1740 // that is the minimal area of this pad, and is useful to ensure a hole
1741 // diameter is acceptable, and is used in Gerber files as flashed area
1742 // reference
1743 if( aPad->GetAnchorPadShape() == PAD_SHAPE::CIRCLE )
1745 }
1746
1747 // Define the way the clearance area is defined in zones. Since all non-custom pad
1748 // shapes are convex to begin with, this really only makes any difference for custom
1749 // pad shapes.
1750 aPad->SetCustomShapeInZoneOpt( m_ZoneCustomPadShape->GetSelection() == 0 ?
1753
1754 switch( aPad->GetAttribute() )
1755 {
1756 case PAD_ATTRIB::PTH:
1757 break;
1758
1759 case PAD_ATTRIB::CONN:
1760 case PAD_ATTRIB::SMD:
1761 // SMD and PAD_ATTRIB::CONN has no hole.
1762 // basically, SMD and PAD_ATTRIB::CONN are same type of pads
1763 // PAD_ATTRIB::CONN has just a default non technical layers that differs from SMD
1764 // and are intended to be used in virtual edge board connectors
1765 // However we can accept a non null offset,
1766 // mainly to allow complex pads build from a set of basic pad shapes
1767 aPad->SetDrillSize( VECTOR2I( 0, 0 ) );
1768 break;
1769
1770 case PAD_ATTRIB::NPTH:
1771 // Mechanical purpose only:
1772 // no net name, no pad name allowed
1773 aPad->SetNumber( wxEmptyString );
1775 break;
1776
1777 default:
1778 wxFAIL_MSG( wxT( "DIALOG_PAD_PROPERTIES::transferDataToPad: unknown pad type" ) );
1779 break;
1780 }
1781
1782 if( aPad->GetShape() == PAD_SHAPE::ROUNDRECT )
1783 {
1785 }
1786 else if( aPad->GetShape() == PAD_SHAPE::CHAMFERED_RECT )
1787 {
1789 {
1792 }
1793 else // Choice is CHOICE_SHAPE_CHAMFERED_RECT, no rounded corner
1794 {
1796 aPad->SetRoundRectRadiusRatio( 0 );
1797 }
1798 }
1799
1801
1802 LSET padLayerMask = LSET();
1803 int copperLayersChoice = m_rbCopperLayersSel->GetSelection();
1804
1806
1807 switch( m_padType->GetSelection() )
1808 {
1809 case PTH_DLG_TYPE:
1810 switch( copperLayersChoice )
1811 {
1812 case 0:
1813 // All copper layers
1814 padLayerMask |= LSET::AllCuMask();
1815 break;
1816
1817 case 1:
1818 // Front, back and connected
1819 padLayerMask |= LSET::AllCuMask();
1822 break;
1823
1824 case 2:
1825 // Connected only
1826 padLayerMask |= LSET::AllCuMask();
1828 break;
1829
1830 case 3:
1831 // No copper layers
1832 break;
1833 }
1834
1835 break;
1836
1837 case NPTH_DLG_TYPE:
1838 switch( copperLayersChoice )
1839 {
1840 case 0: padLayerMask.set( F_Cu ).set( B_Cu ); break;
1841 case 1: padLayerMask.set( F_Cu ); break;
1842 case 2: padLayerMask.set( B_Cu ); break;
1843 default: break;
1844 }
1845
1846 break;
1847
1848 case SMD_DLG_TYPE:
1849 case CONN_DLG_TYPE:
1850 switch( copperLayersChoice )
1851 {
1852 case 0: padLayerMask.set( F_Cu ); break;
1853 case 1: padLayerMask.set( B_Cu ); break;
1854 }
1855
1856 break;
1857
1858 case APERTURE_DLG_TYPE:
1859 // no copper layers
1860 break;
1861 }
1862
1863 if( m_layerFrontAdhesive->GetValue() )
1864 padLayerMask.set( F_Adhes );
1865
1866 if( m_layerBackAdhesive->GetValue() )
1867 padLayerMask.set( B_Adhes );
1868
1869 if( m_layerFrontPaste->GetValue() )
1870 padLayerMask.set( F_Paste );
1871
1872 if( m_layerBackPaste->GetValue() )
1873 padLayerMask.set( B_Paste );
1874
1875 if( m_layerFrontSilk->GetValue() )
1876 padLayerMask.set( F_SilkS );
1877
1878 if( m_layerBackSilk->GetValue() )
1879 padLayerMask.set( B_SilkS );
1880
1881 if( m_layerFrontMask->GetValue() )
1882 padLayerMask.set( F_Mask );
1883
1884 if( m_layerBackMask->GetValue() )
1885 padLayerMask.set( B_Mask );
1886
1887 if( m_layerECO1->GetValue() )
1888 padLayerMask.set( Eco1_User );
1889
1890 if( m_layerECO2->GetValue() )
1891 padLayerMask.set( Eco2_User );
1892
1893 if( m_layerUserDwgs->GetValue() )
1894 padLayerMask.set( Dwgs_User );
1895
1896 aPad->SetLayerSet( padLayerMask );
1897
1898 return !error;
1899}
1900
1901
1902void DIALOG_PAD_PROPERTIES::OnOffsetCheckbox( wxCommandEvent& event )
1903{
1904 if( m_offsetShapeOpt->GetValue() )
1905 {
1908 }
1909
1910 // Show/hide controls depending on m_offsetShapeOpt being enabled
1911 m_offsetCtrls->Show( m_offsetShapeOpt->GetValue() );
1912 m_offsetShapeOptLabel->Show( m_offsetShapeOpt->GetValue() );
1913
1914 for( size_t i = 0; i < m_notebook->GetPageCount(); ++i )
1915 m_notebook->GetPage( i )->Layout();
1916
1917 OnValuesChanged( event );
1918}
1919
1920
1922{
1923 if( m_padToDieOpt->GetValue() && m_currentPad )
1925
1926 OnValuesChanged( event );
1927}
1928
1929
1930void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
1931{
1932 if( m_canUpdate )
1933 {
1935 return;
1936
1937 // If the pad size has changed, update the displayed values for rounded rect pads.
1939
1940 redraw();
1941 }
1942}
1943
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=std::numeric_limits< size_t >::max(), bool value=true)
Definition: base_set.h:61
bool test(size_t pos) const
Definition: base_set.h:47
bool any() const
Definition: base_set.h:55
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
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:92
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:264
VECTOR2I GetFPRelativePosition() const
Definition: board_item.cpp:293
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:218
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:864
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:447
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:575
bool LegacyTeardrops() const
Definition: board.h:1254
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:874
const SizeVec & GetSize() const
Definition: box2.h:196
coord_type GetTop() const
Definition: box2.h:219
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:128
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
coord_type GetRight() const
Definition: box2.h:207
coord_type GetLeft() const
Definition: box2.h:218
coord_type GetBottom() const
Definition: box2.h:212
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)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
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.
bool Show(bool aShow) 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
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 onTeardropCurvePointsUpdateUi(wxUpdateUIEvent &event) override
void OnDrillShapeSelected(wxCommandEvent &event) override
void OnUpdateUI(wxUpdateUIEvent &event) 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 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:228
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:279
bool IsFlipped() const
Definition: footprint.h:380
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:175
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:180
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)
Load new settings from program common settings.
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
void SetViewport(const BOX2D &aViewport)
Set the visible area of the VIEW.
Definition: view.cpp:559
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:317
void SetBoundary(const BOX2D &aBoundary)
Set limits for view area.
Definition: view.h:287
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:1687
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:203
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:871
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:221
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:35
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:732
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 SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
Definition: padstack.h:273
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
bool IsAperturePad() const
Definition: pad.h:402
void SetAttribute(PAD_ATTRIB aAttribute)
Definition: pad.cpp:745
void SetLayerSet(LSET aLayers) override
Definition: pad.h:391
PAD_PROP GetProperty() const
Definition: pad.h:398
bool GetRemoveUnconnected() const
Definition: pad.h:644
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:392
int GetSizeX() const
Definition: pad.h:259
std::optional< double > GetLocalSolderPasteMarginRatio() const
Definition: pad.h:425
const VECTOR2I & GetDrillSize() const
Definition: pad.h:267
PAD_ATTRIB GetAttribute() const
Definition: pad.h:395
static LSET PTHMask()
layer set for a through hole pad
Definition: pad.cpp:286
void SetThermalGap(int aGap)
Definition: pad.h:583
void SetThermalSpokeAngle(const EDA_ANGLE &aAngle)
The orientation of the thermal spokes.
Definition: pad.h:564
const wxString & GetNumber() const
Definition: pad.h:134
int GetRoundRectCornerRadius() const
Definition: pad.cpp:425
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
Definition: pad.h:429
void DeletePrimitivesList()
Clear the basic shapes list.
VECTOR2I GetPosition() const override
Definition: pad.h:201
void SetProperty(PAD_PROP aProperty)
Definition: pad.cpp:793
const std::vector< std::shared_ptr< PCB_SHAPE > > & GetPrimitives() const
Accessor to the basic shape list for custom-shaped pads.
Definition: pad.h:318
EDA_ANGLE GetThermalSpokeAngle() const
Definition: pad.h:568
void SetOffset(const VECTOR2I &aOffset)
Definition: pad.h:273
void SetChamferRectRatio(double aChamferScale)
Has meaning only for chamfered rectangular pads.
Definition: pad.cpp:445
const VECTOR2I & GetOffset() const
Definition: pad.h:274
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: pad.cpp:307
void SetRoundRectCornerRadius(double aRadius)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:431
int GetDrillSizeX() const
Definition: pad.h:269
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.h:372
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
Definition: pad.h:414
bool GetKeepTopBottom() const
Definition: pad.h:660
void SetLocalZoneConnection(ZONE_CONNECTION aType)
Definition: pad.h:434
std::optional< int > GetLocalClearance() const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
Definition: pad.h:410
void SetDelta(const VECTOR2I &aSize)
Definition: pad.h:263
void SetPadstack(const PADSTACK &aPadstack)
Definition: pad.h:280
void SetPosition(const VECTOR2I &aPos) override
Definition: pad.h:195
const PADSTACK & Padstack() const
Definition: pad.h:278
const VECTOR2I & GetDelta() const
Definition: pad.h:264
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: pad.cpp:300
void SetDrillSize(const VECTOR2I &aSize)
Definition: pad.h:266
PAD_SHAPE GetShape() const
Definition: pad.h:193
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition: pad.h:359
PADSTACK::CUSTOM_SHAPE_ZONE_MODE GetCustomShapeInZoneOpt() const
Definition: pad.h:214
PAD_DRILL_SHAPE GetDrillShape() const
Definition: pad.h:377
void Flip(const VECTOR2I &VECTOR2I, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pad.cpp:826
static LSET ApertureMask()
layer set for an aperture pad
Definition: pad.cpp:314
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: pad.cpp:1667
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: pad.cpp:293
std::optional< int > GetLocalSolderPasteMargin() const
Definition: pad.h:419
void CheckPad(UNITS_PROVIDER *aUnitsProvider, const std::function< void(int aErrorCode, const wxString &aMsg)> &aErrorHandler) const
Definition: pad.cpp:2048
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pad.h:413
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
Definition: pad.h:420
void SetShape(PAD_SHAPE aShape)
Set the new shape of this pad.
Definition: pad.h:184
int GetSizeY() const
Definition: pad.h:261
int GetThermalSpokeWidth() const
Definition: pad.h:555
EDA_ANGLE GetFPRelativeOrientation() const
Definition: pad.cpp:817
void SetFPRelativeOrientation(const EDA_ANGLE &aAngle)
Definition: pad.cpp:808
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:224
void SetRoundRectRadiusRatio(double aRadiusScale)
Has meaning only for rounded rectangle pads.
Definition: pad.cpp:437
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Definition: pad.h:235
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
Definition: pad.cpp:801
int GetChamferPositions() const
Definition: pad.h:624
void ReplacePrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
void SetLocalClearance(std::optional< int > aClearance)
Definition: pad.h:411
ZONE_CONNECTION GetLocalZoneConnection() const
Definition: pad.h:435
void SetThermalSpokeWidth(int aWidth)
Set the width of the thermal spokes connecting the pad to a zone.
Definition: pad.h:554
void SetSize(const VECTOR2I &aSize)
Definition: pad.h:251
double GetRoundRectRadiusRatio() const
Definition: pad.h:605
int GetThermalGap() const
Definition: pad.h:584
const VECTOR2I & GetSize() const
Definition: pad.h:256
void SetChamferPositions(int aPositions)
Has meaning only for chamfered rectangular pads.
Definition: pad.h:623
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:206
double GetChamferRectRatio() const
Definition: pad.h:614
void SetPadToDieLength(int aLength)
Definition: pad.h:407
int GetPadToDieLength() const
Definition: pad.h:408
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
Returns 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.
int m_CurveSegCount
True if the teardrop should be curved.
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.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
int GetIntValue()
Definition: unit_binder.h:127
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:71
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.
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:188
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[]
static bool PadHasMeaningfulRoundingRadius(const PAD &aPad)
Returns true if the pad's rounding ratio is valid (i.e.
#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
static double GetDefaultIpcRoundingRatio(const PAD &aPad)
Get a sensible default for a rounded rectangle pad's rounding ratio.
#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:59
@ DRCE_PADSTACK_INVALID
Definition: drc_item.h:60
@ DRCE_PAD_TH_WITH_NO_HOLE
Definition: drc_item.h:80
#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_GRID
Definition: layer_ids.h:209
@ B_Adhes
Definition: layer_ids.h:97
@ Dwgs_User
Definition: layer_ids.h:109
@ F_Paste
Definition: layer_ids.h:101
@ F_Adhes
Definition: layer_ids.h:98
@ B_Mask
Definition: layer_ids.h:106
@ B_Cu
Definition: layer_ids.h:95
@ Eco1_User
Definition: layer_ids.h:111
@ F_Mask
Definition: layer_ids.h:107
@ B_Paste
Definition: layer_ids.h:100
@ F_SilkS
Definition: layer_ids.h:104
@ Eco2_User
Definition: layer_ids.h:112
@ B_SilkS
Definition: layer_ids.h:103
@ 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:154
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
Definition: padstack.h:74
@ 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:46
PAD_PROP
The set of pad properties used in Gerber files (Draw files, and P&P files) to define some properties ...
Definition: padstack.h:91
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:228
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:673
VECTOR2< double > VECTOR2D
Definition: vector2d.h:672