KiCad PCB EDA Suite
dialog_pad_properties.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
10  * Copyright (C) 2013 Dick Hollenbeck, dick@softplc.com
11  * Copyright (C) 2008-2013 Wayne Stambaugh <stambaughw@verizon.net>
12  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, you may find one here:
26  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
27  * or you may search the http://www.gnu.org website for the version 2 license,
28  * or you may write to the Free Software Foundation, Inc.,
29  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
30  */
31 
32 #include <fctsys.h>
33 #include <common.h>
34 #include <gr_basic.h>
36 #include <trigo.h>
37 #include <class_drawpanel.h>
38 #include <confirm.h>
39 #include <pcbnew.h>
40 #include <wxBasePcbFrame.h>
41 #include <base_units.h>
42 #include <unit_format.h>
43 #include <board_commit.h>
44 
45 #include <class_board.h>
46 #include <class_module.h>
47 #include <pcb_painter.h>
48 
49 #include <dialog_pad_properties.h>
50 #include <html_messagebox.h>
51 
52 
53 // list of pad shapes, ordered like the pad shape wxChoice in dialog.
54 static PAD_SHAPE_T code_shape[] = {
60  PAD_SHAPE_CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
61  PAD_SHAPE_CUSTOM // choice = PAD_SHAPE_CUSTOM_RECT_ANCHOR
62 };
63 
64 // the ordered index of the pad shape wxChoice in dialog.
65 // keep it consistent with code_shape[] and dialog strings
74 };
75 
76 
77 
78 static PAD_ATTR_T code_type[] = {
83 };
84 
85 
86 // Default mask layers setup for pads according to the pad type
87 static const LSET std_pad_layers[] = {
88  // PAD_ATTRIB_STANDARD:
90 
91  // PAD_ATTRIB_SMD:
93 
94  // PAD_ATTRIB_CONN:
96 
97  // PAD_ATTRIB_HOLE_NOT_PLATED:
99 };
100 
101 
103 {
104  DIALOG_PAD_PROPERTIES dlg( this, aPad );
105  dlg.ShowModal();
106 }
107 
108 
110  DIALOG_PAD_PROPERTIES_BASE( aParent ),
111  m_OrientValidator( 1, &m_OrientValue )
112 {
113  m_canUpdate = false;
114  m_parent = aParent;
115  m_currentPad = aPad; // aPad can be NULL, if the dialog is called
116  // from the footprint editor to set default pad setup
117 
119 
120  m_OrientValidator.SetRange( -360.0, 360.0 );
121  m_PadOrientCtrl->SetValidator( m_OrientValidator );
122  m_OrientValidator.SetWindow( m_PadOrientCtrl );
123 
125 
127  m_dummyPad = new D_PAD( (MODULE*) NULL );
128 
129  if( aPad )
130  *m_dummyPad = *aPad;
131  else // We are editing a "master" pad, i.e. a template to create new pads
133 
134  initValues();
135 
136  // Usually, TransferDataToWindow is called by OnInitDialog
137  // calling it here fixes all widgets sizes, and FinishDialogSettings can
138  // safely fix minsizes
140 
141  // Initialize canvas to be able to display the dummy pad:
142  prepareCanvas();
143 
144  m_sdbSizerOK->SetDefault();
145  m_canUpdate = true;
146 
147  // Now all widgets have the size fixed, call FinishDialogSettings
149 }
150 
151 bool DIALOG_PAD_PROPERTIES::m_drawPadOutlineMode = false; // Stores the pad draw option during a session
152 
153 
154 void DIALOG_PAD_PROPERTIES::OnInitDialog( wxInitDialogEvent& event )
155 {
156  m_PadNumCtrl->SetFocus();
157  m_PadNumCtrl->SetSelection( -1, -1 );
158  m_selectedColor = COLOR4D( 1.0, 1.0, 1.0, 0.7 );
159 
160  // Needed on some WM to be sure the pad is redrawn according to the final size
161  // of the canvas, with the right zoom factor
162  redraw();
163 }
164 
165 
166 void DIALOG_PAD_PROPERTIES::OnCancel( wxCommandEvent& event )
167 {
168  // Mandatory to avoid m_panelShowPadGal trying to draw something
169  // in a non valid context during closing process:
170  if( m_parent->IsGalCanvasActive() )
172 
173  // Now call default handler for wxID_CANCEL command event
174  event.Skip();
175 }
176 
177 
179 {
180  // Enable or disable the widgets in page managing custom shape primitives
181  m_listCtrlPrimitives->Enable( aEnable );
182  m_buttonDel->Enable( aEnable );
183  m_buttonEditShape->Enable( aEnable );
184  m_buttonAddShape->Enable( aEnable );
185  m_buttonDup->Enable( aEnable );
186  m_buttonGeometry->Enable( aEnable );
187  m_buttonImport->Enable( aEnable );
188 }
189 
190 
192 {
193  // Initialize the canvases (legacy or gal) to display the pad
194  // Enable the suitable canvas and make some inits
195 
196  // Show the X and Y axis. It is usefull because pad shape can have an offset
197  // or be a complex shape.
198  KIGFX::COLOR4D axis_color = LIGHTBLUE;
199 
200  m_axisOrigin = new KIGFX::ORIGIN_VIEWITEM( axis_color,
202  Millimeter2iu( 0.2 ),
204  m_axisOrigin->SetDrawAtZero( true );
205 
206  if( m_parent->IsGalCanvasActive() )
207  {
210 
211  m_panelShowPadGal->Show();
212  m_panelShowPad->Hide();
213 
215 
216  // fix the pad render mode (filled/not filled)
217  KIGFX::PCB_RENDER_SETTINGS* settings =
218  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
219  bool filled = !m_cbShowPadOutline->IsChecked();
220  settings->SetSketchMode( LAYER_PADS_TH, !filled );
221  settings->SetSketchMode( LAYER_PAD_FR, !filled );
222  settings->SetSketchMode( LAYER_PAD_BK, !filled );
223  settings->SetSketchModeGraphicItems( !filled );
224 
225  // gives a non null grid size (0.001mm) because GAL layer does not like a 0 size grid:
226  double gridsize = 0.001 * IU_PER_MM;
227  view->GetGAL()->SetGridSize( VECTOR2D( gridsize, gridsize ) );
228  view->Add( m_dummyPad );
229  view->Add( m_axisOrigin );
230 
232  Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
233  }
234  else
235  {
236  m_panelShowPad->Show();
237  m_panelShowPadGal->Hide();
238  }
239 }
240 
241 
242 void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
243 {
244  wxPaintDC dc( m_panelShowPad );
245  PAD_DRAWINFO drawInfo;
246 
248 
249  if( m_dummyPad->GetLayerSet()[F_Cu] )
250  {
252  }
253 
254  if( m_dummyPad->GetLayerSet()[B_Cu] )
255  {
256  color = color.LegacyMix( m_parent->Settings().Colors().GetItemColor( LAYER_PAD_BK ) );
257  }
258 
259  // What could happen: the pad color is *actually* black, or no
260  // copper was selected
261  if( color == BLACK )
262  color = LIGHTGRAY;
263 
264  drawInfo.m_Color = color;
265  drawInfo.m_HoleColor = DARKGRAY;
266  drawInfo.m_Offset = m_dummyPad->GetPosition();
267  drawInfo.m_Display_padnum = true;
268  drawInfo.m_Display_netname = true;
270 
272  drawInfo.m_ShowNotPlatedHole = true;
273 
274  // Shows the local pad clearance
276 
277  wxSize dc_size = dc.GetSize();
278  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
279 
280  // Calculate a suitable scale to fit the available draw area
281  int dim = m_dummyPad->GetBoundingRadius() *2;
282 
283  // Invalid x size. User could enter zero, or have deleted all text prior to
284  // entering a new value; this is also treated as zero. If dim is left at
285  // zero, the drawing scale is zero and we get a crash.
286  if( dim == 0 )
287  {
288  // If drill size has been set, use that. Otherwise default to 1mm.
289  dim = m_dummyPad->GetDrillSize().x;
290  if( dim == 0 )
291  dim = Millimeter2iu( 1.0 );
292  }
293 
294  if( m_dummyPad->GetLocalClearance() > 0 )
295  dim += m_dummyPad->GetLocalClearance() * 2;
296 
297  double scale = (double) dc_size.x / dim;
298 
299  // If the pad is a circle, use the x size here instead.
300  int ysize;
301 
303  ysize = m_dummyPad->GetSize().x;
304  else
305  ysize = m_dummyPad->GetSize().y;
306 
307  dim = ysize + std::abs( m_dummyPad->GetDelta().x );
308 
309  // Invalid y size. See note about x size above.
310  if( dim == 0 )
311  {
312  dim = m_dummyPad->GetDrillSize().y;
313  if( dim == 0 )
314  dim = Millimeter2iu( 0.1 );
315  }
316 
317  if( m_dummyPad->GetLocalClearance() > 0 )
318  dim += m_dummyPad->GetLocalClearance() * 2;
319 
320  double altscale = (double) dc_size.y / dim;
321  scale = std::min( scale, altscale );
322 
323  // Give a margin
324  scale *= 0.7;
325  dc.SetUserScale( scale, scale );
326 
327  GRResetPenAndBrush( &dc );
328  m_dummyPad->DrawShape( NULL, &dc, drawInfo );
329 
330  // draw selected primitives:
331  long select = m_listCtrlPrimitives->GetFirstSelected();
332  wxPoint start, end, center;
333 
334  while( select >= 0 )
335  {
336  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
337 
338  // The best way to calculate parameters to draw a primitive is to
339  // use a dummy DRAWSEGMENT and use its methods
340  // Note: in legacy canvas, the pad has the 0,0 position
341  DRAWSEGMENT dummySegment;
342  primitive.ExportTo( &dummySegment );
343  dummySegment.Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
344 
345  switch( primitive.m_Shape )
346  {
347  case S_SEGMENT: // usual segment : line with rounded ends
348  if( !m_drawPadOutlineMode )
349  GRFilledSegment( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
350  primitive.m_Thickness, m_selectedColor );
351  else
352  GRCSegm( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
353  primitive.m_Thickness, m_selectedColor );
354  break;
355 
356  case S_ARC: // Arc with rounded ends
357  if( !m_drawPadOutlineMode )
358  GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
359  dummySegment.GetCenter(), primitive.m_Thickness, m_selectedColor );
360  else
361  {
362  GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
363  dummySegment.GetCenter(), 0, m_selectedColor );
364 /* GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
365  dummySegment.GetCenter() - primitive.m_Thickness, 0, m_selectedColor );*/
366  }
367  break;
368 
369  case S_CIRCLE: // ring or circle
370  if( primitive.m_Thickness )
371  {
372  if( !m_drawPadOutlineMode )
373  GRCircle( NULL, &dc, dummySegment.GetCenter(), primitive.m_Radius,
374  primitive.m_Thickness, m_selectedColor );
375  else
376  {
377  GRCircle( NULL, &dc, dummySegment.GetCenter(),
378  primitive.m_Radius + primitive.m_Thickness/2, 0,
379  m_selectedColor );
380  GRCircle( NULL, &dc, dummySegment.GetCenter(),
381  primitive.m_Radius - primitive.m_Thickness/2, 0,
382  m_selectedColor );
383  }
384  }
385  else
386  {
387  if( !m_drawPadOutlineMode )
388  GRFilledCircle( NULL, &dc, dummySegment.GetCenter(),
389  primitive.m_Radius, m_selectedColor );
390  else
391  GRCircle( NULL, &dc, dummySegment.GetCenter(),
392  primitive.m_Radius, 0, m_selectedColor );
393  }
394  break;
395 
396  case S_POLYGON: // polygon
397  {
398  std::vector<wxPoint> poly = dummySegment.GetPolyPoints();
399  GRClosedPoly( NULL, &dc, poly.size(), &poly[0],
400  m_drawPadOutlineMode ? false : true,
402  }
403  break;
404 
405  default:
406  break;
407  }
408 
409  select = m_listCtrlPrimitives->GetNextSelected( select );
410  }
411 
412  // Draw X and Y axis. This is particularly useful to show the
413  // reference position of pads with offset and no hole, or custom pad shapes
414  const int linethickness = 0;
415  GRLine( NULL, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0,
416  linethickness, LIGHTBLUE ); // X axis
417  GRLine( NULL, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ),
418  linethickness, LIGHTBLUE ); // Y axis
419 
420  event.Skip();
421 }
422 
423 
425 {
426  // Note:
427  // To avoid generating a wxEVT_TEXT event from m_tcCornerSizeRatio
428  // we use ChangeValue instead of SetValue, to set the displayed string
430  {
431  m_tcCornerSizeRatio->ChangeValue( wxString::Format( "%.1f",
435  }
436  else if( m_dummyPad->GetShape() == PAD_SHAPE_RECT )
437  {
438  m_tcCornerSizeRatio->ChangeValue( "0" );
439  m_staticTextCornerRadiusValue->SetLabel( "0" );
440  }
441  else
442  {
443  m_tcCornerSizeRatio->ChangeValue( wxEmptyString );
444  m_staticTextCornerRadiusValue->SetLabel( wxEmptyString );
445  }
446 }
447 
448 
450 {
452  return;
453 
454  wxString value = m_tcCornerSizeRatio->GetValue();
455  double rrRadiusRatioPercent;
456 
457  if( value.ToDouble( &rrRadiusRatioPercent ) )
458  {
459  // Clamp rrRadiusRatioPercent to acceptable value (0.0 to 50.0)
460  if( rrRadiusRatioPercent < 0.0 )
461  {
462  rrRadiusRatioPercent = 0.0;
463  m_tcCornerSizeRatio->ChangeValue( "0.0" );
464  }
465 
466  if( rrRadiusRatioPercent > 50.0 )
467  {
468  rrRadiusRatioPercent = 0.5;
469  m_tcCornerSizeRatio->ChangeValue( "50.0" );
470  }
471 
475  redraw();
476  }
477 }
478 
479 
481 {
482  wxString msg;
483  double angle;
484 
485  // Disable pad net name wxTextCtrl if the caller is the footprint editor
486  // because nets are living only in the board managed by the board editor
488 
489 
490  // Setup layers names from board
491  // Should be made first, before calling m_rbCopperLayersSel->SetSelection()
492  m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( F_Cu ) );
493  m_rbCopperLayersSel->SetString( 1, m_board->GetLayerName( B_Cu ) );
494 
495  m_PadLayerAdhCmp->SetLabel( m_board->GetLayerName( F_Adhes ) );
496  m_PadLayerAdhCu->SetLabel( m_board->GetLayerName( B_Adhes ) );
498  m_PadLayerPateCu->SetLabel( m_board->GetLayerName( B_Paste ) );
500  m_PadLayerSilkCu->SetLabel( m_board->GetLayerName( B_SilkS ) );
501  m_PadLayerMaskCmp->SetLabel( m_board->GetLayerName( F_Mask ) );
502  m_PadLayerMaskCu->SetLabel( m_board->GetLayerName( B_Mask ) );
503  m_PadLayerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
504  m_PadLayerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
506 
507  m_isFlipped = false;
508 
509  if( m_currentPad )
510  {
512 
513  if( m_isFlipped )
514  m_staticModuleSideValue->SetLabel( _( "Back side (footprint is mirrored)" ) );
515 
516  // Diplay footprint rotation ( angles are in 0.1 degree )
517  MODULE* footprint = m_currentPad->GetParent();
518 
519  if( footprint )
520  msg.Printf( "%.1f", footprint->GetOrientationDegrees() );
521  else
522  msg = _("No footprint" );
523 
524  m_staticModuleRotValue->SetLabel( msg );
525  }
526 
527  if( m_isFlipped )
528  {
529  wxPoint pt = m_dummyPad->GetOffset();
530  pt.y = -pt.y;
531  m_dummyPad->SetOffset( pt );
532 
533  wxSize sz = m_dummyPad->GetDelta();
534  sz.y = -sz.y;
535  m_dummyPad->SetDelta( sz );
536 
537  // flip pad's layers
539 
540  // flip custom pad shapes
542  }
543 
545 
547 
548  m_PadNumCtrl->SetValue( m_dummyPad->GetName() );
549  m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() );
550 
551  // Set the unit name in dialog:
552  wxStaticText* unitTexts[] =
553  {
561  };
562 
563  for( unsigned ii = 0; ii < DIM( unitTexts ); ++ii )
564  unitTexts[ii]->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
565 
566  // Display current pad parameters units:
569 
572 
575 
578 
579  if( m_dummyPad->GetDelta().x )
580  {
582  m_trapDeltaDirChoice->SetSelection( 0 );
583  }
584  else
585  {
587  m_trapDeltaDirChoice->SetSelection( 1 );
588  }
589 
591 
596 
597  // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
599 
601  m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
602 
603  msg.Printf( wxT( "%f" ), m_dummyPad->GetLocalSolderPasteMarginRatio() * 100.0 );
604 
605  if( m_dummyPad->GetLocalSolderPasteMarginRatio() == 0.0 && msg[0] == '0' )
606  // Sometimes Printf adds a sign if the value is small
607  m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
608  else
609  m_SolderPasteMarginRatioCtrl->SetValue( msg );
610 
611  switch( m_dummyPad->GetZoneConnection() )
612  {
613  default:
615  m_ZoneConnectionChoice->SetSelection( 0 );
616  break;
617 
618  case PAD_ZONE_CONN_FULL:
619  m_ZoneConnectionChoice->SetSelection( 1 );
620  break;
621 
623  m_ZoneConnectionChoice->SetSelection( 2 );
624  break;
625 
626  case PAD_ZONE_CONN_NONE:
627  m_ZoneConnectionChoice->SetSelection( 3 );
628  break;
629  }
630 
632  m_ZoneCustomPadShape->SetSelection( 1 );
633  else
634  m_ZoneCustomPadShape->SetSelection( 0 );
635 
636  if( m_currentPad )
637  {
638  angle = m_currentPad->GetOrientation();
639  MODULE* footprint = m_currentPad->GetParent();
640 
641  if( footprint )
642  angle -= footprint->GetOrientation();
643 
644  if( m_isFlipped )
645  angle = -angle;
646 
647  m_dummyPad->SetOrientation( angle );
648  }
649 
650  angle = m_dummyPad->GetOrientation();
651 
652  NORMALIZE_ANGLE_180( angle ); // ? normalizing is in D_PAD::SetOrientation()
653 
654  // Set layers used by this pad: :
656 
657  // Pad Orient
658  switch( int( angle ) )
659  {
660  case 0:
661  m_PadOrient->SetSelection( 0 );
662  break;
663 
664  case 900:
665  m_PadOrient->SetSelection( 1 );
666  break;
667 
668  case -900:
669  m_PadOrient->SetSelection( 2 );
670  break;
671 
672  case 1800:
673  case -1800:
674  m_PadOrient->SetSelection( 3 );
675  break;
676 
677  default:
678  m_PadOrient->SetSelection( 4 );
679  break;
680  }
681 
682  switch( m_dummyPad->GetShape() )
683  {
684  default:
685  case PAD_SHAPE_CIRCLE:
686  m_PadShape->SetSelection( CHOICE_SHAPE_CIRCLE );
687  break;
688 
689  case PAD_SHAPE_OVAL:
690  m_PadShape->SetSelection( CHOICE_SHAPE_OVAL );
691  break;
692 
693  case PAD_SHAPE_RECT:
694  m_PadShape->SetSelection( CHOICE_SHAPE_RECT );
695  break;
696 
697  case PAD_SHAPE_TRAPEZOID:
698  m_PadShape->SetSelection( CHOICE_SHAPE_TRAPEZOID );
699  break;
700 
701  case PAD_SHAPE_ROUNDRECT:
702  m_PadShape->SetSelection( CHOICE_SHAPE_ROUNDRECT );
703  break;
704 
705  case PAD_SHAPE_CUSTOM:
708  else
710  break;
711  }
712 
714 
715  m_OrientValue = angle / 10.0;
716 
717  // Type of pad selection
718  m_PadType->SetSelection( 0 );
719 
720  for( unsigned ii = 0; ii < DIM( code_type ); ii++ )
721  {
722  if( code_type[ii] == m_dummyPad->GetAttribute() )
723  {
724  m_PadType->SetSelection( ii );
725  break;
726  }
727  }
728 
729  // Enable/disable Pad name,and pad length die
730  // (disable for NPTH pads (mechanical pads)
732 
733  m_PadNumCtrl->Enable( enable );
734  m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
735  m_LengthPadToDieCtrl->Enable( enable );
736 
738  m_DrillShapeCtrl->SetSelection( 0 );
739  else
740  m_DrillShapeCtrl->SetSelection( 1 );
741 
742  // Update some dialog widgets state (Enable/disable options):
743  wxCommandEvent cmd_event;
745  OnDrillShapeSelected( cmd_event );
746  OnPadShapeSelection( cmd_event );
748 
749  // Update basic shapes list
751 }
752 
753 // A small helper function, to display coordinates:
754 static wxString formatCoord( wxPoint aCoord )
755 {
756  return wxString::Format( "(X:%s Y:%s)",
757  CoordinateToString( aCoord.x, true ),
758  CoordinateToString( aCoord.y, true ) );
759 }
760 
762 {
763  m_listCtrlPrimitives->ClearAll();
764 
765  wxListItem itemCol;
766  itemCol.SetImage(-1);
767 
768  for( int ii = 0; ii < 5; ++ii )
769  m_listCtrlPrimitives->InsertColumn(ii, itemCol);
770 
771  wxString bs_info[5];
772 
773  for( unsigned ii = 0; ii < m_primitives.size(); ++ii )
774  {
775  const PAD_CS_PRIMITIVE& primitive = m_primitives[ii];
776 
777  for( unsigned jj = 0; jj < 5; ++jj )
778  bs_info[jj].Empty();
779 
780  bs_info[4] = wxString::Format( _( "width %s" ),
781  CoordinateToString( primitive.m_Thickness, true ) );
782 
783  switch( primitive.m_Shape )
784  {
785  case S_SEGMENT: // usual segment : line with rounded ends
786  bs_info[0] = _( "Segment" );
787  bs_info[1] = _( "from " ) + formatCoord( primitive.m_Start );
788  bs_info[2] = _( "to " ) + formatCoord( primitive.m_End );
789  break;
790 
791  case S_ARC: // Arc with rounded ends
792  bs_info[0] = _( "Arc" );
793  bs_info[1] = _( "center " ) + formatCoord( primitive.m_Start ); // Center
794  bs_info[2] = _( "start " ) + formatCoord( primitive.m_End ); // Start point
795  bs_info[3] = wxString::Format( _( "angle %s" ), FMT_ANGLE( primitive.m_ArcAngle ) );
796  break;
797 
798  case S_CIRCLE: // ring or circle
799  if( primitive.m_Thickness )
800  bs_info[0] = _( "ring" );
801  else
802  bs_info[0] = _( "circle" );
803 
804  bs_info[1] = formatCoord( primitive.m_Start );
805  bs_info[2] = wxString::Format( _( "radius %s" ),
806  CoordinateToString( primitive.m_Radius, true ) );
807  break;
808 
809  case S_POLYGON: // polygon
810  bs_info[0] = "Polygon";
811  bs_info[1] = wxString::Format( _( "corners count %d" ), primitive.m_Poly.size() );
812  break;
813 
814  default:
815  bs_info[0] = "Unknown primitive";
816  break;
817  }
818 
819  long tmp = m_listCtrlPrimitives->InsertItem(ii, bs_info[0]);
820  m_listCtrlPrimitives->SetItemData(tmp, ii);
821 
822  for( int jj = 0, col = 0; jj < 5; ++jj )
823  {
824  m_listCtrlPrimitives->SetItem(tmp, col++, bs_info[jj]);
825  }
826  }
827 
828  // Now columns are filled, ensure correct width of columns
829  for( unsigned ii = 0; ii < 5; ++ii )
830  m_listCtrlPrimitives->SetColumnWidth( ii, wxLIST_AUTOSIZE );
831 }
832 
833 void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
834 {
835  redraw();
836  event.Skip();
837 }
838 
839 
840 void DIALOG_PAD_PROPERTIES::onChangePadMode( wxCommandEvent& event )
841 {
843 
844  if( m_parent->IsGalCanvasActive() )
845  {
847 
848  // fix the pad render mode (filled/not filled)
849  KIGFX::PCB_RENDER_SETTINGS* settings =
850  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
851 
856  }
857 
858  redraw();
859 }
860 
861 
862 void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
863 {
864  bool is_custom = false;
865 
866  switch( m_PadShape->GetSelection() )
867  {
868  case CHOICE_SHAPE_CIRCLE:
869  m_ShapeDelta_Ctrl->Enable( false );
870  m_trapDeltaDirChoice->Enable( false );
871  m_ShapeSize_Y_Ctrl->Enable( false );
872  m_ShapeOffset_X_Ctrl->Enable( false );
873  m_ShapeOffset_Y_Ctrl->Enable( false );
874  break;
875 
876  case CHOICE_SHAPE_OVAL:
877  m_ShapeDelta_Ctrl->Enable( false );
878  m_trapDeltaDirChoice->Enable( false );
879  m_ShapeSize_Y_Ctrl->Enable( true );
880  m_ShapeOffset_X_Ctrl->Enable( true );
881  m_ShapeOffset_Y_Ctrl->Enable( true );
882  break;
883 
884  case CHOICE_SHAPE_RECT:
885  m_ShapeDelta_Ctrl->Enable( false );
886  m_trapDeltaDirChoice->Enable( false );
887  m_ShapeSize_Y_Ctrl->Enable( true );
888  m_ShapeOffset_X_Ctrl->Enable( true );
889  m_ShapeOffset_Y_Ctrl->Enable( true );
890  break;
891 
893  m_ShapeDelta_Ctrl->Enable( true );
894  m_trapDeltaDirChoice->Enable( true );
895  m_ShapeSize_Y_Ctrl->Enable( true );
896  m_ShapeOffset_X_Ctrl->Enable( true );
897  m_ShapeOffset_Y_Ctrl->Enable( true );
898  break;
899 
901  m_ShapeDelta_Ctrl->Enable( false );
902  m_trapDeltaDirChoice->Enable( false );
903  m_ShapeSize_Y_Ctrl->Enable( true );
904  m_ShapeOffset_X_Ctrl->Enable( true );
905  m_ShapeOffset_Y_Ctrl->Enable( true );
906  // Ensure m_tcCornerSizeRatio contains the right value:
907  m_tcCornerSizeRatio->ChangeValue( wxString::Format( "%.1f",
909  break;
910 
911  case CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR: // PAD_SHAPE_CUSTOM, circular anchor
912  case CHOICE_SHAPE_CUSTOM_RECT_ANCHOR: // PAD_SHAPE_CUSTOM, rect anchor
913  is_custom = true;
914  m_ShapeDelta_Ctrl->Enable( false );
915  m_trapDeltaDirChoice->Enable( false );
916  m_ShapeSize_Y_Ctrl->Enable(
917  m_PadShape->GetSelection() == CHOICE_SHAPE_CUSTOM_RECT_ANCHOR );
918  m_ShapeOffset_X_Ctrl->Enable( false );
919  m_ShapeOffset_Y_Ctrl->Enable( false );
920  break;
921  }
922 
923  enablePrimitivePage( is_custom );
924 
925  // A few widgets are enabled only for rounded rect pads:
926  m_tcCornerSizeRatio->Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
927 
928  // PAD_SHAPE_CUSTOM type has constraints for zone connection and thermal shape:
929  // only not connected is allowed to avoid destroying the shape.
930  // Enable/disable options only available for custom shaped pads
931  m_ZoneConnectionChoice->Enable( !is_custom );
932  m_ThermalWidthCtrl->Enable( !is_custom );
933  m_ThermalGapCtrl->Enable( !is_custom );
934 
935  m_sbSizerZonesSettings->Show( !is_custom );
936  m_sbSizerCustomShapedZonesSettings->Show( is_custom );
937 
939 
941  redraw();
942 }
943 
944 
945 void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
946 {
947  if( m_PadType->GetSelection() == 1 || m_PadType->GetSelection() == 2 )
948  {
949  // pad type = SMD or CONN: no hole allowed
950  m_PadDrill_X_Ctrl->Enable( false );
951  m_PadDrill_Y_Ctrl->Enable( false );
952  }
953  else
954  {
955  switch( m_DrillShapeCtrl->GetSelection() )
956  {
957  case 0: //CIRCLE:
958  m_PadDrill_X_Ctrl->Enable( true );
959  m_PadDrill_Y_Ctrl->Enable( false );
960  break;
961 
962  case 1: //OVALE:
963  m_PadDrill_X_Ctrl->Enable( true );
964  m_PadDrill_Y_Ctrl->Enable( true );
965  break;
966  }
967  }
968 
970  redraw();
971 }
972 
973 
974 void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
975 {
976  switch( m_PadOrient->GetSelection() )
977  {
978  case 0:
980  break;
981 
982  case 1:
983  m_dummyPad->SetOrientation( 900 );
984  break;
985 
986  case 2:
987  m_dummyPad->SetOrientation( -900 );
988  break;
989 
990  case 3:
991  m_dummyPad->SetOrientation( 1800 );
992  break;
993 
994  default:
995  break;
996  }
997 
999  m_OrientValidator.TransferToWindow();
1000 
1002  redraw();
1003 }
1004 
1005 
1006 void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
1007 {
1008  unsigned ii = m_PadType->GetSelection();
1009 
1010  if( ii >= DIM( code_type ) ) // catches < 0 also
1011  ii = 0;
1012 
1013  LSET layer_mask = std_pad_layers[ii];
1014  setPadLayersList( layer_mask );
1015 
1016  // Enable/disable drill dialog items:
1017  event.SetId( m_DrillShapeCtrl->GetSelection() );
1018  OnDrillShapeSelected( event );
1019 
1020  if( ii == 0 || ii == DIM( code_type )-1 )
1021  m_DrillShapeCtrl->Enable( true );
1022  else
1023  m_DrillShapeCtrl->Enable( false );
1024 
1025  // Enable/disable Pad name,and pad length die
1026  // (disable for NPTH pads (mechanical pads)
1027  bool enable = ii != 3;
1028  m_PadNumCtrl->Enable( enable );
1029  m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
1030  m_LengthPadToDieCtrl->Enable( enable );
1031 }
1032 
1033 
1035 {
1036  LSET cu_set = layer_mask & LSET::AllCuMask();
1037 
1038  if( cu_set == LSET( F_Cu ) )
1039  m_rbCopperLayersSel->SetSelection( 0 );
1040  else if( cu_set == LSET( B_Cu ) )
1041  m_rbCopperLayersSel->SetSelection( 1 );
1042  else if( cu_set.any() )
1043  m_rbCopperLayersSel->SetSelection( 2 );
1044  else
1045  m_rbCopperLayersSel->SetSelection( 3 );
1046 
1047  m_PadLayerAdhCmp->SetValue( layer_mask[F_Adhes] );
1048  m_PadLayerAdhCu->SetValue( layer_mask[B_Adhes] );
1049 
1050  m_PadLayerPateCmp->SetValue( layer_mask[F_Paste] );
1051  m_PadLayerPateCu->SetValue( layer_mask[B_Paste] );
1052 
1053  m_PadLayerSilkCmp->SetValue( layer_mask[F_SilkS] );
1054  m_PadLayerSilkCu->SetValue( layer_mask[B_SilkS] );
1055 
1056  m_PadLayerMaskCmp->SetValue( layer_mask[F_Mask] );
1057  m_PadLayerMaskCu->SetValue( layer_mask[B_Mask] );
1058 
1059  m_PadLayerECO1->SetValue( layer_mask[Eco1_User] );
1060  m_PadLayerECO2->SetValue( layer_mask[Eco2_User] );
1061 
1062  m_PadLayerDraft->SetValue( layer_mask[Dwgs_User] );
1063 }
1064 
1065 
1066 // Called when select/deselect a layer.
1067 void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
1068 {
1070  redraw();
1071 }
1072 
1073 
1074 // test if all values are acceptable for the pad
1076 {
1077  bool error = transferDataToPad( m_dummyPad );
1078  bool skip_tstoffset = false; // the offset prm is not always tested
1079 
1080  wxArrayString error_msgs;
1081  wxString msg;
1082 
1083  // Test for incorrect values
1084  if( (m_dummyPad->GetSize().x <= 0) ||
1085  ((m_dummyPad->GetSize().y <= 0) && (m_dummyPad->GetShape() != PAD_SHAPE_CIRCLE)) )
1086  {
1087  error_msgs.Add( _( "Pad size must be greater than zero" ) );
1088  }
1089 
1090  if( (m_dummyPad->GetSize().x < m_dummyPad->GetDrillSize().x) ||
1091  (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
1092  {
1093  error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
1094  skip_tstoffset = true; // offset prm will be not tested because if the drill value
1095  // is incorrect the offset prm is always seen as incorrect, even if it is 0
1096  }
1097 
1098  if( m_dummyPad->GetLocalClearance() < 0 )
1099  {
1100  error_msgs.Add( _( "Pad local clearance must be zero or greater than zero" ) );
1101  }
1102 
1103  // Some pads need a negative solder mask clearance (mainly for BGA with small pads)
1104  // However the negative solder mask clearance must not create negative mask size
1105  // Therefore test for minimal acceptable negative value
1106  // Hovewer, a negative value can give strange result with custom shapes, so it is not
1107  // allowed for custom pad shape
1109  {
1111  error_msgs.Add( _( "Pad local solder mask clearance must be zero or greater than zero" ) );
1112  else
1113  {
1114  int min_smClearance = -std::min( m_dummyPad->GetSize().x, m_dummyPad->GetSize().y )/2;
1115 
1116  if( m_dummyPad->GetLocalSolderMaskMargin() <= min_smClearance )
1117  {
1118  error_msgs.Add( wxString::Format(
1119  _( "Pad local solder mask clearance must be greater than %s" ),
1120  StringFromValue( g_UserUnit, min_smClearance, true ) ) );
1121  }
1122  }
1123  }
1124 
1126  {
1127  error_msgs.Add( _( "Pad local solder paste clearance must be zero or less than zero" ) );
1128  }
1129 
1130  LSET padlayers_mask = m_dummyPad->GetLayerSet();
1131 
1132  if( padlayers_mask == 0 )
1133  error_msgs.Add( _( "Error: pad has no layer" ) );
1134 
1135  if( !padlayers_mask[F_Cu] && !padlayers_mask[B_Cu] )
1136  {
1137  if( m_dummyPad->GetDrillSize().x || m_dummyPad->GetDrillSize().y )
1138  {
1139  // Note: he message is shown in an HTML window
1140  msg = _( "Error: the pad is not on a copper layer and has a hole" );
1141 
1143  {
1144  msg += wxT( "<br><br><i>" );
1145  msg += _( "For NPTH pad, set pad size value to pad drill value,"
1146  " if you do not want this pad plotted in gerber files"
1147  );
1148  }
1149 
1150  error_msgs.Add( msg );
1151  }
1152  }
1153 
1154  if( !skip_tstoffset )
1155  {
1156  wxPoint max_size;
1157  max_size.x = std::abs( m_dummyPad->GetOffset().x );
1158  max_size.y = std::abs( m_dummyPad->GetOffset().y );
1159  max_size.x += m_dummyPad->GetDrillSize().x / 2;
1160  max_size.y += m_dummyPad->GetDrillSize().y / 2;
1161 
1162  if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
1163  ( m_dummyPad->GetSize().y / 2 < max_size.y ) )
1164  {
1165  error_msgs.Add( _( "Incorrect value for pad offset" ) );
1166  }
1167  }
1168 
1169  if( error )
1170  {
1171  error_msgs.Add( _( "Too large value for pad delta size" ) );
1172  }
1173 
1174  switch( m_dummyPad->GetAttribute() )
1175  {
1176  case PAD_ATTRIB_HOLE_NOT_PLATED: // Not plated, but through hole, a hole is expected
1177  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
1178  if( m_dummyPad->GetDrillSize().x <= 0 )
1179  error_msgs.Add( _( "Error: Through hole pad: drill diameter set to 0" ) );
1180  break;
1181 
1182  case PAD_ATTRIB_CONN: // Connector pads are smd pads, just they do not have solder paste.
1183  if( padlayers_mask[B_Paste] || padlayers_mask[F_Paste] )
1184  error_msgs.Add( _( "Error: Connector pads are not on the solder paste layer\n"
1185  "Use SMD pads instead" ) );
1186  // Fall trough
1187  case PAD_ATTRIB_SMD: // SMD and Connector pads (One external copper layer only)
1188  {
1189  LSET innerlayers_mask = padlayers_mask & LSET::InternalCuMask();
1190 
1191  if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) ||
1192  innerlayers_mask.count() != 0 )
1193  error_msgs.Add( _( "Error: only one external copper layer allowed for SMD or Connector pads" ) );
1194  }
1195  break;
1196  }
1197 
1198 
1200  {
1201  wxString value = m_tcCornerSizeRatio->GetValue();
1202  double rrRadiusRatioPercent;
1203 
1204  if( !value.ToDouble( &rrRadiusRatioPercent ) )
1205  error_msgs.Add( _( "Incorrect corner size value" ) );
1206  else
1207  {
1208  if( rrRadiusRatioPercent < 0.0 )
1209  error_msgs.Add( _( "Incorrect (negative) corner size value" ) );
1210  else if( rrRadiusRatioPercent > 50.0 )
1211  error_msgs.Add( _( "Corner size value must be smaller than 50%" ) );
1212  }
1213  }
1214 
1216  {
1218  error_msgs.Add(
1219  _( "Incorrect pad shape: the shape must be equivalent to only one polygon" ) );
1220  }
1221 
1222 
1223  if( error_msgs.GetCount() )
1224  {
1225  HTML_MESSAGE_BOX dlg( this, _("Pad setup errors list" ) );
1226  dlg.ListSet( error_msgs );
1227  dlg.ShowModal();
1228  }
1229 
1230  return error_msgs.GetCount() == 0;
1231 }
1232 
1233 
1235 {
1236  if( m_parent->IsGalCanvasActive() )
1237  {
1240 
1241  // The layer used to place primitive items selected when editing custom pad shapes
1242  // we use here a layer never used in a pad:
1243  #define SELECTED_ITEMS_LAYER Dwgs_User
1244 
1246  KIGFX::PCB_RENDER_SETTINGS* settings =
1247  static_cast<KIGFX::PCB_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
1249 
1250  view->Update( m_dummyPad );
1251 
1252  // delete previous items if highlight list
1253  while( m_highligth.size() )
1254  {
1255  delete m_highligth.back(); // the dtor also removes item from view
1256  m_highligth.pop_back();
1257  }
1258 
1259  // highlight selected primitives:
1260  long select = m_listCtrlPrimitives->GetFirstSelected();
1261 
1262  while( select >= 0 )
1263  {
1264  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
1265 
1266  DRAWSEGMENT* dummySegment = new DRAWSEGMENT;
1267  dummySegment->SetLayer( SELECTED_ITEMS_LAYER );
1268  primitive.ExportTo( dummySegment );
1269  dummySegment->Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
1270  dummySegment->Move( m_dummyPad->GetPosition() );
1271 
1272  // Update selected primitive (highligth selected)
1273  switch( primitive.m_Shape )
1274  {
1275  case S_SEGMENT:
1276  case S_ARC:
1277  break;
1278 
1279  case S_CIRCLE: // ring or circle
1280  if( primitive.m_Thickness == 0 ) // filled circle
1281  { // the filled circle option does not exist in a DRAWSEGMENT
1282  // but it is easy to create it with a circle having the
1283  // right radius and outline width
1284  wxPoint end = dummySegment->GetCenter();
1285  end.x += primitive.m_Radius/2;
1286  dummySegment->SetEnd( end );
1287  dummySegment->SetWidth( primitive.m_Radius );
1288  }
1289  break;
1290 
1291  case S_POLYGON:
1292  break;
1293 
1294  default:
1295  delete dummySegment;
1296  dummySegment = nullptr;
1297  break;
1298  }
1299 
1300  if( dummySegment )
1301  {
1302  view->Add( dummySegment );
1303  m_highligth.push_back( dummySegment );
1304  }
1305 
1306  select = m_listCtrlPrimitives->GetNextSelected( select );
1307  }
1308 
1309  BOX2I bbox = m_dummyPad->ViewBBox();
1310 
1311  if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
1312  {
1313  // gives a size to the full drawable area
1314  BOX2I drawbox;
1315  drawbox.Move( m_dummyPad->GetPosition() );
1316  drawbox.Inflate( bbox.GetSize().x*2, bbox.GetSize().y*2 );
1317  view->SetBoundary( drawbox );
1318 
1319  // Autozoom
1320  view->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) );
1321 
1322  // Add a margin
1323  view->SetScale( m_panelShowPadGal->GetView()->GetScale() * 0.7 );
1324 
1327  }
1328  }
1329  else
1330  {
1331  m_panelShowPad->Refresh();
1332  }
1333 }
1334 
1335 
1337 {
1338  if( !wxDialog::TransferDataToWindow() )
1339  return false;
1340 
1341  if( !m_panelGeneral->TransferDataToWindow() )
1342  return false;
1343 
1344  if( !m_localSettingsPanel->TransferDataToWindow() )
1345  return false;
1346 
1347  return true;
1348 }
1349 
1350 
1352 {
1353  BOARD_COMMIT commit( m_parent );
1354 
1355  if( !wxDialog::TransferDataFromWindow() )
1356  return false;
1357 
1358  if( !m_panelGeneral->TransferDataFromWindow() )
1359  return false;
1360 
1361  if( !m_localSettingsPanel->TransferDataFromWindow() )
1362  return false;
1363 
1364  if( !padValuesOK() )
1365  return false;
1366 
1367  bool rastnestIsChanged = false;
1368  int isign = m_isFlipped ? -1 : 1;
1369 
1371  // m_padMaster is a pattern: ensure there is no net for this pad:
1373 
1374  if( !m_currentPad ) // Set current Pad parameters
1375  return true;
1376 
1377  commit.Modify( m_currentPad );
1378 
1379  // redraw the area where the pad was, without pad (delete pad on screen)
1383 
1384  // Update values
1387 
1389  {
1391  rastnestIsChanged = true;
1392  }
1393 
1394  wxSize size;
1395  MODULE* footprint = m_currentPad->GetParent();
1396 
1397  if( footprint )
1398  {
1399  footprint->SetLastEditTime();
1400 
1401  // compute the pos 0 value, i.e. pad position for footprint with orientation = 0
1402  // i.e. relative to footprint origin (footprint position)
1403  wxPoint pt = m_currentPad->GetPosition() - footprint->GetPosition();
1404  RotatePoint( &pt, -footprint->GetOrientation() );
1405  m_currentPad->SetPos0( pt );
1407  + footprint->GetOrientation() );
1408  }
1409 
1411 
1412  size = m_padMaster->GetDelta();
1413  size.y *= isign;
1414  m_currentPad->SetDelta( size );
1415 
1418 
1419  wxPoint offset = m_padMaster->GetOffset();
1420  offset.y *= isign;
1421  m_currentPad->SetOffset( offset );
1422 
1424 
1427 
1428 
1431 
1432  if( m_isFlipped )
1433  {
1436  }
1437 
1439  {
1440  rastnestIsChanged = true;
1442  }
1443 
1444  if( m_isFlipped )
1445  {
1447  }
1448 
1450 
1451  wxString padNetname;
1452 
1453  // For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
1455  padNetname = m_PadNetNameCtrl->GetValue();
1456 
1457  if( m_currentPad->GetNetname() != padNetname )
1458  {
1459  const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname );
1460 
1461  if( !padNetname.IsEmpty() && netinfo == NULL )
1462  {
1463  DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
1464  }
1465  else if( netinfo )
1466  {
1467  rastnestIsChanged = true;
1468  m_currentPad->SetNetCode( netinfo->GetNet() );
1469  }
1470  }
1471 
1479 
1482  else
1484 
1485 
1486  // rounded rect pads with radius ratio = 0 are in fact rect pads.
1487  // So set the right shape (and perhaps issues with a radius = 0)
1490  {
1492  }
1493 
1494  // define the way the clearance area is defined in zones
1496 
1497  if( footprint )
1498  footprint->CalculateBoundingBox();
1499 
1501 
1502  // redraw the area where the pad was
1504 
1505  commit.Push( _( "Modify pad" ) );
1506 
1507  if( rastnestIsChanged ) // The net ratsnest must be recalculated
1508  m_board->m_Status_Pcb = 0;
1509 
1510  return true;
1511 }
1512 
1513 
1515 {
1516  wxString msg;
1517  int x, y;
1518 
1519  if( !Validate() )
1520  return true;
1521  if( !m_panelGeneral->Validate() )
1522  return true;
1523  if( !m_localSettingsPanel->Validate() )
1524  return true;
1525 
1526  m_OrientValidator.TransferFromWindow();
1527 
1528  aPad->SetAttribute( code_type[m_PadType->GetSelection()] );
1529  aPad->SetShape( code_shape[m_PadShape->GetSelection()] );
1532 
1533  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1534  aPad->SetPrimitives( m_primitives );
1535 
1536  // Read pad clearances values:
1542  double dtmp = 0.0;
1543  msg = m_SolderPasteMarginRatioCtrl->GetValue();
1544  msg.ToDouble( &dtmp );
1545 
1546  // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
1547  if( dtmp < -50.0 )
1548  dtmp = -50.0;
1549  // A margin ratio is always <= 0
1550  // 0 means use full pad copper area
1551  if( dtmp > 0.0 )
1552  dtmp = 0.0;
1553 
1554  aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );
1555 
1556  switch( m_ZoneConnectionChoice->GetSelection() )
1557  {
1558  default:
1559  case 0:
1561  break;
1562 
1563  case 1:
1565  break;
1566 
1567  case 2:
1569  break;
1570 
1571  case 3:
1573  break;
1574  }
1575 
1576  // Read pad position:
1579 
1580  aPad->SetPosition( wxPoint( x, y ) );
1581  aPad->SetPos0( wxPoint( x, y ) );
1582 
1583  // Read pad drill:
1586 
1587  if( m_DrillShapeCtrl->GetSelection() == 0 )
1588  {
1590  y = x;
1591  }
1592  else
1594 
1595  aPad->SetDrillSize( wxSize( x, y ) );
1596 
1597  // Read pad shape size:
1600 
1601  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1602  y = x;
1603 
1604  // for custom shped pads, the pad size is the anchor pad size:
1605  if( aPad->GetShape() == PAD_SHAPE_CUSTOM && aPad->GetAnchorPadShape() == PAD_SHAPE_CIRCLE )
1606  y = x;
1607 
1608  aPad->SetSize( wxSize( x, y ) );
1609 
1610  // Read pad length die
1612 
1613  // For a trapezoid, test delta value (be sure delta is not too large for pad size)
1614  // remember DeltaSize.x is the Y size variation
1615  bool error = false;
1616 
1617  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
1618  {
1619  wxSize delta;
1620 
1621  // For a trapezoid, only one of delta.x or delta.y is not 0, depending on
1622  // the direction.
1623  if( m_trapDeltaDirChoice->GetSelection() == 0 )
1624  delta.x = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
1625  else
1626  delta.y = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
1627 
1628  if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
1629  {
1630  delta.x = -aPad->GetSize().y + 2;
1631  error = true;
1632  }
1633 
1634  if( delta.x > 0 && delta.x >= aPad->GetSize().y )
1635  {
1636  delta.x = aPad->GetSize().y - 2;
1637  error = true;
1638  }
1639 
1640  if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
1641  {
1642  delta.y = -aPad->GetSize().x + 2;
1643  error = true;
1644  }
1645 
1646  if( delta.y > 0 && delta.y >= aPad->GetSize().x )
1647  {
1648  delta.y = aPad->GetSize().x - 2;
1649  error = true;
1650  }
1651 
1652  aPad->SetDelta( delta );
1653  }
1654 
1655  // Read pad shape offset:
1658  aPad->SetOffset( wxPoint( x, y ) );
1659 
1660  aPad->SetOrientation( m_OrientValue * 10.0 );
1661  aPad->SetName( m_PadNumCtrl->GetValue() );
1662 
1663  // Check if user has set an existing net name
1664  const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() );
1665 
1666  if( netinfo != NULL )
1667  aPad->SetNetCode( netinfo->GetNet() );
1668  else
1670 
1671  // Clear some values, according to the pad type and shape
1672  switch( aPad->GetShape() )
1673  {
1674  case PAD_SHAPE_CIRCLE:
1675  aPad->SetOffset( wxPoint( 0, 0 ) );
1676  aPad->SetDelta( wxSize( 0, 0 ) );
1677  x = aPad->GetSize().x;
1678  aPad->SetSize( wxSize( x, x ) );
1679  break;
1680 
1681  case PAD_SHAPE_RECT:
1682  aPad->SetDelta( wxSize( 0, 0 ) );
1683  break;
1684 
1685  case PAD_SHAPE_OVAL:
1686  aPad->SetDelta( wxSize( 0, 0 ) );
1687  break;
1688 
1689  case PAD_SHAPE_TRAPEZOID:
1690  break;
1691 
1692  case PAD_SHAPE_ROUNDRECT:
1693  aPad->SetDelta( wxSize( 0, 0 ) );
1694  break;
1695 
1696  case PAD_SHAPE_CUSTOM:
1697  aPad->SetOffset( wxPoint( 0, 0 ) );
1698  aPad->SetDelta( wxSize( 0, 0 ) );
1699 
1700  // The pad custom has a "anchor pad" (a basic shape: round or rect pad)
1701  // that is the minimal area of this pad, and is usefull to ensure a hole
1702  // diameter is acceptable, and is used in Gerber files as flashed area
1703  // reference
1704  if( aPad->GetAnchorPadShape() == PAD_SHAPE_CIRCLE )
1705  {
1706  x = aPad->GetSize().x;
1707  aPad->SetSize( wxSize( x, x ) );
1708  }
1709 
1710  // define the way the clearance area is defined in zones
1711  aPad->SetCustomShapeInZoneOpt( m_ZoneCustomPadShape->GetSelection() == 0 ?
1714 
1715  break;
1716 
1717  default:
1718  ;
1719  }
1720 
1721  switch( aPad->GetAttribute() )
1722  {
1723  case PAD_ATTRIB_STANDARD:
1724  break;
1725 
1726  case PAD_ATTRIB_CONN:
1727  case PAD_ATTRIB_SMD:
1728  // SMD and PAD_ATTRIB_CONN has no hole.
1729  // basically, SMD and PAD_ATTRIB_CONN are same type of pads
1730  // PAD_ATTRIB_CONN has just a default non technical layers that differs from SMD
1731  // and are intended to be used in virtual edge board connectors
1732  // However we can accept a non null offset,
1733  // mainly to allow complex pads build from a set of basic pad shapes
1734  aPad->SetDrillSize( wxSize( 0, 0 ) );
1735  break;
1736 
1738  // Mechanical purpose only:
1739  // no offset, no net name, no pad name allowed
1740  aPad->SetOffset( wxPoint( 0, 0 ) );
1741  aPad->SetName( wxEmptyString );
1743  break;
1744 
1745  default:
1746  DisplayError( NULL, wxT( "Error: unknown pad type" ) );
1747  break;
1748  }
1749 
1750  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
1751  {
1752  wxString value = m_tcCornerSizeRatio->GetValue();
1753  double rrRadiusRatioPercent;
1754 
1755  if( value.ToDouble( &rrRadiusRatioPercent ) )
1756  aPad->SetRoundRectRadiusRatio( rrRadiusRatioPercent / 100.0 );
1757  }
1758 
1759  LSET padLayerMask;
1760 
1761  switch( m_rbCopperLayersSel->GetSelection() )
1762  {
1763  case 0:
1764  padLayerMask.set( F_Cu );
1765  break;
1766 
1767  case 1:
1768  padLayerMask.set( B_Cu );
1769  break;
1770 
1771  case 2:
1772  padLayerMask |= LSET::AllCuMask();
1773  break;
1774 
1775  case 3: // No copper layers
1776  break;
1777  }
1778 
1779  if( m_PadLayerAdhCmp->GetValue() )
1780  padLayerMask.set( F_Adhes );
1781 
1782  if( m_PadLayerAdhCu->GetValue() )
1783  padLayerMask.set( B_Adhes );
1784 
1785  if( m_PadLayerPateCmp->GetValue() )
1786  padLayerMask.set( F_Paste );
1787 
1788  if( m_PadLayerPateCu->GetValue() )
1789  padLayerMask.set( B_Paste );
1790 
1791  if( m_PadLayerSilkCmp->GetValue() )
1792  padLayerMask.set( F_SilkS );
1793 
1794  if( m_PadLayerSilkCu->GetValue() )
1795  padLayerMask.set( B_SilkS );
1796 
1797  if( m_PadLayerMaskCmp->GetValue() )
1798  padLayerMask.set( F_Mask );
1799 
1800  if( m_PadLayerMaskCu->GetValue() )
1801  padLayerMask.set( B_Mask );
1802 
1803  if( m_PadLayerECO1->GetValue() )
1804  padLayerMask.set( Eco1_User );
1805 
1806  if( m_PadLayerECO2->GetValue() )
1807  padLayerMask.set( Eco2_User );
1808 
1809  if( m_PadLayerDraft->GetValue() )
1810  padLayerMask.set( Dwgs_User );
1811 
1812  aPad->SetLayerSet( padLayerMask );
1813 
1814  return error;
1815 }
1816 
1817 
1818 void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
1819 {
1820  if( m_canUpdate )
1821  {
1823  // If the pad size has changed, update the displayed values
1824  // for rounded rect pads
1826 
1827  redraw();
1828  }
1829 }
1830 
1832 {
1833  long select = m_listCtrlPrimitives->GetFirstSelected();
1834 
1835  if( select < 0 )
1836  {
1837  wxMessageBox( _( "No shape selected" ) );
1838  return;
1839  }
1840 
1841  PAD_CS_PRIMITIVE& shape = m_primitives[select];
1842 
1843  if( shape.m_Shape == S_POLYGON )
1844  {
1845  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, &shape );
1846 
1847  if( dlg.ShowModal() != wxID_OK )
1848  return;
1849 
1850  dlg.TransferDataFromWindow();
1851  }
1852 
1853  else
1854  {
1855  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, &shape );
1856 
1857  if( dlg.ShowModal() != wxID_OK )
1858  return;
1859 
1860  dlg.TransferDataFromWindow();
1861  }
1862 
1864 
1865  if( m_canUpdate )
1866  {
1868  redraw();
1869  }
1870 }
1871 
1872 
1874 {
1875  // Called on a double click on the basic shapes list
1876  // To Do: highligth the primitive(s) currently selected.
1877  redraw();
1878 }
1879 
1880 
1882 void DIALOG_PAD_PROPERTIES::onPrimitiveDClick( wxMouseEvent& event )
1883 {
1884  editPrimitive();
1885 }
1886 
1887 
1888 // Called on a click on basic shapes list panel button
1889 void DIALOG_PAD_PROPERTIES::onEditPrimitive( wxCommandEvent& event )
1890 {
1891  editPrimitive();
1892 }
1893 
1894 // Called on a click on basic shapes list panel button
1895 void DIALOG_PAD_PROPERTIES::onDeletePrimitive( wxCommandEvent& event )
1896 {
1897  long select = m_listCtrlPrimitives->GetFirstSelected();
1898 
1899  if( select < 0 )
1900  return;
1901 
1902  // Multiple selections are allowed. get them and remove corresponding shapes
1903  std::vector<long> indexes;
1904  indexes.push_back( select );
1905 
1906  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1907  indexes.push_back( select );
1908 
1909  // Erase all select shapes
1910  for( unsigned ii = indexes.size(); ii > 0; --ii )
1911  m_primitives.erase( m_primitives.begin() + indexes[ii-1] );
1912 
1914 
1915  if( m_canUpdate )
1916  {
1918  redraw();
1919  }
1920 }
1921 
1922 
1923 void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
1924 {
1925  // Ask user for shape type
1926  wxString shapelist[] =
1927  {
1928  _( "Segment" ), _( "Arc" ), _( "ring/circle" ), _( "polygon" )
1929  };
1930 
1931  int type = wxGetSingleChoiceIndex( wxEmptyString, _( "Select shape type:" ),
1932  DIM( shapelist ), shapelist, 0 );
1933 
1934  STROKE_T listtype[] =
1935  {
1937  };
1938 
1939  PAD_CS_PRIMITIVE primitive( listtype[type] );
1940 
1941  if( listtype[type] == S_POLYGON )
1942  {
1943  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, &primitive );
1944 
1945  if( dlg.ShowModal() != wxID_OK )
1946  return;
1947  }
1948  else
1949  {
1950  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, &primitive );
1951 
1952  if( dlg.ShowModal() != wxID_OK )
1953  return;
1954  }
1955 
1956  m_primitives.push_back( primitive );
1957 
1959 
1960  if( m_canUpdate )
1961  {
1963  redraw();
1964  }
1965 }
1966 
1967 
1968 void DIALOG_PAD_PROPERTIES::onImportPrimitives( wxCommandEvent& event )
1969 {
1970  wxMessageBox( "Not yet available" );
1971 }
1972 
1973 
1974 void DIALOG_PAD_PROPERTIES::onGeometryTransform( wxCommandEvent& event )
1975 {
1976  long select = m_listCtrlPrimitives->GetFirstSelected();
1977 
1978  if( select < 0 )
1979  {
1980  wxMessageBox( _( "No shape selected" ) );
1981  return;
1982  }
1983 
1984  // Multiple selections are allowed. Build selected shapes list
1985  std::vector<long> indexes;
1986  indexes.push_back( select );
1987 
1988  std::vector<PAD_CS_PRIMITIVE*> shapeList;
1989  shapeList.push_back( &m_primitives[select] );
1990 
1991  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1992  {
1993  indexes.push_back( select );
1994  shapeList.push_back( &m_primitives[select] );
1995  }
1996 
1997  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, shapeList, false );
1998 
1999  if( dlg.ShowModal() != wxID_OK )
2000  return;
2001 
2002  // Transfert new settings:
2003  dlg.Transform();
2004 
2006 
2007  if( m_canUpdate )
2008  {
2010  redraw();
2011  }
2012 }
2013 
2014 
2015 void DIALOG_PAD_PROPERTIES::onDuplicatePrimitive( wxCommandEvent& event )
2016 {
2017  long select = m_listCtrlPrimitives->GetFirstSelected();
2018 
2019  if( select < 0 )
2020  {
2021  wxMessageBox( _( "No shape selected" ) );
2022  return;
2023  }
2024 
2025  // Multiple selections are allowed. Build selected shapes list
2026  std::vector<long> indexes;
2027  indexes.push_back( select );
2028 
2029  std::vector<PAD_CS_PRIMITIVE*> shapeList;
2030  shapeList.push_back( &m_primitives[select] );
2031 
2032  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
2033  {
2034  indexes.push_back( select );
2035  shapeList.push_back( &m_primitives[select] );
2036  }
2037 
2038  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, shapeList, true );
2039 
2040  if( dlg.ShowModal() != wxID_OK )
2041  return;
2042 
2043  // Transfert new settings:
2044  dlg.Transform( &m_primitives, dlg.GetDuplicateCount() );
2045 
2047 
2048  if( m_canUpdate )
2049  {
2051  redraw();
2052  }
2053 }
void OnInitDialog(wxInitDialogEvent &event) override
bool MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon=NULL, int aCircleToSegmentsCount=32)
Merge all basic shapes, converted to a polygon in one polygon, in m_customShapeAsPolygon.
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:673
void OnValuesChanged(wxCommandEvent &event) override
Called when a dimension has changed.
const Vec & GetOrigin() const
Definition: box2.h:181
void Move(const Vec &aMoveVector)
Function Move moves the rectangle by the aMoveVector.
Definition: box2.h:108
wxString CoordinateToString(int aValue, bool aConvertToMils)
Function CoordinateToString is a helper to convert the integer coordinate aValue to a string in inche...
Definition: base_units.cpp:118
#define DIM(x)
of elements in an array
Definition: macros.h:98
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:218
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
PAD_SHAPE_T GetAnchorPadShape() const
Function GetAnchorPadShape.
Definition: class_pad.h:226
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask, paste, solder layers are swapped internal layers are flipped only if the copper layers count is known.
Definition: lset.cpp:518
DIALOG_PAD_PROPERTIES(PCB_BASE_FRAME *aParent, D_PAD *aPad)
const std::vector< PAD_CS_PRIMITIVE > & GetPrimitives() const
Accessor to the basic shape list.
Definition: class_pad.h:336
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:514
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:99
bool m_Display_padnum
Definition: class_pad.h:75
void FlipPrimitives()
Flip the basic shapes, in custom pads.
Definition: class_pad.cpp:434
virtual void Move(const wxPoint &aMoveVector) override
Function Move move this object.
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:398
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:730
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
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:58
multilayer pads, usually with holes
GAL_TYPE GetBackend() const
Function GetBackend Returns the type of backend currently used by GAL canvas.
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:120
This file is part of the common library.
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:346
const wxPoint GetCenter() const override
Function GetCenter()
static LSET SMDMask()
layer set for a SMD pad on Front layer
Definition: class_pad.cpp:106
void CalculateBoundingBox()
Function CalculateBoundingBox calculates the bounding box in board coordinates.
int GetPadToDieLength() const
Definition: class_pad.h:401
bool transferDataToPad(D_PAD *aPad)
Copy values from dialog field to aPad's members.
Class BOARD to handle a board.
wxString StringFromValue(EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:204
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:511
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
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,.
int GetLocalSolderMaskMargin() const
Definition: class_pad.h:403
MODULE * GetParent() const
Definition: class_pad.h:162
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:61
BOX2< VECTOR2D > BOX2D
Definition: box2.h:469
wxFloatingPointValidator< double > m_OrientValidator
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:510
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
Definition: draw_panel.cpp:312
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
void onChangePadMode(wxCommandEvent &event) override
usual segment : line with rounded ends
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:274
#define FMT_ANGLE
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
void NORMALIZE_ANGLE_180(T &Angle)
Definition: trigo.h:314
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
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:620
void Transform(std::vector< PAD_CS_PRIMITIVE > *aList=NULL, int aDuplicateCount=0)
Apply geometric transform (rotation, move, scale) defined in dialog aDuplicate = 1 ...
void SetLastEditTime(time_t aTime)
Definition: class_module.h:302
const Vec & GetSize() const
Definition: box2.h:177
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:873
const std::vector< wxPoint > GetPolyPoints() const
void onCornerSizePercentChange(wxCommandEvent &event) override
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
#define abs(a)
Definition: auxiliary.h:84
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:247
smd pads, back layer
void SetSketchModeGraphicItems(bool aEnabled)
Turns on/off sketch mode for graphic items (DRAWSEGMENTs, texts).
Definition: pcb_painter.h:134
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:806
static const int delta[8][2]
Definition: solve.cpp:112
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
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
void SetBoundary(const BOX2I &aBoundary)
Function SetBoundary() Sets limits for view area.
Definition: view.h:275
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
const wxPoint & GetArcStart() const
static PAD_SHAPE_T code_shape[]
class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, created by wxFormBuilder ...
Pads are not covered.
Definition: zones.h:57
COLOR4D GetItemColor(int aItemIdx) const
Function GetItemColor.
dialog pad properties editor.
KIGFX::ORIGIN_VIEWITEM * m_axisOrigin
Class PCB_RENDER_SETTINGS Stores PCB specific render settings.
Definition: pcb_painter.h:62
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:253
void OnCancel(wxCommandEvent &event) override
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
Definition: class_pad.cpp:1286
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.
Classes used in Pcbnew, CvPcb and GerbView.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:280
std::vector< wxPoint > m_Poly
is also the start point of the arc
Definition: class_pad.h:102
double GetOrientationDegrees() const
Definition: class_module.h:181
VECTOR2< double > VECTOR2D
Definition: vector2d.h:588
void OnSetLayers(wxCommandEvent &event) override
void SetZoneConnection(ZoneConnection aType)
Definition: class_pad.h:469
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:793
void OnPaintShowPanel(wxPaintEvent &event) override
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:177
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:182
wxStaticBoxSizer * m_sbSizerCustomShapedZonesSettings
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:586
double GetOrientation() const
Definition: class_module.h:180
void SetPos0(const wxPoint &aPos)
Definition: class_pad.h:262
PCB_GENERAL_SETTINGS & Settings()
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
Arcs (with rounded ends)
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit)
Definition: base_units.cpp:484
Helper class to handle a primitive (basic shape: polygon, segment, circle or arc) to build a custom p...
Definition: class_pad.h:91
ZoneConnection GetZoneConnection() const
Definition: class_pad.cpp:650
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:395
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
Class DIALOG_PAD_PROPERTIES_BASE.
void SetDrawAtZero(bool aDrawFlag)
Function SetDrawAtZero() Set the draw at zero flag.
int GetThermalWidth() const
Definition: class_pad.cpp:661
void OnResize(wxSizeEvent &event)
void OnPadShapeSelection(wxCommandEvent &event) override
void PadTypeSelected(wxCommandEvent &event) override
int GetThermalGap() const
Definition: class_pad.cpp:672
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:633
void SetThermalWidth(int aWidth)
Definition: class_pad.h:472
COLOR4D m_HoleColor
Definition: class_pad.h:70
void onPrimitiveDClick(wxMouseEvent &event) override
Called on a double click on the basic shapes list.
const wxSize & GetSize() const
Definition: class_pad.h:269
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
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:217
const wxString & GetName() const
Definition: class_pad.h:190
void OnDrillShapeSelected(wxCommandEvent &event) override
bool IsGalCanvasActive() const
Function IsGalCanvasActive is used to check which canvas (GAL-based or standard) is currently in use...
Definition: draw_frame.h:871
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
bool m_ShowNotPlatedHole
Definition: class_pad.h:80
int GetLocalSolderPasteMargin() const
Definition: class_pad.h:409
void SetPadToDieLength(int aLength)
Definition: class_pad.h:400
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:196
Class HTML_MESSAGE_BOX.
int GetNet() const
Function GetNet.
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:1385
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:380
int ValueFromTextCtrl(const wxTextCtrl &aTextCtr)
Convert the number Value in a string according to the internal units and the selected unit (g_UserUni...
Definition: base_units.cpp:385
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:62
void onImportPrimitives(wxCommandEvent &event) override
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:392
bool IsFlipped() const
Definition: class_pad.cpp:126
void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
void UseColorScheme(const COLORS_DESIGN_SETTINGS *aSettings)
Function UseColorScheme Applies layer color settings.
int GetLocalClearance() const
Definition: class_pad.h:406
COLORS_DESIGN_SETTINGS & Colors()
void SetLocalClearance(int aClearance)
Definition: class_pad.h:407
a dialog to edit basic polygonal shape parameters
double GetLocalSolderPasteMarginRatio() const
Definition: class_pad.h:412
void SetLocalSolderPasteMarginRatio(double aRatio)
Definition: class_pad.h:413
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
bool SwitchBackend(GAL_TYPE aGalType) override
Function SwitchBackend Switches method of rendering graphics.
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...
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:266
bool TransferDataFromWindow() override
Updates the different parameters for the component being edited.
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:394
Class NETINFO_ITEM handles the data for a net.
Definition: class_netinfo.h:69
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:266
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
std::vector< PAD_CS_PRIMITIVE > m_primitives
const wxString & GetNetname() const
Function GetNetname.
double GetRoundRectRadiusRatio() const
has meaning only for rounded rect pads
Definition: class_pad.h:608
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:379
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:404
CUST_PAD_SHAPE_IN_ZONE GetCustomShapeInZoneOpt() const
Definition: class_pad.h:232
static wxString formatCoord(wxPoint aCoord)
void SetSketchMode(int aItemLayer, bool aEnabled)
Function SetSketchMode Turns on/off sketch mode for given item layer.
Definition: pcb_painter.h:114
void GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:621
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:850
const wxPoint GetArcEnd() const
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
const wxSize & GetDelta() const
Definition: class_pad.h:272
Usual pad.
Definition: pad_shapes.h:60
std::vector< DRAWSEGMENT * > m_highligth
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
The common library.
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:217
#define SELECTED_ITEMS_LAYER
bool m_ShowPadFilled
Definition: class_pad.h:77
void SetEnd(const wxPoint &aEnd)
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:401
double GetScale() const
Function GetScale()
Definition: view.h:265
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:281
bool padValuesOK()
test if all values are acceptable for the pad
COLOR4D m_Color
Definition: class_pad.h:68
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Function GetGalCanvas returns a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:879
void SetLocalSolderPasteMargin(int aMargin)
Definition: class_pad.h:410
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
Definition: class_pad.cpp:113
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:242
void InstallPadOptionsFrame(D_PAD *pad)
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:312
bool IsType(FRAME_T aType) const
Definition: wxstruct.h:227
Module description (excepted pads)
Definition: colors.h:45
Class VIEW.
Definition: view.h:58
bool m_Display_netname
Definition: class_pad.h:76
const wxPoint GetPosition() const override
Definition: class_pad.h:220
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
void SetOffset(const wxPoint &aOffset)
Definition: class_pad.h:277
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:74
void SetThermalGap(int aGap)
Definition: class_pad.h:475
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
const wxPoint GetPosition() const override
Definition: class_module.h:175
Use thermal relief for pads.
Definition: zones.h:58
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:199
void StopDrawing()
Function StopDrawing() Prevents the GAL canvas from further drawing till it is recreated or StartDraw...
const wxPoint & GetOffset() const
Definition: class_pad.h:278
double m_ArcAngle
radius of a circle
Definition: class_pad.h:99
a dialog to edit basics shapes parameters.
#define DO_NOT_DRAW
Used to disable draw function.
Definition: base_struct.h:139
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
void SetDelta(const wxSize &aSize)
Definition: class_pad.h:271
#define min(a, b)
Definition: auxiliary.h:85
pads are covered by copper
Definition: zones.h:59
int m_Status_Pcb
Flags used in ratsnest calculation and update.
Definition: class_board.h:237
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:894
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void SetWidth(int aWidth)