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