KiCad PCB EDA Suite
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, dick@softplc.com
6  * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2019 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 <fctsys.h>
28 #include <common.h>
29 #include <gr_basic.h>
31 #include <view/view_controls.h>
32 #include <trigo.h>
33 #include <class_drawpanel.h>
34 #include <confirm.h>
35 #include <pcbnew.h>
36 #include <pcb_base_frame.h>
37 #include <base_units.h>
38 #include <board_commit.h>
39 #include <bitmaps.h>
40 
41 #include <class_board.h>
42 #include <class_module.h>
43 #include <pcb_painter.h>
44 #include <widgets/net_selector.h>
45 
46 #include <dialog_pad_properties.h>
47 
48 #include <dialog_pad_properties.h>
49 #include <html_messagebox.h>
50 
51 #include <convert_basic_shapes_to_polygon.h> // for enum RECT_CHAMFER_POSITIONS definition
52 
53 
54 // list of pad shapes, ordered like the pad shape wxChoice in dialog.
56 {
63  PAD_SHAPE_CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
64  PAD_SHAPE_CUSTOM // choice = PAD_SHAPE_CUSTOM_RECT_ANCHOR
65 };
66 
67 // the ordered index of the pad shape wxChoice in dialog.
68 // keep it consistent with code_shape[] and dialog strings
70 {
79 };
80 
82 {
87  PAD_ATTRIB_CONN // Aperture pad (type CONN with no copper layers)
88 };
89 
90 // Default mask layers setup for pads according to the pad type
91 static const LSET std_pad_layers[] =
92 {
93  D_PAD::StandardMask(), // PAD_ATTRIB_STANDARD:
94  D_PAD::SMDMask(), // PAD_ATTRIB_SMD:
95  D_PAD::ConnSMDMask(), // PAD_ATTRIB_CONN:
96  D_PAD::UnplatedHoleMask(), // PAD_ATTRIB_HOLE_NOT_PLATED:
98 };
99 
100 
102 {
103  DIALOG_PAD_PROPERTIES dlg( this, aPad );
104  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
105 }
106 
107 
109  DIALOG_PAD_PROPERTIES_BASE( aParent ),
110  m_parent( aParent ),
111  m_canUpdate( false ),
112  m_posX( aParent, m_posXLabel, m_posXCtrl, m_posXUnits ),
113  m_posY( aParent, m_posYLabel, m_posYCtrl, m_posYUnits ),
114  m_sizeX( aParent, m_sizeXLabel, m_sizeXCtrl, m_sizeXUnits, true ),
115  m_sizeY( aParent, m_sizeYLabel, m_sizeYCtrl, m_sizeYUnits, true ),
116  m_offsetX( aParent, m_offsetXLabel, m_offsetXCtrl, m_offsetXUnits, true ),
117  m_offsetY( aParent, m_offsetYLabel, m_offsetYCtrl, m_offsetYUnits, true ),
118  m_padToDie( aParent, m_padToDieLabel, m_padToDieCtrl, m_padToDieUnits, true ),
119  m_trapDelta( aParent, m_trapDeltaLabel, m_trapDeltaCtrl, m_trapDeltaUnits, true ),
120  m_cornerRadius( aParent, m_cornerRadiusLabel, m_tcCornerRadius, m_cornerRadiusUnits, true ),
121  m_holeX( aParent, m_holeXLabel, m_holeXCtrl, m_holeXUnits, true ),
122  m_holeY( aParent, m_holeYLabel, m_holeYCtrl, m_holeYUnits, true ),
123  m_OrientValidator( 1, &m_OrientValue ),
124  m_clearance( aParent, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits, true ),
125  m_maskClearance( aParent, m_maskClearanceLabel, m_maskClearanceCtrl, m_maskClearanceUnits, true ),
126  m_pasteClearance( aParent, m_pasteClearanceLabel, m_pasteClearanceCtrl, m_pasteClearanceUnits, true ),
127  m_spokeWidth( aParent, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits, true ),
128  m_thermalGap( aParent, m_thermalGapLabel, m_thermalGapCtrl, m_thermalGapUnits, true )
129 {
130  m_currentPad = aPad; // aPad can be NULL, if the dialog is called
131  // from the footprint editor to set default pad setup
132 
134 
136 
137  m_OrientValidator.SetRange( -360.0, 360.0 );
138  m_orientation->SetValidator( m_OrientValidator );
139  m_OrientValidator.SetWindow( m_orientation );
140 
141  m_cbShowPadOutline->SetValue( m_sketchPreview );
142 
143  m_FlippedWarningIcon->SetBitmap( KiBitmap( dialog_warning_xpm ) );
144  m_nonCopperWarningIcon->SetBitmap( KiBitmap( dialog_warning_xpm ) );
145 
147  m_dummyPad = new D_PAD( (MODULE*) NULL );
148 
149  if( aPad )
150  {
151  *m_dummyPad = *aPad;
153  }
154  else // We are editing a "master" pad, i.e. a template to create new pads
156 
157  initValues();
158 
159  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
160  infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
161  m_techLayersLabel->SetFont( infoFont );
162  m_parentInfoLine1->SetFont( infoFont );
163  m_parentInfoLine2->SetFont( infoFont );
164  m_staticTextInfoNegVal->SetFont( infoFont );
165  m_staticTextInfoPosValue->SetFont( infoFont );
166  m_nonCopperNote->SetFont( infoFont );
167 
168  // Usually, TransferDataToWindow is called by OnInitDialog
169  // calling it here fixes all widget sizes so FinishDialogSettings can safely fix minsizes
171 
172  // Initialize canvas to be able to display the dummy pad:
173  prepareCanvas();
174 
176  m_sdbSizerOK->SetDefault();
177  m_canUpdate = true;
178 
179  m_PadNetSelector->Connect( NET_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ), NULL, this );
180 
181  // Now all widgets have the size fixed, call FinishDialogSettings
183 }
184 
185 
187 {
188  m_PadNetSelector->Disconnect( NET_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES::OnValuesChanged ), NULL, this );
189 
190  delete m_dummyPad;
191  delete m_axisOrigin;
192 }
193 
194 
195 bool DIALOG_PAD_PROPERTIES::m_sketchPreview = false; // Stores the pad draw option during a session
196 
197 
198 void DIALOG_PAD_PROPERTIES::OnInitDialog( wxInitDialogEvent& event )
199 {
200  m_selectedColor = COLOR4D( 1.0, 1.0, 1.0, 0.7 );
201 
202  // Needed on some WM to be sure the pad is redrawn according to the final size
203  // of the canvas, with the right zoom factor
204  redraw();
205 }
206 
207 
208 void DIALOG_PAD_PROPERTIES::OnCancel( wxCommandEvent& event )
209 {
210  // Mandatory to avoid m_panelShowPadGal trying to draw something
211  // in a non valid context during closing process:
212  if( m_parent->IsGalCanvasActive() )
214 
215  // Now call default handler for wxID_CANCEL command event
216  event.Skip();
217 }
218 
219 
221 {
222  // Enable or disable the widgets in page managing custom shape primitives
223  m_listCtrlPrimitives->Enable( aEnable );
224  m_buttonDel->Enable( aEnable );
225  m_buttonEditShape->Enable( aEnable );
226  m_buttonAddShape->Enable( aEnable );
227  m_buttonDup->Enable( aEnable );
228  m_buttonGeometry->Enable( aEnable );
229 }
230 
231 
233 {
234  // Initialize the canvases (legacy or gal) to display the pad
235 
236  // Show the X and Y axis. It is usefull because pad shape can have an offset
237  // or be a complex shape.
238  KIGFX::COLOR4D axis_color = LIGHTBLUE;
239 
241  Millimeter2iu( 0.2 ),
243  m_axisOrigin->SetDrawAtZero( true );
244 
245  if( m_parent->IsGalCanvasActive() )
246  {
250 
251  bool mousewheelPan = m_parent->GetCanvas()->GetEnableMousewheelPan();
253 
254  m_panelShowPadGal->Show();
255  m_panelShowPad->Hide();
256 
258 
259  // fix the pad render mode (filled/not filled)
260  auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
261  bool sketchMode = m_cbShowPadOutline->IsChecked();
262  settings->SetSketchMode( LAYER_PADS_TH, sketchMode );
263  settings->SetSketchMode( LAYER_PAD_FR, sketchMode );
264  settings->SetSketchMode( LAYER_PAD_BK, sketchMode );
265  settings->SetSketchModeGraphicItems( sketchMode );
266 
267  // gives a non null grid size (0.001mm) because GAL layer does not like a 0 size grid:
268  double gridsize = 0.001 * IU_PER_MM;
269  view->GetGAL()->SetGridSize( VECTOR2D( gridsize, gridsize ) );
270  // And do not show the grid:
271  view->GetGAL()->SetGridVisibility( false );
272  view->Add( m_dummyPad );
273  view->Add( m_axisOrigin );
274 
276  Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
277  }
278  else
279  {
280  m_panelShowPad->Show();
281  m_panelShowPadGal->Hide();
282  }
283 }
284 
285 
286 void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
287 {
288  wxPaintDC dc( m_panelShowPad );
289  PAD_DRAWINFO drawInfo;
290 
292 
293  if( m_dummyPad->GetLayerSet()[F_Cu] )
295 
296  if( m_dummyPad->GetLayerSet()[B_Cu] )
298 
299  // What could happen: the pad color is *actually* black, or no copper was selected
300  if( color == BLACK )
301  color = LIGHTGRAY;
302 
303  drawInfo.m_Color = color;
304  drawInfo.m_HoleColor = DARKGRAY;
305  drawInfo.m_Offset = m_dummyPad->GetPosition();
306  drawInfo.m_Display_padnum = true;
307  drawInfo.m_Display_netname = true;
308  drawInfo.m_ShowPadFilled = !m_sketchPreview;
309 
311  drawInfo.m_ShowNotPlatedHole = true;
312 
313  // Shows the local pad clearance
315 
316  wxSize dc_size = dc.GetSize();
317  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
318 
319  // Calculate a suitable scale to fit the available draw area
320  int dim = m_dummyPad->GetBoundingRadius() *2;
321 
322  // Invalid x size. User could enter zero, or have deleted all text prior to
323  // entering a new value; this is also treated as zero. If dim is left at
324  // zero, the drawing scale is zero and we get a crash.
325  if( dim == 0 )
326  {
327  // If drill size has been set, use that. Otherwise default to 1mm.
328  dim = m_dummyPad->GetDrillSize().x;
329 
330  if( dim == 0 )
331  dim = Millimeter2iu( 1.0 );
332  }
333 
334  if( m_dummyPad->GetLocalClearance() > 0 )
335  dim += m_dummyPad->GetLocalClearance() * 2;
336 
337  double scale = (double) dc_size.x / dim;
338 
339  // If the pad is a circle, use the x size here instead.
340  int ysize;
341 
343  ysize = m_dummyPad->GetSize().x;
344  else
345  ysize = m_dummyPad->GetSize().y;
346 
347  dim = ysize + std::abs( m_dummyPad->GetDelta().x );
348 
349  // Invalid y size. See note about x size above.
350  if( dim == 0 )
351  {
352  dim = m_dummyPad->GetDrillSize().y;
353 
354  if( dim == 0 )
355  dim = Millimeter2iu( 0.1 );
356  }
357 
358  if( m_dummyPad->GetLocalClearance() > 0 )
359  dim += m_dummyPad->GetLocalClearance() * 2;
360 
361  double altscale = (double) dc_size.y / dim;
362  scale = std::min( scale, altscale );
363 
364  // Give a margin
365  scale *= 0.7;
366  dc.SetUserScale( scale, scale );
367 
368  GRResetPenAndBrush( &dc );
369  m_dummyPad->DrawShape( NULL, &dc, drawInfo );
370 
371  // draw selected primitives:
372  long select = m_listCtrlPrimitives->GetFirstSelected();
373 
374  while( select >= 0 )
375  {
376  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
377 
378  // The best way to calculate parameters to draw a primitive is to
379  // use a dummy DRAWSEGMENT and use its methods
380  // Note: in legacy canvas, the pad has the 0,0 position
381  DRAWSEGMENT dummySegment;
382  primitive.ExportTo( &dummySegment );
383  dummySegment.Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
384 
385  switch( primitive.m_Shape )
386  {
387  case S_SEGMENT: // usual segment : line with rounded ends
388  if( !m_sketchPreview )
389  GRFilledSegment( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
390  primitive.m_Thickness, m_selectedColor );
391  else
392  GRCSegm( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
393  primitive.m_Thickness, m_selectedColor );
394  break;
395 
396  case S_ARC: // Arc with rounded ends
397  if( !m_sketchPreview )
398  GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
399  dummySegment.GetCenter(), primitive.m_Thickness, m_selectedColor );
400  else
401  {
402  GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
403  dummySegment.GetCenter(), 0, m_selectedColor );
404 /* GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
405  dummySegment.GetCenter() - primitive.m_Thickness, 0, m_selectedColor );*/
406  }
407  break;
408 
409  case S_CIRCLE: // ring or circle
410  if( primitive.m_Thickness )
411  {
412  if( !m_sketchPreview )
413  GRCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius,
414  primitive.m_Thickness, m_selectedColor );
415  else
416  {
417  GRCircle( nullptr, &dc, dummySegment.GetCenter(),
418  primitive.m_Radius + primitive.m_Thickness/2, 0, m_selectedColor );
419  GRCircle( nullptr, &dc, dummySegment.GetCenter(),
420  primitive.m_Radius - primitive.m_Thickness/2, 0, m_selectedColor );
421  }
422  }
423  else
424  {
425  if( !m_sketchPreview )
426  GRFilledCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius,
427  m_selectedColor );
428  else
429  GRCircle( nullptr, &dc, dummySegment.GetCenter(), primitive.m_Radius, 0,
430  m_selectedColor );
431  }
432  break;
433 
434  case S_POLYGON: // polygon
435  {
436  std::vector<wxPoint> poly = dummySegment.BuildPolyPointsList();
437  GRClosedPoly( nullptr, &dc, poly.size(), &poly[0], !m_sketchPreview,
439  }
440  break;
441 
442  default:
443  break;
444  }
445 
446  select = m_listCtrlPrimitives->GetNextSelected( select );
447  }
448 
449  // Draw X and Y axis. This is particularly useful to show the
450  // reference position of pads with offset and no hole, or custom pad shapes
451  const int t = 0; // line thickness
452  GRLine( nullptr, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0, t, LIGHTBLUE );
453  GRLine( nullptr, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ), t, LIGHTBLUE );
454 
455  event.Skip();
456 }
457 
458 
460 {
461  // Note: use m_tcCornerSizeRatio->ChangeValue() to avoid generating a wxEVT_TEXT event
462 
465  {
466  auto ratio = wxString::Format( "%.1f", m_dummyPad->GetRoundRectRadiusRatio() * 100 );
467  m_tcCornerSizeRatio->ChangeValue( ratio );
469 
470  ratio = wxString::Format( "%.1f", m_dummyPad->GetChamferRectRatio() * 100 );
471  m_tcChamferRatio->ChangeValue( ratio );
472  }
473  else if( m_dummyPad->GetShape() == PAD_SHAPE_RECT )
474  {
475  m_tcCornerSizeRatio->ChangeValue( "0" );
477  }
478  else
479  {
480  m_tcCornerSizeRatio->ChangeValue( wxEmptyString );
481  m_cornerRadius.SetValue( wxEmptyString );
482  }
483 }
484 
485 
486 void DIALOG_PAD_PROPERTIES::onCornerRadiusChange( wxCommandEvent& event )
487 {
490  return;
491 
492  double rrRadius = m_cornerRadius.GetValue();
493 
494  if( rrRadius < 0.0 )
495  {
496  rrRadius = 0.0;
497  m_tcCornerRadius->ChangeValue( wxString::Format( "%.1f", rrRadius ) );
498  }
499 
502 
503  auto ratio = wxString::Format( "%.1f", m_dummyPad->GetRoundRectRadiusRatio() * 100 );
504  m_tcCornerSizeRatio->ChangeValue( ratio );
505  redraw();
506 }
507 
508 
510 {
513  return;
514 
515  wxString value = m_tcCornerSizeRatio->GetValue();
516  double ratioPercent;
517 
518  bool asChanged = false;
519 
520  if( value.ToDouble( &ratioPercent ) )
521  {
522  // Clamp ratioPercent to acceptable value (0.0 to 50.0)
523  if( ratioPercent < 0.0 )
524  {
525  ratioPercent = 0.0;
526  value.Printf( "%.1f", ratioPercent );
527  m_tcCornerSizeRatio->ChangeValue( value );
528  }
529 
530  if( ratioPercent > 50.0 )
531  {
532  ratioPercent = 0.5;
533  value.Printf( "%.1f", ratioPercent*100.0 );
534  m_tcCornerSizeRatio->ChangeValue( value );
535  }
536 
537  asChanged = true;
538  }
539 
540  value = m_tcChamferRatio->GetValue();
541 
542  if( value.ToDouble( &ratioPercent ) )
543  {
544  // Clamp ratioPercent to acceptable value (0.0 to 50.0)
545  if( ratioPercent < 0.0 )
546  {
547  ratioPercent = 0.0;
548  value.Printf( "%.1f", ratioPercent );
549  m_tcChamferRatio->ChangeValue( value );
550  }
551 
552  if( ratioPercent > 50.0 )
553  {
554  ratioPercent = 0.5;
555  value.Printf( "%.1f", ratioPercent*100.0 );
556  m_tcChamferRatio->ChangeValue( value );
557  }
558 
559  asChanged = true;
560  }
561 
562  if( asChanged )
563  {
566  redraw();
567  }
568 }
569 
570 
572 {
573  wxString msg;
574  double angle;
575 
576  // Disable pad net name wxTextCtrl if the caller is the footprint editor
577  // because nets are living only in the board managed by the board editor
579 
580 
581  // Setup layers names from board
582  // Should be made first, before calling m_rbCopperLayersSel->SetSelection()
583  m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( F_Cu ) );
584  m_rbCopperLayersSel->SetString( 1, m_board->GetLayerName( B_Cu ) );
585 
586  m_PadLayerAdhCmp->SetLabel( m_board->GetLayerName( F_Adhes ) );
587  m_PadLayerAdhCu->SetLabel( m_board->GetLayerName( B_Adhes ) );
589  m_PadLayerPateCu->SetLabel( m_board->GetLayerName( B_Paste ) );
591  m_PadLayerSilkCu->SetLabel( m_board->GetLayerName( B_SilkS ) );
592  m_PadLayerMaskCmp->SetLabel( m_board->GetLayerName( F_Mask ) );
593  m_PadLayerMaskCu->SetLabel( m_board->GetLayerName( B_Mask ) );
594  m_PadLayerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
595  m_PadLayerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
597 
598  m_isFlipped = false;
599 
600  if( m_currentPad )
601  {
603 
604  // Diplay parent footprint info
605  MODULE* footprint = m_currentPad->GetParent();
606  wxString msg1, msg2;
607 
608  if( footprint )
609  {
610  wxString side = footprint->IsFlipped() ? _( "back side (mirrored)" ) : _( "front side" );
611  msg1.Printf( _("Footprint %s (%s),"), footprint->GetReference(), footprint->GetValue() );
612  msg2.Printf( _("%s, rotated %.1f deg"), side, footprint->GetOrientation() / 10.0 );
613  }
614 
615  m_parentInfoLine1->SetLabel( msg1 );
616  m_parentInfoLine2->SetLabel( msg2 );
617  }
618 
619  if( m_isFlipped )
620  {
621  wxPoint pt = m_dummyPad->GetOffset();
622  pt.y = -pt.y;
623  m_dummyPad->SetOffset( pt );
624 
625  wxSize sz = m_dummyPad->GetDelta();
626  sz.y = -sz.y;
627  m_dummyPad->SetDelta( sz );
628 
629  // flip pad's layers
631 
632  // flip custom pad shapes
634  }
635 
637 
639 
640  m_PadNumCtrl->SetValue( m_dummyPad->GetName() );
642 
643  // Display current pad parameters units:
646 
649 
652 
655 
656  if( m_dummyPad->GetDelta().x )
657  {
659  m_trapAxisCtrl->SetSelection( 0 );
660  }
661  else
662  {
664  m_trapAxisCtrl->SetSelection( 1 );
665  }
666 
668 
674 
675  // Prefer "-0" to "0" for normally negative values
677  m_pasteClearanceCtrl->SetValue( wxT( "-" ) + m_pasteClearanceCtrl->GetValue() );
678 
679  msg.Printf( wxT( "%f" ), m_dummyPad->GetLocalSolderPasteMarginRatio() * 100.0 );
680 
681  if( m_dummyPad->GetLocalSolderPasteMarginRatio() == 0.0 && msg[0] == '0' )
682  // Sometimes Printf adds a sign if the value is small
683  m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
684  else
686 
687  switch( m_dummyPad->GetZoneConnection() )
688  {
689  default:
691  m_ZoneConnectionChoice->SetSelection( 0 );
692  m_ZoneConnectionCustom->SetSelection( 0 );
693  break;
694 
695  case PAD_ZONE_CONN_FULL:
696  m_ZoneConnectionChoice->SetSelection( 1 );
697  m_ZoneConnectionCustom->SetSelection( 1 );
698  break;
699 
701  m_ZoneConnectionChoice->SetSelection( 2 );
702  m_ZoneConnectionCustom->SetSelection( 0 );
703  break;
704 
705  case PAD_ZONE_CONN_NONE:
706  m_ZoneConnectionChoice->SetSelection( 3 );
707  m_ZoneConnectionCustom->SetSelection( 0 );
708  break;
709  }
710 
712  m_ZoneCustomPadShape->SetSelection( 1 );
713  else
714  m_ZoneCustomPadShape->SetSelection( 0 );
715 
716  if( m_currentPad )
717  {
719  MODULE* footprint = m_currentPad->GetParent();
720 
721  if( footprint )
722  angle -= footprint->GetOrientation();
723 
724  if( m_isFlipped )
725  angle = -angle;
726 
728  }
729 
731 
732  NORMALIZE_ANGLE_180( angle ); // ? normalizing is in D_PAD::SetOrientation()
733 
734  // Set layers used by this pad: :
736 
737  // Pad Orient
738  // Note: use ChangeValue() instead of SetValue() so that we don't generate events
739  m_orientation->ChangeValue( StringFromValue( DEGREES, angle ) );
740 
741  switch( m_dummyPad->GetShape() )
742  {
743  default:
744  case PAD_SHAPE_CIRCLE: m_PadShape->SetSelection( CHOICE_SHAPE_CIRCLE ); break;
745  case PAD_SHAPE_OVAL: m_PadShape->SetSelection( CHOICE_SHAPE_OVAL ); break;
746  case PAD_SHAPE_RECT: m_PadShape->SetSelection( CHOICE_SHAPE_RECT ); break;
747  case PAD_SHAPE_TRAPEZOID: m_PadShape->SetSelection( CHOICE_SHAPE_TRAPEZOID ); break;
748  case PAD_SHAPE_ROUNDRECT: m_PadShape->SetSelection( CHOICE_SHAPE_ROUNDRECT ); break;
750 
751  case PAD_SHAPE_CUSTOM:
754  else
756  break;
757  }
758 
759 
764 
766 
767  // Type of pad selection
769  {
770  m_PadType->SetSelection( 4 );
771  }
772  else
773  {
774  switch( m_dummyPad->GetAttribute() )
775  {
776  case PAD_ATTRIB_STANDARD: m_PadType->SetSelection( 0 ); break;
777  case PAD_ATTRIB_SMD: m_PadType->SetSelection( 1 ); break;
778  case PAD_ATTRIB_CONN: m_PadType->SetSelection( 2 ); break;
779  case PAD_ATTRIB_HOLE_NOT_PLATED: m_PadType->SetSelection( 3 ); break;
780  }
781  }
782 
783  // Disable Pad name,and pad to die length for NPTH pads (mechanical pads)
785 
786  m_PadNumText->Enable( enable );
787  m_PadNumCtrl->Enable( enable );
788  m_PadNameText->Enable( enable && m_canEditNetName && m_currentPad );
789  m_PadNetSelector->Enable( enable && m_canEditNetName && m_currentPad );
790  m_padToDie.Enable( enable );
791 
793  m_holeShapeCtrl->SetSelection( 0 );
794  else
795  m_holeShapeCtrl->SetSelection( 1 );
796 
797  // Update some dialog widgets state (Enable/disable options):
798  wxCommandEvent cmd_event;
800  OnDrillShapeSelected( cmd_event );
801  OnPadShapeSelection( cmd_event );
803 
804  // Update basic shapes list
806 }
807 
808 // A small helper function, to display coordinates:
809 static wxString formatCoord( EDA_UNITS_T aUnits, wxPoint aCoord )
810 {
811  return wxString::Format( "(X:%s Y:%s)",
812  MessageTextFromValue( aUnits, aCoord.x, true ),
813  MessageTextFromValue( aUnits, aCoord.y, true ) );
814 }
815 
817 {
818  m_listCtrlPrimitives->ClearAll();
819 
820  wxListItem itemCol;
821  itemCol.SetImage(-1);
822 
823  for( int ii = 0; ii < 5; ++ii )
824  m_listCtrlPrimitives->InsertColumn(ii, itemCol);
825 
826  wxString bs_info[5];
827 
828  for( unsigned ii = 0; ii < m_primitives.size(); ++ii )
829  {
830  const PAD_CS_PRIMITIVE& primitive = m_primitives[ii];
831 
832  for( unsigned jj = 0; jj < 5; ++jj )
833  bs_info[jj].Empty();
834 
835  bs_info[4] = wxString::Format( _( "width %s" ),
836  MessageTextFromValue( m_units, primitive.m_Thickness, true ) );
837 
838  switch( primitive.m_Shape )
839  {
840  case S_SEGMENT: // usual segment : line with rounded ends
841  bs_info[0] = _( "Segment" );
842  bs_info[1] = _( "from " ) + formatCoord( m_units, primitive.m_Start );
843  bs_info[2] = _( "to " ) + formatCoord( m_units, primitive.m_End );
844  break;
845 
846  case S_CURVE: // Bezier segment
847  bs_info[0] = _( "Bezier" );
848  bs_info[1] = _( "from " ) + formatCoord( m_units, primitive.m_Start );
849  bs_info[2] = _( "to " ) + formatCoord( m_units, primitive.m_End );
850  break;
851 
852  case S_ARC: // Arc with rounded ends
853  bs_info[0] = _( "Arc" );
854  bs_info[1] = _( "center " ) + formatCoord( m_units, primitive.m_Start );// Center
855  bs_info[2] = _( "start " ) + formatCoord( m_units, primitive.m_End ); // Start point
856  bs_info[3] = wxString::Format( _( "angle %s" ), FormatAngle( primitive.m_ArcAngle ) );
857  break;
858 
859  case S_CIRCLE: // ring or circle
860  if( primitive.m_Thickness )
861  bs_info[0] = _( "ring" );
862  else
863  bs_info[0] = _( "circle" );
864 
865  bs_info[1] = formatCoord( m_units, primitive.m_Start );
866  bs_info[2] = wxString::Format( _( "radius %s" ),
867  MessageTextFromValue( m_units, primitive.m_Radius, true ) );
868  break;
869 
870  case S_POLYGON: // polygon
871  bs_info[0] = "Polygon";
872  bs_info[1] = wxString::Format( _( "corners count %d" ), (int) primitive.m_Poly.size() );
873  break;
874 
875  default:
876  bs_info[0] = "Unknown primitive";
877  break;
878  }
879 
880  long tmp = m_listCtrlPrimitives->InsertItem(ii, bs_info[0]);
881  m_listCtrlPrimitives->SetItemData(tmp, ii);
882 
883  for( int jj = 0, col = 0; jj < 5; ++jj )
884  {
885  m_listCtrlPrimitives->SetItem(tmp, col++, bs_info[jj]);
886  }
887  }
888 
889  // Now columns are filled, ensure correct width of columns
890  for( unsigned ii = 0; ii < 5; ++ii )
891  m_listCtrlPrimitives->SetColumnWidth( ii, wxLIST_AUTOSIZE );
892 }
893 
894 void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
895 {
896  redraw();
897  event.Skip();
898 }
899 
900 
901 void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
902 {
903  m_sketchPreview = m_cbShowPadOutline->GetValue();
904 
905  if( m_parent->IsGalCanvasActive() )
906  {
908 
909  // fix the pad render mode (filled/not filled)
910  KIGFX::PCB_RENDER_SETTINGS* settings =
911  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
912 
917  }
918 
919  redraw();
920 }
921 
922 
923 
924 void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
925 {
926  bool is_custom = false;
927 
928  switch( m_PadShape->GetSelection() )
929  {
930  case CHOICE_SHAPE_CIRCLE:
931  m_trapDelta.Enable( false );
932  m_trapAxisLabel->Enable( false );
933  m_trapAxisCtrl->Enable( false );
934  m_sizeY.Enable( false );
935  m_offsetX.Enable( false );
936  m_offsetY.Enable( false );
937  break;
938 
939  case CHOICE_SHAPE_OVAL:
940  m_trapDelta.Enable( false );
941  m_trapAxisLabel->Enable( false );
942  m_trapAxisCtrl->Enable( false );
943  m_sizeY.Enable( true );
944  m_offsetX.Enable( true );
945  m_offsetY.Enable( true );
946  break;
947 
948  case CHOICE_SHAPE_RECT:
949  m_trapDelta.Enable( false );
950  m_trapAxisLabel->Enable( false );
951  m_trapAxisCtrl->Enable( false );
952  m_sizeY.Enable( true );
953  m_offsetX.Enable( true );
954  m_offsetY.Enable( true );
955  break;
956 
958  m_trapDelta.Enable( true );
959  m_trapAxisLabel->Enable( true );
960  m_trapAxisCtrl->Enable( true );
961  m_sizeY.Enable( true );
962  m_offsetX.Enable( true );
963  m_offsetY.Enable( true );
964  break;
965 
968  m_trapDelta.Enable( false );
969  m_trapAxisLabel->Enable( false );
970  m_trapAxisCtrl->Enable( false );
971  m_sizeY.Enable( true );
972  m_offsetX.Enable( true );
973  m_offsetY.Enable( true );
974  // Ensure m_tcCornerSizeRatio contains the right value:
975  m_tcCornerSizeRatio->ChangeValue( wxString::Format( "%.1f",
977  break;
978 
979  case CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR: // PAD_SHAPE_CUSTOM, circular anchor
980  case CHOICE_SHAPE_CUSTOM_RECT_ANCHOR: // PAD_SHAPE_CUSTOM, rect anchor
981  is_custom = true;
982  m_trapDelta.Enable( false );
983  m_trapAxisLabel->Enable( false );
984  m_trapAxisCtrl->Enable( false );
986  m_offsetX.Enable( false );
987  m_offsetY.Enable( false );
988  break;
989  }
990 
991  enablePrimitivePage( is_custom );
992 
993  // A few widgets are enabled only for rounded rect and chamfered pads:
994  bool chamfered_rect_enable = m_PadShape->GetSelection() == CHOICE_SHAPE_CHAMFERED_RECT;
995  bool round_rect_enable = m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT ||
996  chamfered_rect_enable;
997  m_staticTextCornerSizeRatio->Enable( round_rect_enable );
998  m_tcCornerSizeRatio->Enable( round_rect_enable );
999  m_staticTextCornerSizeRatioUnit->Enable( round_rect_enable );
1000  m_cornerRadius.Enable( round_rect_enable );
1001 
1002  m_cbTopLeft->Enable( chamfered_rect_enable );
1003  m_cbTopRight->Enable( chamfered_rect_enable );
1004  m_cbBottomLeft->Enable( chamfered_rect_enable );
1005  m_cbBottomRight->Enable( chamfered_rect_enable );
1006  m_tcChamferRatio->Enable( chamfered_rect_enable );
1007 
1008  // PAD_SHAPE_CUSTOM type has constraints for zone connection and thermal shape:
1009  // only not connected or solid connection is allowed to avoid destroying the shape.
1010  // Enable/disable options only available for custom shaped pads
1011  m_ZoneConnectionChoice->Enable( !is_custom );
1012  m_ZoneConnectionCustom->Enable( is_custom );
1013  m_spokeWidth.Enable( !is_custom );
1014  m_thermalGap.Enable( !is_custom );
1015 
1016  m_sbSizerZonesSettings->Show( !is_custom );
1017  m_sbSizerCustomShapedZonesSettings->Show( is_custom );
1018 
1020 
1022  redraw();
1023 }
1024 
1025 
1026 void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
1027 {
1029  redraw();
1030 }
1031 
1032 
1033 void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
1034 {
1036  redraw();
1037 }
1038 
1039 
1040 void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
1041 {
1042  int ii = m_PadType->GetSelection();
1043 
1044  if( (unsigned)ii >= arrayDim( code_type ) ) // catches < 0 also
1045  ii = 0;
1046 
1047  bool hasHole, hasConnection;
1048 
1049  switch( ii )
1050  {
1051  default:
1052  case 0: /* PTH */ hasHole = true; hasConnection = true; break;
1053  case 1: /* SMD */ hasHole = false; hasConnection = true; break;
1054  case 2: /* CONN */ hasHole = false; hasConnection = true; break;
1055  case 3: /* NPTH */ hasHole = true; hasConnection = false; break;
1056  case 4: /* Aperture */ hasHole = false; hasConnection = false; break;
1057  }
1058 
1059  LSET layer_mask = std_pad_layers[ii];
1060  setPadLayersList( layer_mask );
1061 
1062  if( !hasHole )
1063  {
1064  m_holeX.SetValue( 0 );
1065  m_holeY.SetValue( 0 );
1066  }
1067  else if ( m_holeX.GetValue() == 0 && m_currentPad )
1068  {
1071  }
1072 
1073  if( !hasConnection )
1074  {
1075  m_PadNumCtrl->SetValue( wxEmptyString );
1077  m_padToDie.SetValue( 0 );
1078  }
1079  else if( m_PadNumCtrl->GetValue().IsEmpty() && m_currentPad )
1080  {
1081  m_PadNumCtrl->SetValue( m_currentPad->GetName() );
1083  }
1084 
1086  redraw();
1087 }
1088 
1089 
1090 void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
1091 {
1092  int ii = m_PadType->GetSelection();
1093 
1094  if( (unsigned)ii >= arrayDim( code_type ) ) // catches < 0 also
1095  ii = 0;
1096 
1097  bool hasHole, hasConnection;
1098 
1099  switch( ii )
1100  {
1101  default:
1102  case 0: /* PTH */ hasHole = true; hasConnection = true; break;
1103  case 1: /* SMD */ hasHole = false; hasConnection = true; break;
1104  case 2: /* CONN */ hasHole = false; hasConnection = true; break;
1105  case 3: /* NPTH */ hasHole = true; hasConnection = false; break;
1106  case 4: /* Aperture */ hasHole = false; hasConnection = false; break;
1107  }
1108 
1109  // Enable/disable hole controls
1110  m_holeShapeLabel->Enable( hasHole );
1111  m_holeShapeCtrl->Enable( hasHole );
1112  m_holeX.Enable( hasHole );
1113  m_holeY.Enable( hasHole && m_holeShapeCtrl->GetSelection() == 1 );
1114 
1115  // Enable/disable Pad number, net and pad length-to-die
1116  m_PadNumText->Enable( hasConnection );
1117  m_PadNumCtrl->Enable( hasConnection );
1118  m_PadNameText->Enable( hasConnection );
1119  m_PadNetSelector->Enable( hasConnection && m_canEditNetName && m_currentPad );
1120  m_padToDie.Enable( hasConnection );
1121 
1122  // Enable/disable Copper Layers control
1123  m_rbCopperLayersSel->Enable( ii != 4 );
1124 }
1125 
1126 
1128 {
1129  LSET cu_set = layer_mask & LSET::AllCuMask();
1130 
1131  if( cu_set == LSET( F_Cu ) )
1132  m_rbCopperLayersSel->SetSelection( 0 );
1133  else if( cu_set == LSET( B_Cu ) )
1134  m_rbCopperLayersSel->SetSelection( 1 );
1135  else if( cu_set.any() )
1136  m_rbCopperLayersSel->SetSelection( 2 );
1137  else
1138  m_rbCopperLayersSel->SetSelection( 3 );
1139 
1140  m_PadLayerAdhCmp->SetValue( layer_mask[F_Adhes] );
1141  m_PadLayerAdhCu->SetValue( layer_mask[B_Adhes] );
1142 
1143  m_PadLayerPateCmp->SetValue( layer_mask[F_Paste] );
1144  m_PadLayerPateCu->SetValue( layer_mask[B_Paste] );
1145 
1146  m_PadLayerSilkCmp->SetValue( layer_mask[F_SilkS] );
1147  m_PadLayerSilkCu->SetValue( layer_mask[B_SilkS] );
1148 
1149  m_PadLayerMaskCmp->SetValue( layer_mask[F_Mask] );
1150  m_PadLayerMaskCu->SetValue( layer_mask[B_Mask] );
1151 
1152  m_PadLayerECO1->SetValue( layer_mask[Eco1_User] );
1153  m_PadLayerECO2->SetValue( layer_mask[Eco2_User] );
1154 
1155  m_PadLayerDraft->SetValue( layer_mask[Dwgs_User] );
1156 }
1157 
1158 
1159 // Called when select/deselect a layer.
1160 void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
1161 {
1163  redraw();
1164 }
1165 
1166 
1167 // test if all values are acceptable for the pad
1169 {
1170  bool error = transferDataToPad( m_dummyPad );
1171  bool skip_tstoffset = false; // the offset prm is not always tested
1172 
1173  wxArrayString error_msgs;
1174  wxString msg;
1175 
1176  // Test for incorrect values
1177  if( (m_dummyPad->GetSize().x <= 0) ||
1178  ((m_dummyPad->GetSize().y <= 0) && (m_dummyPad->GetShape() != PAD_SHAPE_CIRCLE)) )
1179  {
1180  error_msgs.Add( _( "Pad size must be greater than zero" ) );
1181  }
1182 
1183  if( (m_dummyPad->GetSize().x < m_dummyPad->GetDrillSize().x) ||
1184  (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
1185  {
1186  error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
1187  skip_tstoffset = true; // offset prm will be not tested because if the drill value
1188  // is incorrect the offset prm is always seen as incorrect, even if it is 0
1189  }
1190 
1191  if( m_dummyPad->GetLocalClearance() < 0 )
1192  {
1193  error_msgs.Add( _( "Pad local clearance must be zero or greater than zero" ) );
1194  }
1195 
1196  // Some pads need a negative solder mask clearance (mainly for BGA with small pads)
1197  // However the negative solder mask clearance must not create negative mask size
1198  // Therefore test for minimal acceptable negative value
1199  // Hovewer, a negative value can give strange result with custom shapes, so it is not
1200  // allowed for custom pad shape
1202  {
1204  error_msgs.Add( _( "Pad local solder mask clearance must be zero or greater than zero" ) );
1205  else
1206  {
1207  int min_smClearance = -std::min( m_dummyPad->GetSize().x, m_dummyPad->GetSize().y )/2;
1208 
1209  if( m_dummyPad->GetLocalSolderMaskMargin() <= min_smClearance )
1210  {
1211  error_msgs.Add( wxString::Format(
1212  _( "Pad local solder mask clearance must be greater than %s" ),
1213  StringFromValue( GetUserUnits(), min_smClearance, true, true ) ) );
1214  }
1215  }
1216  }
1217 
1218  // Some pads need a positive solder paste clearance (mainly for BGA with small pads)
1219  // Hovewer, a positive value can create issues if the resulting shape is too big.
1220  // (like a solder paste creating a solder paste area on a neighbour pad or on the solder mask)
1221  // So we could ask for user to confirm the choice
1222  // Currently there are no test
1223 
1224  LSET padlayers_mask = m_dummyPad->GetLayerSet();
1225 
1226  if( padlayers_mask == 0 )
1227  error_msgs.Add( _( "Error: pad has no layer" ) );
1228 
1229  if( !padlayers_mask[F_Cu] && !padlayers_mask[B_Cu] )
1230  {
1231  if( m_dummyPad->GetDrillSize().x || m_dummyPad->GetDrillSize().y )
1232  {
1233  // Note: he message is shown in an HTML window
1234  msg = _( "Error: the pad is not on a copper layer and has a hole" );
1235 
1237  {
1238  msg += wxT( "<br><br><i>" );
1239  msg += _( "For NPTH pad, set pad size value to pad drill value,"
1240  " if you do not want this pad plotted in gerber files" );
1241  }
1242 
1243  error_msgs.Add( msg );
1244  }
1245  }
1246 
1247  if( !skip_tstoffset )
1248  {
1249  wxPoint max_size;
1250  max_size.x = std::abs( m_dummyPad->GetOffset().x );
1251  max_size.y = std::abs( m_dummyPad->GetOffset().y );
1252  max_size.x += m_dummyPad->GetDrillSize().x / 2;
1253  max_size.y += m_dummyPad->GetDrillSize().y / 2;
1254 
1255  if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
1256  ( m_dummyPad->GetSize().y / 2 < max_size.y ) )
1257  {
1258  error_msgs.Add( _( "Incorrect value for pad offset" ) );
1259  }
1260  }
1261 
1262  if( error )
1263  error_msgs.Add( _( "Too large value for pad delta size" ) );
1264 
1265  switch( m_dummyPad->GetAttribute() )
1266  {
1267  case PAD_ATTRIB_HOLE_NOT_PLATED: // Not plated, but through hole, a hole is expected
1268  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
1269  if( m_dummyPad->GetDrillSize().x <= 0 ||
1271  error_msgs.Add( _( "Error: Through hole pad: drill diameter set to 0" ) );
1272  break;
1273 
1274  case PAD_ATTRIB_CONN: // Connector pads are smd pads, just they do not have solder paste.
1275  if( padlayers_mask[B_Paste] || padlayers_mask[F_Paste] )
1276  error_msgs.Add( _( "Error: Connector pads are not on the solder paste layer\n"
1277  "Use SMD pads instead" ) );
1278  // Fall trough
1279  case PAD_ATTRIB_SMD: // SMD and Connector pads (One external copper layer only)
1280  {
1281  LSET innerlayers_mask = padlayers_mask & LSET::InternalCuMask();
1282 
1283  if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) ||
1284  innerlayers_mask.count() != 0 )
1285  error_msgs.Add( _( "Error: only one external copper layer allowed for SMD or Connector pads" ) );
1286  }
1287  break;
1288  }
1289 
1290 
1293  {
1294  wxString value = m_tcCornerSizeRatio->GetValue();
1295  double rrRadiusRatioPercent;
1296 
1297  if( !value.ToDouble( &rrRadiusRatioPercent ) )
1298  error_msgs.Add( _( "Incorrect corner size value" ) );
1299  else
1300  {
1301  if( rrRadiusRatioPercent < 0.0 )
1302  error_msgs.Add( _( "Incorrect (negative) corner size value" ) );
1303  else if( rrRadiusRatioPercent > 50.0 )
1304  error_msgs.Add( _( "Corner size value must be smaller than 50%" ) );
1305  }
1306  }
1307 
1309  {
1311  error_msgs.Add( _( "Incorrect pad shape: the shape must be equivalent to only one polygon" ) );
1312  }
1313 
1314 
1315  if( error_msgs.GetCount() )
1316  {
1317  HTML_MESSAGE_BOX dlg( this, _("Pad setup errors list" ) );
1318  dlg.ListSet( error_msgs );
1319  dlg.ShowModal();
1320  }
1321 
1322  return error_msgs.GetCount() == 0;
1323 }
1324 
1325 
1327 {
1328  if( m_parent->IsGalCanvasActive() )
1329  {
1332 
1333  // The layer used to place primitive items selected when editing custom pad shapes
1334  // we use here a layer never used in a pad:
1335  #define SELECTED_ITEMS_LAYER Dwgs_User
1336 
1338  KIGFX::PCB_RENDER_SETTINGS* settings =
1339  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
1341 
1342  view->Update( m_dummyPad );
1343 
1344  // delete previous items if highlight list
1345  while( m_highlight.size() )
1346  {
1347  delete m_highlight.back(); // the dtor also removes item from view
1348  m_highlight.pop_back();
1349  }
1350 
1351  // highlight selected primitives:
1352  long select = m_listCtrlPrimitives->GetFirstSelected();
1353 
1354  while( select >= 0 )
1355  {
1356  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
1357 
1358  DRAWSEGMENT* dummySegment = new DRAWSEGMENT;
1359  dummySegment->SetLayer( SELECTED_ITEMS_LAYER );
1360  primitive.ExportTo( dummySegment );
1361  dummySegment->Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
1362  dummySegment->Move( m_dummyPad->GetPosition() );
1363 
1364  // Update selected primitive (highlight selected)
1365  switch( primitive.m_Shape )
1366  {
1367  case S_SEGMENT:
1368  case S_ARC:
1369  case S_CURVE:
1370  break;
1371 
1372  case S_CIRCLE: // ring or circle
1373  if( primitive.m_Thickness == 0 ) // filled circle
1374  { // the filled circle option does not exist in a DRAWSEGMENT
1375  // but it is easy to create it with a circle having the
1376  // right radius and outline width
1377  wxPoint end = dummySegment->GetCenter();
1378  end.x += primitive.m_Radius / 2;
1379  dummySegment->SetEnd( end );
1380  dummySegment->SetWidth( primitive.m_Radius );
1381  }
1382  break;
1383 
1384  case S_POLYGON:
1385  break;
1386 
1387  default:
1388  delete dummySegment;
1389  dummySegment = nullptr;
1390  break;
1391  }
1392 
1393  if( dummySegment )
1394  {
1395  view->Add( dummySegment );
1396  m_highlight.push_back( dummySegment );
1397  }
1398 
1399  select = m_listCtrlPrimitives->GetNextSelected( select );
1400  }
1401 
1402  BOX2I bbox = m_dummyPad->ViewBBox();
1403 
1404  if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
1405  {
1406  // gives a size to the full drawable area
1407  BOX2I drawbox;
1408  drawbox.Move( m_dummyPad->GetPosition() );
1409  drawbox.Inflate( bbox.GetSize().x * 2, bbox.GetSize().y * 2 );
1410 
1411  view->SetBoundary( drawbox );
1412 
1413  // Autozoom
1414  view->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) );
1415 
1416  // Add a margin
1417  view->SetScale( m_panelShowPadGal->GetView()->GetScale() * 0.7 );
1418 
1421  }
1422  }
1423  else
1424  {
1425  m_panelShowPad->Refresh();
1426  }
1427 }
1428 
1429 
1431 {
1432  if( !wxDialog::TransferDataToWindow() )
1433  return false;
1434 
1435  if( !m_panelGeneral->TransferDataToWindow() )
1436  return false;
1437 
1438  if( !m_localSettingsPanel->TransferDataToWindow() )
1439  return false;
1440 
1441  return true;
1442 }
1443 
1444 
1446 {
1447  BOARD_COMMIT commit( m_parent );
1448 
1449  if( !wxDialog::TransferDataFromWindow() )
1450  return false;
1451 
1452  if( !m_panelGeneral->TransferDataFromWindow() )
1453  return false;
1454 
1455  if( !m_localSettingsPanel->TransferDataFromWindow() )
1456  return false;
1457 
1458  if( !padValuesOK() )
1459  return false;
1460 
1461  bool rastnestIsChanged = false;
1462  int isign = m_isFlipped ? -1 : 1;
1463 
1465  // m_padMaster is a pattern: ensure there is no net for this pad:
1467 
1468  if( !m_currentPad ) // Set current Pad parameters
1469  return true;
1470 
1471  commit.Modify( m_currentPad );
1472 
1473  // redraw the area where the pad was, without pad (delete pad on screen)
1477 
1478  // Update values
1481 
1483  {
1485  rastnestIsChanged = true;
1486  }
1487 
1488  wxSize size;
1489  MODULE* footprint = m_currentPad->GetParent();
1490 
1491  if( footprint )
1492  {
1493  footprint->SetLastEditTime();
1494 
1495  // compute the pos 0 value, i.e. pad position for footprint with orientation = 0
1496  // i.e. relative to footprint origin (footprint position)
1497  wxPoint pt = m_currentPad->GetPosition() - footprint->GetPosition();
1498  RotatePoint( &pt, -footprint->GetOrientation() );
1499  m_currentPad->SetPos0( pt );
1501  + footprint->GetOrientation() );
1502  }
1503 
1505 
1506  size = m_padMaster->GetDelta();
1507  size.y *= isign;
1508  m_currentPad->SetDelta( size );
1509 
1512 
1513  wxPoint offset = m_padMaster->GetOffset();
1514  offset.y *= isign;
1515  m_currentPad->SetOffset( offset );
1516 
1518 
1521 
1522 
1525 
1526  if( m_isFlipped )
1527  {
1530  }
1531 
1533  {
1534  rastnestIsChanged = true;
1536  }
1537 
1538  if( m_isFlipped )
1539  {
1541  }
1542 
1544 
1545  int padNetcode = NETINFO_LIST::UNCONNECTED;
1546 
1547  // For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
1549  padNetcode = m_PadNetSelector->GetSelectedNetcode();
1550 
1551  if( m_currentPad->GetNetCode() != padNetcode )
1552  {
1553  rastnestIsChanged = true;
1554  m_currentPad->SetNetCode( padNetcode );
1555  }
1556 
1566 
1568  {
1571  else
1573  }
1574  else
1576 
1577 
1578  // rounded rect pads with radius ratio = 0 are in fact rect pads.
1579  // So set the right shape (and perhaps issues with a radius = 0)
1582  {
1584  }
1585 
1586  // define the way the clearance area is defined in zones
1588 
1589  if( footprint )
1590  footprint->CalculateBoundingBox();
1591 
1593 
1594  // redraw the area where the pad was
1596 
1597  commit.Push( _( "Modify pad" ) );
1598 
1599  if( rastnestIsChanged ) // The net ratsnest must be recalculated
1600  m_board->m_Status_Pcb = 0;
1601 
1602  return true;
1603 }
1604 
1605 
1607 {
1608  wxString msg;
1609 
1610  if( !Validate() )
1611  return true;
1612  if( !m_panelGeneral->Validate() )
1613  return true;
1614  if( !m_localSettingsPanel->Validate() )
1615  return true;
1616  if( !m_spokeWidth.Validate( 0, INT_MAX ) )
1617  return false;
1618 
1619  m_OrientValidator.TransferFromWindow();
1620 
1621  aPad->SetAttribute( code_type[m_PadType->GetSelection()] );
1622  aPad->SetShape( code_shape[m_PadShape->GetSelection()] );
1625 
1626  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1627  aPad->SetPrimitives( m_primitives );
1628 
1629  // Read pad clearances values:
1634  aPad->SetThermalGap( m_thermalGap.GetValue() );
1635  double dtmp = 0.0;
1636  msg = m_SolderPasteMarginRatioCtrl->GetValue();
1637  msg.ToDouble( &dtmp );
1638 
1639  // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
1640  if( dtmp < -50.0 )
1641  dtmp = -50.0;
1642  // A margin ratio is always <= 0
1643  // 0 means use full pad copper area
1644  if( dtmp > 0.0 )
1645  dtmp = 0.0;
1646 
1647  aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );
1648 
1649  switch( m_ZoneConnectionChoice->GetSelection() )
1650  {
1651  default:
1652  case 0: aPad->SetZoneConnection( PAD_ZONE_CONN_INHERITED ); break;
1653  case 1: aPad->SetZoneConnection( PAD_ZONE_CONN_FULL ); break;
1654  case 2: aPad->SetZoneConnection( PAD_ZONE_CONN_THERMAL ); break;
1655  case 3: aPad->SetZoneConnection( PAD_ZONE_CONN_NONE ); break;
1656  }
1657 
1658  // Custom shape has only 2 options:
1659  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1660  {
1661  if( m_ZoneConnectionCustom->GetSelection() == 0 )
1663  else
1665  }
1666 
1667  aPad->SetPosition( wxPoint( m_posX.GetValue(), m_posY.GetValue() ) );
1668  aPad->SetPos0( wxPoint( m_posX.GetValue(), m_posY.GetValue() ) );
1669 
1670  if( m_holeShapeCtrl->GetSelection() == 0 )
1671  {
1673  aPad->SetDrillSize( wxSize( m_holeX.GetValue(), m_holeX.GetValue() ) );
1674  }
1675  else
1676  {
1678  aPad->SetDrillSize( wxSize( m_holeX.GetValue(), m_holeY.GetValue() ) );
1679  }
1680 
1681  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1682  aPad->SetSize( wxSize( m_sizeX.GetValue(), m_sizeX.GetValue() ) );
1683  else
1684  aPad->SetSize( wxSize( m_sizeX.GetValue(), m_sizeY.GetValue() ) );
1685 
1686  // Read pad length die
1688 
1689  // For a trapezoid, test delta value (be sure delta is not too large for pad size)
1690  // remember DeltaSize.x is the Y size variation
1691  bool error = false;
1692 
1693  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
1694  {
1695  wxSize delta;
1696 
1697  // For a trapezoid, only one of delta.x or delta.y is not 0, depending on
1698  // the direction.
1699  if( m_trapAxisCtrl->GetSelection() == 0 )
1700  delta.x = m_trapDelta.GetValue();
1701  else
1702  delta.y = m_trapDelta.GetValue();
1703 
1704  if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
1705  {
1706  delta.x = -aPad->GetSize().y + 2;
1707  error = true;
1708  }
1709 
1710  if( delta.x > 0 && delta.x >= aPad->GetSize().y )
1711  {
1712  delta.x = aPad->GetSize().y - 2;
1713  error = true;
1714  }
1715 
1716  if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
1717  {
1718  delta.y = -aPad->GetSize().x + 2;
1719  error = true;
1720  }
1721 
1722  if( delta.y > 0 && delta.y >= aPad->GetSize().x )
1723  {
1724  delta.y = aPad->GetSize().x - 2;
1725  error = true;
1726  }
1727 
1728  aPad->SetDelta( delta );
1729  }
1730 
1731  aPad->SetOffset( wxPoint( m_offsetX.GetValue(), m_offsetY.GetValue() ) );
1732  aPad->SetOrientation( m_OrientValue * 10.0 );
1733  aPad->SetName( m_PadNumCtrl->GetValue() );
1735 
1736  int chamfers = 0;
1737 
1738  if( m_cbTopLeft->GetValue() )
1739  chamfers |= RECT_CHAMFER_TOP_LEFT;
1740 
1741  if( m_cbTopRight->GetValue() )
1742  chamfers |= RECT_CHAMFER_TOP_RIGHT;
1743 
1744  if( m_cbBottomLeft->GetValue() )
1745  chamfers |= RECT_CHAMFER_BOTTOM_LEFT;
1746 
1747  if( m_cbBottomRight->GetValue() )
1748  chamfers |= RECT_CHAMFER_BOTTOM_RIGHT;
1749 
1750  aPad->SetChamferPositions( chamfers );
1751 
1752  // Clear some values, according to the pad type and shape
1753  switch( aPad->GetShape() )
1754  {
1755  case PAD_SHAPE_CIRCLE:
1756  aPad->SetOffset( wxPoint( 0, 0 ) );
1757  aPad->SetDelta( wxSize( 0, 0 ) );
1758  break;
1759 
1760  case PAD_SHAPE_RECT:
1761  aPad->SetDelta( wxSize( 0, 0 ) );
1762  break;
1763 
1764  case PAD_SHAPE_OVAL:
1765  aPad->SetDelta( wxSize( 0, 0 ) );
1766  break;
1767 
1768  case PAD_SHAPE_TRAPEZOID:
1769  break;
1770 
1771  case PAD_SHAPE_ROUNDRECT:
1773  aPad->SetDelta( wxSize( 0, 0 ) );
1774  break;
1775 
1776  case PAD_SHAPE_CUSTOM:
1777  aPad->SetOffset( wxPoint( 0, 0 ) );
1778  aPad->SetDelta( wxSize( 0, 0 ) );
1779 
1780  // The pad custom has a "anchor pad" (a basic shape: round or rect pad)
1781  // that is the minimal area of this pad, and is usefull to ensure a hole
1782  // diameter is acceptable, and is used in Gerber files as flashed area
1783  // reference
1784  if( aPad->GetAnchorPadShape() == PAD_SHAPE_CIRCLE )
1785  aPad->SetSize( wxSize( m_sizeX.GetValue(), m_sizeX.GetValue() ) );
1786 
1787  // define the way the clearance area is defined in zones
1788  aPad->SetCustomShapeInZoneOpt( m_ZoneCustomPadShape->GetSelection() == 0 ?
1791  break;
1792 
1793  default:
1794  ;
1795  }
1796 
1797  switch( aPad->GetAttribute() )
1798  {
1799  case PAD_ATTRIB_STANDARD:
1800  break;
1801 
1802  case PAD_ATTRIB_CONN:
1803  case PAD_ATTRIB_SMD:
1804  // SMD and PAD_ATTRIB_CONN has no hole.
1805  // basically, SMD and PAD_ATTRIB_CONN are same type of pads
1806  // PAD_ATTRIB_CONN has just a default non technical layers that differs from SMD
1807  // and are intended to be used in virtual edge board connectors
1808  // However we can accept a non null offset,
1809  // mainly to allow complex pads build from a set of basic pad shapes
1810  aPad->SetDrillSize( wxSize( 0, 0 ) );
1811  break;
1812 
1814  // Mechanical purpose only:
1815  // no offset, no net name, no pad name allowed
1816  aPad->SetOffset( wxPoint( 0, 0 ) );
1817  aPad->SetName( wxEmptyString );
1819  break;
1820 
1821  default:
1822  DisplayError( NULL, wxT( "Error: unknown pad type" ) );
1823  break;
1824  }
1825 
1826  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT || aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
1827  {
1828  wxString value = m_tcCornerSizeRatio->GetValue();
1829  double ratioPercent;
1830 
1831  if( value.ToDouble( &ratioPercent ) )
1832  aPad->SetRoundRectRadiusRatio( ratioPercent / 100.0 );
1833 
1834  value = m_tcChamferRatio->GetValue();
1835 
1836  if( value.ToDouble( &ratioPercent ) )
1837  aPad->SetChamferRectRatio( ratioPercent / 100.0 );
1838  }
1839 
1840  LSET padLayerMask;
1841 
1842  switch( m_rbCopperLayersSel->GetSelection() )
1843  {
1844  case 0: padLayerMask.set( F_Cu ); break;
1845  case 1: padLayerMask.set( B_Cu ); break;
1846  case 2: padLayerMask |= LSET::AllCuMask(); break;
1847  case 3: break; // No copper layers
1848  }
1849 
1850  if( m_PadLayerAdhCmp->GetValue() )
1851  padLayerMask.set( F_Adhes );
1852 
1853  if( m_PadLayerAdhCu->GetValue() )
1854  padLayerMask.set( B_Adhes );
1855 
1856  if( m_PadLayerPateCmp->GetValue() )
1857  padLayerMask.set( F_Paste );
1858 
1859  if( m_PadLayerPateCu->GetValue() )
1860  padLayerMask.set( B_Paste );
1861 
1862  if( m_PadLayerSilkCmp->GetValue() )
1863  padLayerMask.set( F_SilkS );
1864 
1865  if( m_PadLayerSilkCu->GetValue() )
1866  padLayerMask.set( B_SilkS );
1867 
1868  if( m_PadLayerMaskCmp->GetValue() )
1869  padLayerMask.set( F_Mask );
1870 
1871  if( m_PadLayerMaskCu->GetValue() )
1872  padLayerMask.set( B_Mask );
1873 
1874  if( m_PadLayerECO1->GetValue() )
1875  padLayerMask.set( Eco1_User );
1876 
1877  if( m_PadLayerECO2->GetValue() )
1878  padLayerMask.set( Eco2_User );
1879 
1880  if( m_PadLayerDraft->GetValue() )
1881  padLayerMask.set( Dwgs_User );
1882 
1883  aPad->SetLayerSet( padLayerMask );
1884 
1885  return error;
1886 }
1887 
1888 
1889 void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
1890 {
1891  if( m_canUpdate )
1892  {
1894  // If the pad size has changed, update the displayed values
1895  // for rounded rect pads
1897 
1898  redraw();
1899  }
1900 }
1901 
1903 {
1904  long select = m_listCtrlPrimitives->GetFirstSelected();
1905 
1906  if( select < 0 )
1907  {
1908  wxMessageBox( _( "No shape selected" ) );
1909  return;
1910  }
1911 
1912  PAD_CS_PRIMITIVE& shape = m_primitives[select];
1913 
1914  if( shape.m_Shape == S_POLYGON )
1915  {
1916  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, m_parent, &shape );
1917 
1918  if( dlg.ShowModal() != wxID_OK )
1919  return;
1920 
1921  dlg.TransferDataFromWindow();
1922  }
1923 
1924  else
1925  {
1926  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, m_parent, &shape );
1927 
1928  if( dlg.ShowModal() != wxID_OK )
1929  return;
1930 
1931  dlg.TransferDataFromWindow();
1932  }
1933 
1935 
1936  if( m_canUpdate )
1937  {
1939  redraw();
1940  }
1941 }
1942 
1943 
1945 {
1946  // Called on a double click on the basic shapes list
1947  // To Do: highligth the primitive(s) currently selected.
1948  redraw();
1949 }
1950 
1951 
1953 void DIALOG_PAD_PROPERTIES::onPrimitiveDClick( wxMouseEvent& event )
1954 {
1955  editPrimitive();
1956 }
1957 
1958 
1959 // Called on a click on basic shapes list panel button
1960 void DIALOG_PAD_PROPERTIES::onEditPrimitive( wxCommandEvent& event )
1961 {
1962  editPrimitive();
1963 }
1964 
1965 // Called on a click on basic shapes list panel button
1966 void DIALOG_PAD_PROPERTIES::onDeletePrimitive( wxCommandEvent& event )
1967 {
1968  long select = m_listCtrlPrimitives->GetFirstSelected();
1969 
1970  if( select < 0 )
1971  return;
1972 
1973  // Multiple selections are allowed. get them and remove corresponding shapes
1974  std::vector<long> indexes;
1975  indexes.push_back( select );
1976 
1977  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1978  indexes.push_back( select );
1979 
1980  // Erase all select shapes
1981  for( unsigned ii = indexes.size(); ii > 0; --ii )
1982  m_primitives.erase( m_primitives.begin() + indexes[ii-1] );
1983 
1985 
1986  if( m_canUpdate )
1987  {
1989  redraw();
1990  }
1991 }
1992 
1993 
1994 void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
1995 {
1996  // Ask user for shape type
1997  wxString shapelist[] = { _( "Segment" ), _( "Arc" ), _( "Bezier" ),
1998  _( "Ring/Circle" ), _( "Polygon" ) };
1999 
2000  int type = wxGetSingleChoiceIndex( _( "Shape type:" ), _( "Add Primitive" ),
2001  arrayDim( shapelist ), shapelist, 0, this );
2002 
2003  // User pressed cancel
2004  if( type == -1 )
2005  return;
2006 
2007  STROKE_T listtype[] = { S_SEGMENT, S_ARC, S_CURVE, S_CIRCLE, S_POLYGON };
2008 
2009  PAD_CS_PRIMITIVE primitive( listtype[type] );
2011 
2012  if( listtype[type] == S_POLYGON )
2013  {
2014  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, m_parent, &primitive );
2015 
2016  if( dlg.ShowModal() != wxID_OK )
2017  return;
2018  }
2019  else
2020  {
2021  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, m_parent, &primitive );
2022 
2023  if( dlg.ShowModal() != wxID_OK )
2024  return;
2025  }
2026 
2027  m_primitives.push_back( primitive );
2028 
2030 
2031  if( m_canUpdate )
2032  {
2034  redraw();
2035  }
2036 }
2037 
2038 
2039 void DIALOG_PAD_PROPERTIES::onGeometryTransform( wxCommandEvent& event )
2040 {
2041  long select = m_listCtrlPrimitives->GetFirstSelected();
2042 
2043  if( select < 0 )
2044  {
2045  wxMessageBox( _( "No shape selected" ) );
2046  return;
2047  }
2048 
2049  // Multiple selections are allowed. Build selected shapes list
2050  std::vector<PAD_CS_PRIMITIVE*> shapeList;
2051  shapeList.push_back( &m_primitives[select] );
2052 
2053  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
2054  shapeList.push_back( &m_primitives[select] );
2055 
2056  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, m_parent, shapeList, false );
2057 
2058  if( dlg.ShowModal() != wxID_OK )
2059  return;
2060 
2061  // Transfert new settings:
2062  dlg.Transform();
2063 
2065 
2066  if( m_canUpdate )
2067  {
2069  redraw();
2070  }
2071 }
2072 
2073 
2074 void DIALOG_PAD_PROPERTIES::onDuplicatePrimitive( wxCommandEvent& event )
2075 {
2076  long select = m_listCtrlPrimitives->GetFirstSelected();
2077 
2078  if( select < 0 )
2079  {
2080  wxMessageBox( _( "No shape selected" ) );
2081  return;
2082  }
2083 
2084  // Multiple selections are allowed. Build selected shapes list
2085  std::vector<PAD_CS_PRIMITIVE*> shapeList;
2086  shapeList.push_back( &m_primitives[select] );
2087 
2088  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
2089  shapeList.push_back( &m_primitives[select] );
2090 
2091  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, m_parent, shapeList, true );
2092 
2093  if( dlg.ShowModal() != wxID_OK )
2094  return;
2095 
2096  // Transfer new settings
2097  // save duplicates to a separate vector to avoid m_primitives reallocation,
2098  // as shapeList contains pointers to its elements
2099  std::vector<PAD_CS_PRIMITIVE> duplicates;
2100  dlg.Transform( &duplicates, dlg.GetDuplicateCount() );
2101  std::move( duplicates.begin(), duplicates.end(), std::back_inserter( m_primitives ) );
2102 
2104 
2105  if( m_canUpdate )
2106  {
2108  redraw();
2109  }
2110 }
void OnInitDialog(wxInitDialogEvent &event) override
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
void OnValuesChanged(wxCommandEvent &event) override
Called when a dimension has changed.
void Move(const Vec &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
Definition: box2.h:118
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:123
int GetLocalSolderMaskMargin() const
Definition: class_pad.h:426
double GetOrientation() const
Definition: class_module.h:188
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask,...
Definition: lset.cpp:521
DIALOG_PAD_PROPERTIES(PCB_BASE_FRAME *aParent, D_PAD *aPad)
int GetNetCode() const
Function GetNetCode.
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:550
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
void enablePrimitivePage(bool aEnable)
enable (or disable) the primitive page editor
static LSET StandardMask()
layer set for a through hole pad
Definition: class_pad.cpp:101
KIGFX::VIEW_CONTROLS * GetViewControls() const
Function GetViewControls() Returns a pointer to the VIEW_CONTROLS instance used in the panel.
bool m_Display_padnum
Definition: class_pad.h:75
void FlipPrimitives()
Flip the basic shapes, in custom pads.
Definition: class_pad.cpp:462
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
virtual void Move(const wxPoint &aMoveVector) override
Function Move move this object.
virtual void SetTopLayer(int aLayer, bool aEnabled=true)
Function SetTopLayer() Sets given layer to be displayed on the top or sets back the default order of ...
Definition: view.cpp:859
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
PAD_ATTR_T
Enum PAD_ATTR_T is the set of pad shapes, used with D_PAD::{Set,Get}Attribute() The double name is fo...
Definition: pad_shapes.h:59
bool IsFlipped() const
function IsFlipped
Definition: class_module.h:258
multilayer pads, usually with holes
bool MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon=NULL, int aCircleToSegmentsCount=ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF)
Merge all basic shapes, converted to a polygon in one polygon, in m_customShapeAsPolygon.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Implementation of conversion functions that require both schematic and board internal units.
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
Definition: class_pad.cpp:122
This file is part of the common library.
const wxPoint GetCenter() const override
Function GetCenter()
PAD_SHAPE_T GetAnchorPadShape() const
Function GetAnchorPadShape.
Definition: class_pad.h:228
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: class_pad.cpp:108
VIEW_CONTROLS class definition.
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
const wxPoint GetArcEnd() const
bool transferDataToPad(D_PAD *aPad)
Copy values from dialog field to aPad's members.
Class BOARD to handle a board.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:931
void ExportTo(DRAWSEGMENT *aTarget)
Export the PAD_CS_PRIMITIVE parameters to a DRAWSEGMENT useful to draw a primitive shape.
wxPoint m_Start
angle of an arc, from its starting point, in 0.1 deg
Definition: class_pad.h:100
virtual bool Validate(int aMin, int aMax, bool setFocusOnError=true)
Function Validate Validates the control against the given range, informing the user of any errors fou...
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
void setPadLayersList(LSET layer_mask)
Function setPadLayersList updates the CheckBox states in pad layers list,.
bool IsFlipped() const
Definition: class_pad.cpp:136
int GetPadToDieLength() const
Definition: class_pad.h:424
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
BOX2< VECTOR2D > BOX2D
Definition: box2.h:521
wxFloatingPointValidator< double > m_OrientValidator
const wxString GetValue() const
Function GetValue.
Definition: class_module.h:487
virtual void EnableMousewheelPan(bool aEnable)
Function EnableMousewheelPan() Enables or disables mousewheel panning.
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:415
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:221
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
virtual void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
int GetSelectedNetcode()
void onChangePadMode(wxCommandEvent &event) override
usual segment : line with rounded ends
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:276
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
void NORMALIZE_ANGLE_180(T &Angle)
Definition: trigo.h:344
void SetRoundRectRadiusRatio(double aRadiusScale)
has meaning only for rounded rect pads Set the scaling factor between the smaller Y or Y size and the...
Definition: class_pad.h:658
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
void Transform(std::vector< PAD_CS_PRIMITIVE > *aList=NULL, int aDuplicateCount=0)
Apply geometric transform (rotation, move, scale) defined in dialog aDuplicate = 1 .
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
int GetThermalGap() const
Definition: class_pad.cpp:759
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:778
void onCornerSizePercentChange(wxCommandEvent &event) override
#define abs(a)
Definition: auxiliary.h:84
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:250
int GetLocalClearance() const
Definition: class_pad.h:429
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:116
void SetSketchModeGraphicItems(bool aEnabled)
Turns on/off sketch mode for graphic items (DRAWSEGMENTs, texts).
Definition: pcb_painter.h:133
void GRClosedPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, COLOR4D Color, COLOR4D BgColor)
Function GRClosedPoly draws a closed polygon onto the drawing context aDC and optionally fills and/or...
Definition: gr_basic.cpp:711
static const int delta[8][2]
Definition: solve.cpp:112
void SetValue(const wxString &aValue) override
Set a new value in evaluator buffer, and display it in the wxTextCtrl.
PAD_SHAPE_T
Enum PAD_SHAPE_T is the set of pad shapes, used with D_PAD::{Set,Get}Shape()
Definition: pad_shapes.h:31
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:417
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:462
int GetChamferPositions() const
has meaning only for chamfered rect pads
Definition: class_pad.h:695
static PAD_SHAPE_T code_shape[]
Classes used in Pcbnew, CvPcb and GerbView.
class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, created by wxFormBuilder
Pads are not covered.
Definition: zones.h:52
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
wxString MessageTextFromValue(EDA_UNITS_T aUnits, int aValue, bool aUseMils)
Definition: base_units.cpp:125
bool IsGalCanvasActive() const
Function IsGalCanvasActive is used to check which canvas (GAL-based or standard) is currently in use.
Definition: draw_frame.h:924
dialog pad properties editor.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Function GetLineThickness Returns the default graphic segment thickness from the layer class for the ...
KIGFX::ORIGIN_VIEWITEM * m_axisOrigin
Class PCB_RENDER_SETTINGS Stores PCB specific render settings.
Definition: pcb_painter.h:61
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
#define SELECTED
Definition: base_struct.h:121
void onAddPrimitive(wxCommandEvent &event) override
static PAD_ATTR_T code_type[]
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Function SetAnchorPadShape Set the shape of the anchor pad for custm shped pads.
Definition: class_pad.h:255
void OnCancel(wxCommandEvent &event) override
static wxString formatCoord(EDA_UNITS_T aUnits, wxPoint aCoord)
std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file.
Definition: base_units.cpp:490
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
Definition: class_pad.cpp:1414
int m_Radius
thickness of segment or outline For filled S_CIRCLE shape, thickness = 0.
Definition: class_pad.h:98
Class LSET is a set of PCB_LAYER_IDs.
const std::vector< PAD_CS_PRIMITIVE > & GetPrimitives() const
Accessor to the basic shape list.
Definition: class_pad.h:341
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:259
std::vector< wxPoint > m_Poly
Bezier Control point 2.
Definition: class_pad.h:104
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
void OnSetLayers(wxCommandEvent &event) override
void SetZoneConnection(ZoneConnection aType)
Definition: class_pad.h:501
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void OnPaintShowPanel(wxPaintEvent &event) override
void SetName(const wxString &aName)
Set the pad name (sometimes called pad number, although it can be an array reference like AA12).
Definition: class_pad.h:184
wxStaticBoxSizer * m_sbSizerCustomShapedZonesSettings
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:264
PCB_GENERAL_SETTINGS & Settings()
int ShowQuasiModal()
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
Arcs (with rounded ends)
const wxPoint & GetOffset() const
Definition: class_pad.h:280
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:400
double GetChamferRectRatio() const
has meaning only for chamfered rect pads
Definition: class_pad.h:672
int GetThermalWidth() const
Definition: class_pad.cpp:748
Helper class to handle a primitive (basic shape: polygon, segment, circle or arc) to build a custom p...
Definition: class_pad.h:91
void SetLastEditTime(timestamp_t aTime)
Definition: class_module.h:313
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:414
void SetSelectedNetcode(int aNetcode)
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
void onCornerRadiusChange(wxCommandEvent &event) override
Class DIALOG_PAD_PROPERTIES_BASE.
void SetDrawAtZero(bool aDrawFlag)
Function SetDrawAtZero() Set the draw at zero flag.
void SetStealsFocus(bool aStealsFocus)
Set whether focus is taken on certain events (mouseover, keys, etc).
void OnResize(wxSizeEvent &event)
void OnPadShapeSelection(wxCommandEvent &event) override
void PadTypeSelected(wxCommandEvent &event) override
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:636
void SetThermalWidth(int aWidth)
Definition: class_pad.h:504
COLOR4D m_HoleColor
Definition: class_pad.h:70
void onPrimitiveDClick(wxMouseEvent &event) override
Called on a double click on the basic shapes list.
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:137
const wxString & GetName() const
Definition: class_pad.h:192
void SetSize(const wxSize &aSize)
Definition: class_pad.h:270
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:624
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Function SetLayerColor Changes the color used to draw a layer.
Definition: painter.h:230
void SetRoundRectCornerRadius(double aRadius)
Set the rounded rectangle radius ratio based on a given radius.
Definition: class_pad.cpp:217
void OnDrillShapeSelected(wxCommandEvent &event) override
const wxPoint & GetArcStart() const
bool m_ShowNotPlatedHole
Definition: class_pad.h:80
void SetNetInfo(NETINFO_LIST *aNetInfoList)
Bezier Curve.
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:399
void SetPadToDieLength(int aLength)
Definition: class_pad.h:423
bool GetEnableMousewheelPan() const
Class HTML_MESSAGE_BOX.
const wxSize & GetDelta() const
Definition: class_pad.h:274
void DrawShape(EDA_RECT *aClipBox, wxDC *aDC, PAD_DRAWINFO &aDrawInfo)
Function DrawShape basic function to draw a pad.
void onGeometryTransform(wxCommandEvent &event) override
wxPoint m_End
is also the center of the circle and arc
Definition: class_pad.h:101
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1539
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:285
NETINFO_LIST & GetNetInfo()
Definition: class_board.h:748
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:63
STROKE_T m_Shape
Definition: class_pad.h:94
void SetGridSize(const VECTOR2D &aGridSize)
Set the grid size.
void StartDrawing()
Function StartDrawing() Begins drawing if it was stopped previously.
int m_PadClearance
Definition: class_pad.h:73
void SetAttribute(PAD_ATTR_T aAttribute)
Definition: class_pad.cpp:420
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
void UseColorScheme(const COLORS_DESIGN_SETTINGS *aSettings)
Function UseColorScheme Applies layer color settings.
COLORS_DESIGN_SETTINGS & Colors()
void SetLocalClearance(int aClearance)
Definition: class_pad.h:430
a dialog to edit basic polygonal shape parameters
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:107
MODULE * GetParent() const
Definition: class_pad.h:164
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_pad.h:436
bool SwitchBackend(GAL_TYPE aGalType) override
Function SwitchBackend Switches method of rendering graphics.
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: class_pad.h:234
int m_Thickness
S_SEGMENT, S_ARC, S_CIRCLE, S_POLYGON only (same as DRAWSEGMENT)
Definition: class_pad.h:95
void OnPrimitiveSelection(wxListEvent &event) override
Called on selection/deselection of a basic shape.
void onEditPrimitive(wxCommandEvent &event) override
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
bool TransferDataFromWindow() override
Updates the different parameters for the component being edited.
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:413
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:300
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
void PadOrientEvent(wxCommandEvent &event) override
wxPoint m_Offset
Definition: class_pad.h:83
const int scale
smd pads, front layer
#define HIGHLIGHTED
item is drawn in normal colors, when the rest is darkened
Definition: base_struct.h:136
std::vector< PAD_CS_PRIMITIVE > m_primitives
bool IsType(FRAME_T aType) const
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetDrillShape(PAD_DRILL_SHAPE_T aDrillShape)
Definition: class_pad.h:398
static const LSET std_pad_layers[]
void onDeletePrimitive(wxCommandEvent &event) override
Event handlers of basic shapes list panel.
void onDuplicatePrimitive(wxCommandEvent &event) override
void SetLocalSolderMaskMargin(int aMargin)
Definition: class_pad.h:427
void SetSketchMode(int aItemLayer, bool aEnabled)
Function SetSketchMode Turns on/off sketch mode for given item layer.
Definition: pcb_painter.h:113
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:394
void GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:526
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:755
const wxSize & GetDrillSize() const
Definition: class_pad.h:277
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
bool IsAperturePad() const
Definition: class_pad.h:421
The common library.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:219
void SetGridVisibility(bool aVisibility)
Sets the visibility setting of the grid.
#define SELECTED_ITEMS_LAYER
bool m_ShowPadFilled
Definition: class_pad.h:77
void SetEnd(const wxPoint &aEnd)
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:543
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:429
double GetRoundRectRadiusRatio() const
has meaning only for rounded rect pads
Definition: class_pad.h:646
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:260
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:210
bool padValuesOK()
test if all values are acceptable for the pad
void SetChamferRectRatio(double aChamferScale)
has meaning only for chamfered rect pads Set the ratio between the smaller Y or Y size and the radius...
Definition: class_pad.h:683
COLOR4D m_Color
Definition: class_pad.h:68
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:433
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: class_pad.cpp:115
void SetCustomShapeInZoneOpt(CUST_PAD_SHAPE_IN_ZONE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
Definition: class_pad.h:244
void InstallPadOptionsFrame(D_PAD *pad)
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:346
GAL_TYPE GetBackend() const
Function GetBackend Returns the type of backend currently used by GAL canvas.
const Vec & GetSize() const
Definition: box2.h:187
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:218
Module description (excepted pads)
Definition: colors.h:45
static LSET ApertureMask()
layer set for an aperture pad
Definition: class_pad.cpp:129
BOARD * GetBoard() const
const Vec & GetOrigin() const
Definition: box2.h:191
Class VIEW.
Definition: view.h:61
void SetBoundary(const BOX2D &aBoundary)
Function SetBoundary() Sets limits for view area.
Definition: view.h:278
EDA_UNITS_T m_units
Definition: dialog_shim.h:173
bool m_Display_netname
Definition: class_pad.h:76
ZoneConnection GetZoneConnection() const
Definition: class_pad.cpp:737
const wxSize & GetSize() const
Definition: class_pad.h:271
const wxPoint GetPosition() const override
Definition: class_pad.h:222
double GetScale() const
Function GetScale()
Definition: view.h:268
int GetLocalSolderPasteMargin() const
Definition: class_pad.h:432
std::vector< DRAWSEGMENT * > m_highlight
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:279
A dialog to apply geometry transforms to a shape or set of shapes (move, rotate around origin,...
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:244
void SetThermalGap(int aGap)
Definition: class_pad.h:507
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:465
const wxPoint GetPosition() const override
Definition: class_module.h:183
Use thermal relief for pads.
Definition: zones.h:53
bool SetPrimitives(const std::vector< PAD_CS_PRIMITIVE > &aPrimitivesList)
Import to the basic shape list.
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void DeletePrimitivesList()
clear the basic shapes list
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: class_pad.cpp:226
EDA_UNITS_T
Definition: common.h:157
void StopDrawing()
Function StopDrawing() Prevents the GAL canvas from further drawing till it is recreated or StartDraw...
double m_ArcAngle
radius of a circle
Definition: class_pad.h:99
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
a dialog to edit basics shapes parameters.
double GetLocalSolderPasteMarginRatio() const
Definition: class_pad.h:435
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:126
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:273
virtual void OnUpdateUI(wxUpdateUIEvent &event) override
#define min(a, b)
Definition: auxiliary.h:85
void SetChamferPositions(int aChamferPositions)
has meaning only for chamfered rect pads set the position of the chamfer for a 0 orientation,...
Definition: class_pad.h:703
pads are covered by copper
Definition: zones.h:54
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:240
void GRArc1(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int xc, int yc, COLOR4D Color)
Definition: gr_basic.cpp:799
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
virtual void ChangeValue(int aValue)
Function ChangeValue Changes the value (in Internal Units) for the text field, taking care of units c...
EDA_UNITS_T GetUserUnits() const override
Definition: dialog_shim.h:133
void SetWidth(int aWidth)