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) 2017 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-2017 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>
35 #include <trigo.h>
36 #include <class_drawpanel.h>
37 #include <confirm.h>
38 #include <pcbnew.h>
39 #include <wxBasePcbFrame.h>
40 #include <base_units.h>
41 #include <unit_format.h>
42 #include <board_commit.h>
43 
44 #include <class_board.h>
45 #include <class_module.h>
46 
47 #include <dialog_pad_properties.h>
48 #include <html_messagebox.h>
49 
50 
51 // list of pad shapes, ordered like the pad shape wxChoice in dialog.
52 static PAD_SHAPE_T code_shape[] = {
58  PAD_SHAPE_CUSTOM, // choice = CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR
59  PAD_SHAPE_CUSTOM // choice = PAD_SHAPE_CUSTOM_RECT_ANCHOR
60 };
61 
62 // the ordered index of the pad shape wxChoice in dialog.
63 // keep it consistent with code_shape[] and dialog strings
72 };
73 
74 
75 
76 static PAD_ATTR_T code_type[] = {
81 };
82 
83 
84 // Default mask layers setup for pads according to the pad type
85 static const LSET std_pad_layers[] = {
86  // PAD_ATTRIB_STANDARD:
88 
89  // PAD_ATTRIB_SMD:
91 
92  // PAD_ATTRIB_CONN:
94 
95  // PAD_ATTRIB_HOLE_NOT_PLATED:
97 };
98 
99 
101 {
102  DIALOG_PAD_PROPERTIES dlg( this, aPad );
103  dlg.ShowModal();
104 }
105 
106 
108  DIALOG_PAD_PROPERTIES_BASE( aParent ),
109  m_OrientValidator( 1, &m_OrientValue )
110 {
111  m_canUpdate = false;
112  m_parent = aParent;
113  m_currentPad = aPad; // aPad can be NULL, if the dialog is called
114  // from the footprint editor to set default pad setup
115 
117 
118  m_OrientValidator.SetRange( -360.0, 360.0 );
119  m_PadOrientCtrl->SetValidator( m_OrientValidator );
120  m_OrientValidator.SetWindow( m_PadOrientCtrl );
121 
123  m_dummyPad = new D_PAD( (MODULE*) NULL );
124 
125  if( aPad )
126  *m_dummyPad = *aPad;
127  else // We are editing a "master" pad, i.e. a template to create new pads
129 
130  initValues();
131 
132  // Usually, TransferDataToWindow is called by OnInitDialog
133  // calling it here fixes all widgets sizes, and FinishDialogSettings can
134  // safely fix minsizes
136 
137  // Initialize canvas to be able to display the dummy pad:
138  prepareCanvas();
139 
140  m_sdbSizerOK->SetDefault();
141  m_canUpdate = true;
142 
143  // Now all widgets have the size fixed, call FinishDialogSettings
145 }
146 
147 
148 void DIALOG_PAD_PROPERTIES::OnInitDialog( wxInitDialogEvent& event )
149 {
150  m_PadNumCtrl->SetFocus();
151  m_PadNumCtrl->SetSelection( -1, -1 );
152 }
153 
154 
156 {
157  // Enable or disable the widgets in page managing custom shape primitives
158  m_listCtrlPrimitives->Enable( aEnable );
159  m_buttonDel->Enable( aEnable );
160  m_buttonEditShape->Enable( aEnable );
161  m_buttonAddShape->Enable( aEnable );
162  m_buttonDup->Enable( aEnable );
163  m_buttonGeometry->Enable( aEnable );
164  m_buttonImport->Enable( aEnable );
165 }
166 
167 
169 {
170  // Initialize the canvases (legacy or gal) to display the pad
171  // Enable the suitable canvas and make some inits
172 
173  // Show the X and Y axis. It is usefull because pad shape can have an offset
174  // or be a complex shape.
175  KIGFX::COLOR4D axis_color = LIGHTBLUE;
176 
177  m_axisOrigin = new KIGFX::ORIGIN_VIEWITEM( axis_color,
179  Millimeter2iu( 0.2 ),
181  m_axisOrigin->SetDrawAtZero( true );
182 
183  if( m_parent->IsGalCanvasActive() )
184  {
187  m_panelShowPadGal->Show();
188  m_panelShowPad->Hide();
191 
193  Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_PAD_PROPERTIES::OnResize ) );
194  }
195  else
196  {
197  m_panelShowPad->Show();
198  m_panelShowPadGal->Hide();
199  }
200 }
201 
202 
203 void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
204 {
205  wxPaintDC dc( m_panelShowPad );
206  PAD_DRAWINFO drawInfo;
207 
209 
210  if( m_dummyPad->GetLayerSet()[F_Cu] )
211  {
213  }
214 
215  if( m_dummyPad->GetLayerSet()[B_Cu] )
216  {
217  color = color.LegacyMix( m_parent->Settings().Colors().GetItemColor( LAYER_PAD_BK ) );
218  }
219 
220  // What could happen: the pad color is *actually* black, or no
221  // copper was selected
222  if( color == BLACK )
223  color = LIGHTGRAY;
224 
225  drawInfo.m_Color = color;
226  drawInfo.m_HoleColor = DARKGRAY;
227  drawInfo.m_Offset = m_dummyPad->GetPosition();
228  drawInfo.m_Display_padnum = true;
229  drawInfo.m_Display_netname = true;
230 
232  drawInfo.m_ShowNotPlatedHole = true;
233 
234  // Shows the local pad clearance
236 
237  wxSize dc_size = dc.GetSize();
238  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
239 
240  // Calculate a suitable scale to fit the available draw area
241  int dim = m_dummyPad->GetBoundingRadius() *2;
242 
243  // Invalid x size. User could enter zero, or have deleted all text prior to
244  // entering a new value; this is also treated as zero. If dim is left at
245  // zero, the drawing scale is zero and we get a crash.
246  if( dim == 0 )
247  {
248  // If drill size has been set, use that. Otherwise default to 1mm.
249  dim = m_dummyPad->GetDrillSize().x;
250  if( dim == 0 )
251  dim = Millimeter2iu( 1.0 );
252  }
253 
254  if( m_dummyPad->GetLocalClearance() > 0 )
255  dim += m_dummyPad->GetLocalClearance() * 2;
256 
257  double scale = (double) dc_size.x / dim;
258 
259  // If the pad is a circle, use the x size here instead.
260  int ysize;
261 
263  ysize = m_dummyPad->GetSize().x;
264  else
265  ysize = m_dummyPad->GetSize().y;
266 
267  dim = ysize + std::abs( m_dummyPad->GetDelta().x );
268 
269  // Invalid y size. See note about x size above.
270  if( dim == 0 )
271  {
272  dim = m_dummyPad->GetDrillSize().y;
273  if( dim == 0 )
274  dim = Millimeter2iu( 0.1 );
275  }
276 
277  if( m_dummyPad->GetLocalClearance() > 0 )
278  dim += m_dummyPad->GetLocalClearance() * 2;
279 
280  double altscale = (double) dc_size.y / dim;
281  scale = std::min( scale, altscale );
282 
283  // Give a margin
284  scale *= 0.7;
285  dc.SetUserScale( scale, scale );
286 
287  GRResetPenAndBrush( &dc );
288  m_dummyPad->DrawShape( NULL, &dc, drawInfo );
289 
290  // draw selected primitives:
291  COLOR4D hcolor = CYAN;
292  long select = m_listCtrlPrimitives->GetFirstSelected();
293  wxPoint start, end, center;
294 
295  while( select >= 0 )
296  {
297  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
298 
299  // The best way to calculate parameters to draw a primitive is to
300  // use a dummy DRAWSEGMENT and use its methods
301  // Note: in legacy canvas, the pad has the 0,0 position
302  DRAWSEGMENT dummySegment;
303  primitive.ExportTo( &dummySegment );
304  dummySegment.Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
305 
306  switch( primitive.m_Shape )
307  {
308  case S_SEGMENT: // usual segment : line with rounded ends
309  GRFilledSegment( NULL, &dc, dummySegment.GetStart(), dummySegment.GetEnd(),
310  primitive.m_Thickness, hcolor );
311  break;
312 
313  case S_ARC: // Arc with rounded ends
314  GRArc1( NULL, &dc, dummySegment.GetArcEnd(), dummySegment.GetArcStart(),
315  dummySegment.GetCenter(), primitive.m_Thickness, hcolor );
316  break;
317 
318  case S_CIRCLE: // ring or circle
319  if( primitive.m_Thickness )
320  {
321  GRCircle( NULL, &dc, dummySegment.GetCenter(), primitive.m_Radius,
322  primitive.m_Thickness, hcolor );
323  }
324  else
325  {
326  GRFilledCircle( NULL, &dc, dummySegment.GetCenter(),
327  primitive.m_Radius, hcolor );
328  }
329  break;
330 
331  case S_POLYGON: // polygon
332  {
333  std::vector<wxPoint> poly = dummySegment.GetPolyPoints();
334  GRClosedPoly( NULL, &dc, poly.size(), &poly[0], /* filled */ true,
335  primitive.m_Thickness, hcolor, hcolor );
336  }
337  break;
338 
339  default:
340  break;
341  }
342 
343  select = m_listCtrlPrimitives->GetNextSelected( select );
344  }
345 
346  // Draw X and Y axis. This is particularly useful to show the
347  // reference position of pads with offset and no hole, or custom pad shapes
348  const int linethickness = 0;
349  GRLine( NULL, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0,
350  linethickness, LIGHTBLUE ); // X axis
351  GRLine( NULL, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ),
352  linethickness, LIGHTBLUE ); // Y axis
353 
354  event.Skip();
355 }
356 
357 
359 {
360  // Note:
361  // To avoid generating a wxEVT_TEXT event from m_tcCornerSizeRatio
362  // we use ChangeValue instead of SetValue, to set the displayed string
364  {
365  m_tcCornerSizeRatio->ChangeValue( wxString::Format( "%.1f",
369  }
370  else if( m_dummyPad->GetShape() == PAD_SHAPE_RECT )
371  {
372  m_tcCornerSizeRatio->ChangeValue( "0" );
373  m_staticTextCornerRadiusValue->SetLabel( "0" );
374  }
375  else
376  {
377  m_tcCornerSizeRatio->ChangeValue( wxEmptyString );
378  m_staticTextCornerRadiusValue->SetLabel( wxEmptyString );
379  }
380 }
381 
382 
384 {
386  return;
387 
388  wxString value = m_tcCornerSizeRatio->GetValue();
389  double rrRadiusRatioPercent;
390 
391  if( value.ToDouble( &rrRadiusRatioPercent ) )
392  {
393  // Clamp rrRadiusRatioPercent to acceptable value (0.0 to 50.0)
394  if( rrRadiusRatioPercent < 0.0 )
395  {
396  rrRadiusRatioPercent = 0.0;
397  m_tcCornerSizeRatio->ChangeValue( "0.0" );
398  }
399 
400  if( rrRadiusRatioPercent > 50.0 )
401  {
402  rrRadiusRatioPercent = 0.5;
403  m_tcCornerSizeRatio->ChangeValue( "50.0" );
404  }
405 
409  redraw();
410  }
411 }
412 
413 
415 {
416  wxString msg;
417  double angle;
418 
419  // Disable pad net name wxTextCtrl if the caller is the footprint editor
420  // because nets are living only in the board managed by the board editor
422 
423 
424  // Setup layers names from board
425  // Should be made first, before calling m_rbCopperLayersSel->SetSelection()
426  m_rbCopperLayersSel->SetString( 0, m_board->GetLayerName( F_Cu ) );
427  m_rbCopperLayersSel->SetString( 1, m_board->GetLayerName( B_Cu ) );
428 
429  m_PadLayerAdhCmp->SetLabel( m_board->GetLayerName( F_Adhes ) );
430  m_PadLayerAdhCu->SetLabel( m_board->GetLayerName( B_Adhes ) );
432  m_PadLayerPateCu->SetLabel( m_board->GetLayerName( B_Paste ) );
434  m_PadLayerSilkCu->SetLabel( m_board->GetLayerName( B_SilkS ) );
435  m_PadLayerMaskCmp->SetLabel( m_board->GetLayerName( F_Mask ) );
436  m_PadLayerMaskCu->SetLabel( m_board->GetLayerName( B_Mask ) );
437  m_PadLayerECO1->SetLabel( m_board->GetLayerName( Eco1_User ) );
438  m_PadLayerECO2->SetLabel( m_board->GetLayerName( Eco2_User ) );
440 
441  m_isFlipped = false;
442 
443  if( m_currentPad )
444  {
446 
447  if( m_isFlipped )
448  m_staticModuleSideValue->SetLabel( _( "Back side (footprint is mirrored)" ) );
449 
450  // Diplay footprint rotation ( angles are in 0.1 degree )
451  MODULE* footprint = m_currentPad->GetParent();
452 
453  if( footprint )
454  msg.Printf( "%.1f", footprint->GetOrientationDegrees() );
455  else
456  msg = _("No footprint" );
457 
458  m_staticModuleRotValue->SetLabel( msg );
459  }
460 
461  if( m_isFlipped )
462  {
463  wxPoint pt = m_dummyPad->GetOffset();
464  pt.y = -pt.y;
465  m_dummyPad->SetOffset( pt );
466 
467  wxSize sz = m_dummyPad->GetDelta();
468  sz.y = -sz.y;
469  m_dummyPad->SetDelta( sz );
470 
471  // flip pad's layers
473 
474  // flip custom pad shapes
476  }
477 
479 
481 
482  m_PadNumCtrl->SetValue( m_dummyPad->GetName() );
483  m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() );
484 
485  // Set the unit name in dialog:
486  wxStaticText* unitTexts[] =
487  {
495  };
496 
497  for( unsigned ii = 0; ii < DIM( unitTexts ); ++ii )
498  unitTexts[ii]->SetLabel( GetAbbreviatedUnitsLabel( g_UserUnit ) );
499 
500  // Display current pad parameters units:
503 
506 
509 
512 
513  if( m_dummyPad->GetDelta().x )
514  {
516  m_trapDeltaDirChoice->SetSelection( 0 );
517  }
518  else
519  {
521  m_trapDeltaDirChoice->SetSelection( 1 );
522  }
523 
525 
530 
531  // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0
533 
535  m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() );
536 
537  msg.Printf( wxT( "%f" ), m_dummyPad->GetLocalSolderPasteMarginRatio() * 100.0 );
538 
539  if( m_dummyPad->GetLocalSolderPasteMarginRatio() == 0.0 && msg[0] == '0' )
540  // Sometimes Printf adds a sign if the value is small
541  m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg );
542  else
543  m_SolderPasteMarginRatioCtrl->SetValue( msg );
544 
545  switch( m_dummyPad->GetZoneConnection() )
546  {
547  default:
549  m_ZoneConnectionChoice->SetSelection( 0 );
550  break;
551 
552  case PAD_ZONE_CONN_FULL:
553  m_ZoneConnectionChoice->SetSelection( 1 );
554  break;
555 
557  m_ZoneConnectionChoice->SetSelection( 2 );
558  break;
559 
560  case PAD_ZONE_CONN_NONE:
561  m_ZoneConnectionChoice->SetSelection( 3 );
562  break;
563  }
564 
566  m_ZoneCustomPadShape->SetSelection( 1 );
567  else
568  m_ZoneCustomPadShape->SetSelection( 0 );
569 
570  if( m_currentPad )
571  {
572  angle = m_currentPad->GetOrientation();
573  MODULE* footprint = m_currentPad->GetParent();
574 
575  if( footprint )
576  angle -= footprint->GetOrientation();
577 
578  if( m_isFlipped )
579  angle = -angle;
580 
581  m_dummyPad->SetOrientation( angle );
582  }
583 
584  angle = m_dummyPad->GetOrientation();
585 
586  NORMALIZE_ANGLE_180( angle ); // ? normalizing is in D_PAD::SetOrientation()
587 
588  // Set layers used by this pad: :
590 
591  // Pad Orient
592  switch( int( angle ) )
593  {
594  case 0:
595  m_PadOrient->SetSelection( 0 );
596  break;
597 
598  case 900:
599  m_PadOrient->SetSelection( 1 );
600  break;
601 
602  case -900:
603  m_PadOrient->SetSelection( 2 );
604  break;
605 
606  case 1800:
607  case -1800:
608  m_PadOrient->SetSelection( 3 );
609  break;
610 
611  default:
612  m_PadOrient->SetSelection( 4 );
613  break;
614  }
615 
616  switch( m_dummyPad->GetShape() )
617  {
618  default:
619  case PAD_SHAPE_CIRCLE:
620  m_PadShape->SetSelection( CHOICE_SHAPE_CIRCLE );
621  break;
622 
623  case PAD_SHAPE_OVAL:
624  m_PadShape->SetSelection( CHOICE_SHAPE_OVAL );
625  break;
626 
627  case PAD_SHAPE_RECT:
628  m_PadShape->SetSelection( CHOICE_SHAPE_RECT );
629  break;
630 
631  case PAD_SHAPE_TRAPEZOID:
632  m_PadShape->SetSelection( CHOICE_SHAPE_TRAPEZOID );
633  break;
634 
635  case PAD_SHAPE_ROUNDRECT:
636  m_PadShape->SetSelection( CHOICE_SHAPE_ROUNDRECT );
637  break;
638 
639  case PAD_SHAPE_CUSTOM:
642  else
644  break;
645  }
646 
648 
649  m_OrientValue = angle / 10.0;
650 
651  // Type of pad selection
652  m_PadType->SetSelection( 0 );
653 
654  for( unsigned ii = 0; ii < DIM( code_type ); ii++ )
655  {
656  if( code_type[ii] == m_dummyPad->GetAttribute() )
657  {
658  m_PadType->SetSelection( ii );
659  break;
660  }
661  }
662 
663  // Enable/disable Pad name,and pad length die
664  // (disable for NPTH pads (mechanical pads)
666 
667  m_PadNumCtrl->Enable( enable );
668  m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
669  m_LengthPadToDieCtrl->Enable( enable );
670 
672  m_DrillShapeCtrl->SetSelection( 0 );
673  else
674  m_DrillShapeCtrl->SetSelection( 1 );
675 
676  // Update some dialog widgets state (Enable/disable options):
677  wxCommandEvent cmd_event;
679  OnDrillShapeSelected( cmd_event );
680  OnPadShapeSelection( cmd_event );
682 
683  // Update basic shapes list
685 }
686 
687 // A small helper function, to display coordinates:
688 static wxString formatCoord( wxPoint aCoord )
689 {
690  return wxString::Format( "(X:%s Y:%s)",
691  CoordinateToString( aCoord.x, true ),
692  CoordinateToString( aCoord.y, true ) );
693 }
694 
696 {
697  m_listCtrlPrimitives->ClearAll();
698 
699  wxListItem itemCol;
700  itemCol.SetImage(-1);
701 
702  for( int ii = 0; ii < 5; ++ii )
703  m_listCtrlPrimitives->InsertColumn(ii, itemCol);
704 
705  wxString bs_info[5];
706 
707  for( unsigned ii = 0; ii < m_primitives.size(); ++ii )
708  {
709  const PAD_CS_PRIMITIVE& primitive = m_primitives[ii];
710 
711  for( unsigned jj = 0; jj < 5; ++jj )
712  bs_info[jj].Empty();
713 
714  bs_info[4] = wxString::Format( _( "width %s" ),
715  CoordinateToString( primitive.m_Thickness, true ) );
716 
717  switch( primitive.m_Shape )
718  {
719  case S_SEGMENT: // usual segment : line with rounded ends
720  bs_info[0] = _( "Segment" );
721  bs_info[1] = _( "from " ) + formatCoord( primitive.m_Start );
722  bs_info[2] = _( "to " ) + formatCoord( primitive.m_End );
723  break;
724 
725  case S_ARC: // Arc with rounded ends
726  bs_info[0] = _( "Arc" );
727  bs_info[1] = _( "center " ) + formatCoord( primitive.m_Start ); // Center
728  bs_info[2] = _( "start " ) + formatCoord( primitive.m_End ); // Start point
729  bs_info[3] = wxString::Format( _( "angle %s" ), FMT_ANGLE( primitive.m_ArcAngle ) );
730  break;
731 
732  case S_CIRCLE: // ring or circle
733  if( primitive.m_Thickness )
734  bs_info[0] = _( "ring" );
735  else
736  bs_info[0] = _( "circle" );
737 
738  bs_info[1] = formatCoord( primitive.m_Start );
739  bs_info[2] = wxString::Format( _( "radius %s" ),
740  CoordinateToString( primitive.m_Radius, true ) );
741  break;
742 
743  case S_POLYGON: // polygon
744  bs_info[0] = "Polygon";
745  bs_info[1] = wxString::Format( _( "corners count %d" ), primitive.m_Poly.size() );
746  break;
747 
748  default:
749  bs_info[0] = "Unknown primitive";
750  break;
751  }
752 
753  long tmp = m_listCtrlPrimitives->InsertItem(ii, bs_info[0]);
754  m_listCtrlPrimitives->SetItemData(tmp, ii);
755 
756  for( int jj = 0, col = 0; jj < 5; ++jj )
757  {
758  m_listCtrlPrimitives->SetItem(tmp, col++, bs_info[jj]);
759  }
760  }
761 
762  // Now columns are filled, ensure correct width of columns
763  for( unsigned ii = 0; ii < 5; ++ii )
764  m_listCtrlPrimitives->SetColumnWidth( ii, wxLIST_AUTOSIZE );
765 }
766 
767 void DIALOG_PAD_PROPERTIES::OnResize( wxSizeEvent& event )
768 {
769  redraw();
770  event.Skip();
771 }
772 
773 
774 void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event )
775 {
776  bool is_custom = false;
777 
778  switch( m_PadShape->GetSelection() )
779  {
780  case CHOICE_SHAPE_CIRCLE:
781  m_ShapeDelta_Ctrl->Enable( false );
782  m_trapDeltaDirChoice->Enable( false );
783  m_ShapeSize_Y_Ctrl->Enable( false );
784  m_ShapeOffset_X_Ctrl->Enable( false );
785  m_ShapeOffset_Y_Ctrl->Enable( false );
786  break;
787 
788  case CHOICE_SHAPE_OVAL:
789  m_ShapeDelta_Ctrl->Enable( false );
790  m_trapDeltaDirChoice->Enable( false );
791  m_ShapeSize_Y_Ctrl->Enable( true );
792  m_ShapeOffset_X_Ctrl->Enable( true );
793  m_ShapeOffset_Y_Ctrl->Enable( true );
794  break;
795 
796  case CHOICE_SHAPE_RECT:
797  m_ShapeDelta_Ctrl->Enable( false );
798  m_trapDeltaDirChoice->Enable( false );
799  m_ShapeSize_Y_Ctrl->Enable( true );
800  m_ShapeOffset_X_Ctrl->Enable( true );
801  m_ShapeOffset_Y_Ctrl->Enable( true );
802  break;
803 
805  m_ShapeDelta_Ctrl->Enable( true );
806  m_trapDeltaDirChoice->Enable( true );
807  m_ShapeSize_Y_Ctrl->Enable( true );
808  m_ShapeOffset_X_Ctrl->Enable( true );
809  m_ShapeOffset_Y_Ctrl->Enable( true );
810  break;
811 
813  m_ShapeDelta_Ctrl->Enable( false );
814  m_trapDeltaDirChoice->Enable( false );
815  m_ShapeSize_Y_Ctrl->Enable( true );
816  m_ShapeOffset_X_Ctrl->Enable( true );
817  m_ShapeOffset_Y_Ctrl->Enable( true );
818  // Ensure m_tcCornerSizeRatio contains the right value:
819  m_tcCornerSizeRatio->ChangeValue( wxString::Format( "%.1f",
821  break;
822 
823  case CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR: // PAD_SHAPE_CUSTOM, circular anchor
824  case CHOICE_SHAPE_CUSTOM_RECT_ANCHOR: // PAD_SHAPE_CUSTOM, rect anchor
825  is_custom = true;
826  m_ShapeDelta_Ctrl->Enable( false );
827  m_trapDeltaDirChoice->Enable( false );
828  m_ShapeSize_Y_Ctrl->Enable(
829  m_PadShape->GetSelection() == CHOICE_SHAPE_CUSTOM_RECT_ANCHOR );
830  m_ShapeOffset_X_Ctrl->Enable( false );
831  m_ShapeOffset_Y_Ctrl->Enable( false );
832  break;
833  }
834 
835  enablePrimitivePage( is_custom );
836 
837  // A few widgets are enabled only for rounded rect pads:
838  m_tcCornerSizeRatio->Enable( m_PadShape->GetSelection() == CHOICE_SHAPE_ROUNDRECT );
839 
840  // PAD_SHAPE_CUSTOM type has constraints for zone connection and thermal shape:
841  // only not connected is allowed to avoid destroying the shape.
842  // Enable/disable options
843  m_ZoneConnectionChoice->Enable( !is_custom );
844  m_ThermalWidthCtrl->Enable( !is_custom );
845  m_ThermalGapCtrl->Enable( !is_custom );
846  m_ZoneCustomPadShape->Enable( is_custom );
847 
849 
851  redraw();
852 }
853 
854 
855 void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event )
856 {
857  if( m_PadType->GetSelection() == 1 || m_PadType->GetSelection() == 2 )
858  {
859  // pad type = SMD or CONN: no hole allowed
860  m_PadDrill_X_Ctrl->Enable( false );
861  m_PadDrill_Y_Ctrl->Enable( false );
862  }
863  else
864  {
865  switch( m_DrillShapeCtrl->GetSelection() )
866  {
867  case 0: //CIRCLE:
868  m_PadDrill_X_Ctrl->Enable( true );
869  m_PadDrill_Y_Ctrl->Enable( false );
870  break;
871 
872  case 1: //OVALE:
873  m_PadDrill_X_Ctrl->Enable( true );
874  m_PadDrill_Y_Ctrl->Enable( true );
875  break;
876  }
877  }
878 
880  redraw();
881 }
882 
883 
884 void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event )
885 {
886  switch( m_PadOrient->GetSelection() )
887  {
888  case 0:
890  break;
891 
892  case 1:
893  m_dummyPad->SetOrientation( 900 );
894  break;
895 
896  case 2:
897  m_dummyPad->SetOrientation( -900 );
898  break;
899 
900  case 3:
901  m_dummyPad->SetOrientation( 1800 );
902  break;
903 
904  default:
905  break;
906  }
907 
909  m_OrientValidator.TransferToWindow();
910 
912  redraw();
913 }
914 
915 
916 void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
917 {
918  unsigned ii = m_PadType->GetSelection();
919 
920  if( ii >= DIM( code_type ) ) // catches < 0 also
921  ii = 0;
922 
923  LSET layer_mask = std_pad_layers[ii];
924  setPadLayersList( layer_mask );
925 
926  // Enable/disable drill dialog items:
927  event.SetId( m_DrillShapeCtrl->GetSelection() );
928  OnDrillShapeSelected( event );
929 
930  if( ii == 0 || ii == DIM( code_type )-1 )
931  m_DrillShapeCtrl->Enable( true );
932  else
933  m_DrillShapeCtrl->Enable( false );
934 
935  // Enable/disable Pad name,and pad length die
936  // (disable for NPTH pads (mechanical pads)
937  bool enable = ii != 3;
938  m_PadNumCtrl->Enable( enable );
939  m_PadNetNameCtrl->Enable( m_canEditNetName && enable && m_currentPad != NULL );
940  m_LengthPadToDieCtrl->Enable( enable );
941 }
942 
943 
945 {
946  LSET cu_set = layer_mask & LSET::AllCuMask();
947 
948  if( cu_set == LSET( F_Cu ) )
949  m_rbCopperLayersSel->SetSelection( 0 );
950  else if( cu_set == LSET( B_Cu ) )
951  m_rbCopperLayersSel->SetSelection( 1 );
952  else if( cu_set.any() )
953  m_rbCopperLayersSel->SetSelection( 2 );
954  else
955  m_rbCopperLayersSel->SetSelection( 3 );
956 
957  m_PadLayerAdhCmp->SetValue( layer_mask[F_Adhes] );
958  m_PadLayerAdhCu->SetValue( layer_mask[B_Adhes] );
959 
960  m_PadLayerPateCmp->SetValue( layer_mask[F_Paste] );
961  m_PadLayerPateCu->SetValue( layer_mask[B_Paste] );
962 
963  m_PadLayerSilkCmp->SetValue( layer_mask[F_SilkS] );
964  m_PadLayerSilkCu->SetValue( layer_mask[B_SilkS] );
965 
966  m_PadLayerMaskCmp->SetValue( layer_mask[F_Mask] );
967  m_PadLayerMaskCu->SetValue( layer_mask[B_Mask] );
968 
969  m_PadLayerECO1->SetValue( layer_mask[Eco1_User] );
970  m_PadLayerECO2->SetValue( layer_mask[Eco2_User] );
971 
972  m_PadLayerDraft->SetValue( layer_mask[Dwgs_User] );
973 }
974 
975 
976 // Called when select/deselect a layer.
977 void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
978 {
980  redraw();
981 }
982 
983 
984 // test if all values are acceptable for the pad
986 {
987  bool error = transferDataToPad( m_dummyPad );
988  bool skip_tstoffset = false; // the offset prm is not always tested
989 
990  wxArrayString error_msgs;
991  wxString msg;
992 
993  // Test for incorrect values
994  if( (m_dummyPad->GetSize().x <= 0) ||
995  ((m_dummyPad->GetSize().y <= 0) && (m_dummyPad->GetShape() != PAD_SHAPE_CIRCLE)) )
996  {
997  error_msgs.Add( _( "Pad size must be greater than zero" ) );
998  }
999 
1000  if( (m_dummyPad->GetSize().x < m_dummyPad->GetDrillSize().x) ||
1001  (m_dummyPad->GetSize().y < m_dummyPad->GetDrillSize().y) )
1002  {
1003  error_msgs.Add( _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
1004  skip_tstoffset = true; // offset prm will be not tested because if the drill value
1005  // is incorrect the offset prm is always seen as incorrect, even if it is 0
1006  }
1007 
1008  if( m_dummyPad->GetLocalClearance() < 0 )
1009  {
1010  error_msgs.Add( _( "Pad local clearance must be zero or greater than zero" ) );
1011  }
1012 
1014  {
1015  error_msgs.Add( _( "Pad local solder mask clearance must be zero or greater than zero" ) );
1016  }
1017 
1019  {
1020  error_msgs.Add( _( "Pad local solder paste clearance must be zero or less than zero" ) );
1021  }
1022 
1023  LSET padlayers_mask = m_dummyPad->GetLayerSet();
1024 
1025  if( padlayers_mask == 0 )
1026  error_msgs.Add( _( "Error: pad has no layer" ) );
1027 
1028  if( !padlayers_mask[F_Cu] && !padlayers_mask[B_Cu] )
1029  {
1030  if( m_dummyPad->GetDrillSize().x || m_dummyPad->GetDrillSize().y )
1031  {
1032  // Note: he message is shown in an HTML window
1033  msg = _( "Error: the pad is not on a copper layer and has a hole" );
1034 
1036  {
1037  msg += wxT( "<br><br><i>" );
1038  msg += _( "For NPTH pad, set pad size value to pad drill value,"
1039  " if you do not want this pad plotted in gerber files"
1040  );
1041  }
1042 
1043  error_msgs.Add( msg );
1044  }
1045  }
1046 
1047  if( !skip_tstoffset )
1048  {
1049  wxPoint max_size;
1050  max_size.x = std::abs( m_dummyPad->GetOffset().x );
1051  max_size.y = std::abs( m_dummyPad->GetOffset().y );
1052  max_size.x += m_dummyPad->GetDrillSize().x / 2;
1053  max_size.y += m_dummyPad->GetDrillSize().y / 2;
1054 
1055  if( ( m_dummyPad->GetSize().x / 2 < max_size.x ) ||
1056  ( m_dummyPad->GetSize().y / 2 < max_size.y ) )
1057  {
1058  error_msgs.Add( _( "Incorrect value for pad offset" ) );
1059  }
1060  }
1061 
1062  if( error )
1063  {
1064  error_msgs.Add( _( "Too large value for pad delta size" ) );
1065  }
1066 
1067  switch( m_dummyPad->GetAttribute() )
1068  {
1069  case PAD_ATTRIB_HOLE_NOT_PLATED: // Not plated, but through hole, a hole is expected
1070  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
1071  if( m_dummyPad->GetDrillSize().x <= 0 )
1072  error_msgs.Add( _( "Error: Through hole pad: drill diameter set to 0" ) );
1073  break;
1074 
1075  case PAD_ATTRIB_CONN: // Connector pads are smd pads, just they do not have solder paste.
1076  if( padlayers_mask[B_Paste] || padlayers_mask[F_Paste] )
1077  error_msgs.Add( _( "Error: Connector pads are not on the solder paste layer\n"
1078  "Use SMD pads instead" ) );
1079  // Fall trough
1080  case PAD_ATTRIB_SMD: // SMD and Connector pads (One external copper layer only)
1081  {
1082  LSET innerlayers_mask = padlayers_mask & LSET::InternalCuMask();
1083 
1084  if( ( padlayers_mask[F_Cu] && padlayers_mask[B_Cu] ) ||
1085  innerlayers_mask.count() != 0 )
1086  error_msgs.Add( _( "Error: only one external copper layer allowed for SMD or Connector pads" ) );
1087  }
1088  break;
1089  }
1090 
1091 
1093  {
1094  wxString value = m_tcCornerSizeRatio->GetValue();
1095  double rrRadiusRatioPercent;
1096 
1097  if( !value.ToDouble( &rrRadiusRatioPercent ) )
1098  error_msgs.Add( _( "Incorrect corner size value" ) );
1099  else
1100  {
1101  if( rrRadiusRatioPercent < 0.0 )
1102  error_msgs.Add( _( "Incorrect (negative) corner size value" ) );
1103  else if( rrRadiusRatioPercent > 50.0 )
1104  error_msgs.Add( _( "Corner size value must be smaller than 50%" ) );
1105  }
1106  }
1107 
1109  {
1111  error_msgs.Add(
1112  _( "Incorrect pad shape: the shape must be equivalent to only one polygon" ) );
1113  }
1114 
1115 
1116  if( error_msgs.GetCount() )
1117  {
1118  HTML_MESSAGE_BOX dlg( this, _("Pad setup errors list" ) );
1119  dlg.ListSet( error_msgs );
1120  dlg.ShowModal();
1121  }
1122 
1123  return error_msgs.GetCount() == 0;
1124 }
1125 
1126 
1128 {
1129  if( m_parent->IsGalCanvasActive() )
1130  {
1131  auto view = m_panelShowPadGal->GetView();
1133 
1134  view->SetTopLayer( F_SilkS );
1135 
1136  view->Update( m_dummyPad );
1137 
1138  // delete previous items if highlight list
1139  while( m_highligth.size() )
1140  {
1141  delete m_highligth.back(); // the dtor also removes item from view
1142  m_highligth.pop_back();
1143  }
1144 
1145  // highlight selected primitives:
1146  long select = m_listCtrlPrimitives->GetFirstSelected();
1147 
1148  while( select >= 0 )
1149  {
1150  PAD_CS_PRIMITIVE& primitive = m_primitives[select];
1151 
1152  DRAWSEGMENT* dummySegment = new DRAWSEGMENT;
1153  dummySegment->SetLayer( F_SilkS );
1154  primitive.ExportTo( dummySegment );
1155  dummySegment->Rotate( wxPoint( 0, 0), m_dummyPad->GetOrientation() );
1156  dummySegment->Move( m_dummyPad->GetPosition() );
1157 
1158  // Update selected primitive (highligth selected)
1159  switch( primitive.m_Shape )
1160  {
1161  case S_SEGMENT:
1162  case S_ARC:
1163  break;
1164 
1165  case S_CIRCLE: // ring or circle
1166  if( primitive.m_Thickness == 0 ) // filled circle
1167  { // the filled circle option does not exist in a DRAWSEGMENT
1168  // but it is easy to create it with a circle having the
1169  // right radius and outline width
1170  wxPoint end = dummySegment->GetCenter();
1171  end.x += primitive.m_Radius/2;
1172  dummySegment->SetEnd( end );
1173  dummySegment->SetWidth( primitive.m_Radius );
1174  }
1175  break;
1176 
1177  case S_POLYGON: // polygon
1178  {
1179  for( auto iter = dummySegment->GetPolyShape().Iterate(); iter; iter++ )
1180  {
1181  (*iter) += VECTOR2I( m_dummyPad->GetPosition() );
1182  }
1183  }
1184  break;
1185 
1186  default:
1187  delete dummySegment;
1188  dummySegment = nullptr;
1189  break;
1190  }
1191 
1192  if( dummySegment )
1193  {
1194  view->Add( dummySegment );
1195  m_highligth.push_back( dummySegment );
1196  }
1197 
1198  select = m_listCtrlPrimitives->GetNextSelected( select );
1199  }
1200 
1201  BOX2I bbox = m_dummyPad->ViewBBox();
1202 
1203  if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
1204  {
1205  // gives a size to the full drawable area
1206  BOX2I drawbox;
1207  drawbox.Move( m_dummyPad->GetPosition() );
1208  drawbox.Inflate( bbox.GetSize().x*2, bbox.GetSize().y*2 );
1209  view->SetBoundary( drawbox );
1210 
1211  // Autozoom
1212  view->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) );
1213 
1214  // Add a margin
1215  view->SetScale( m_panelShowPadGal->GetView()->GetScale() * 0.7 );
1216 
1219  }
1220  }
1221  else
1222  {
1223  m_panelShowPad->Refresh();
1224  }
1225 }
1226 
1227 
1229 {
1230  if( !wxDialog::TransferDataToWindow() )
1231  return false;
1232 
1233  if( !m_panelGeneral->TransferDataToWindow() )
1234  return false;
1235 
1236  if( !m_localSettingsPanel->TransferDataToWindow() )
1237  return false;
1238 
1239  return true;
1240 }
1241 
1242 
1244 {
1245  BOARD_COMMIT commit( m_parent );
1246 
1247  if( !wxDialog::TransferDataFromWindow() )
1248  return false;
1249 
1250  if( !m_panelGeneral->TransferDataFromWindow() )
1251  return false;
1252 
1253  if( !m_localSettingsPanel->TransferDataFromWindow() )
1254  return false;
1255 
1256  if( !padValuesOK() )
1257  return false;
1258 
1259  bool rastnestIsChanged = false;
1260  int isign = m_isFlipped ? -1 : 1;
1261 
1263  // m_padMaster is a pattern: ensure there is no net for this pad:
1265 
1266  if( !m_currentPad ) // Set current Pad parameters
1267  return true;
1268 
1269  commit.Modify( m_currentPad );
1270 
1271  // redraw the area where the pad was, without pad (delete pad on screen)
1275 
1276  // Update values
1279 
1281  {
1283  rastnestIsChanged = true;
1284  }
1285 
1286  wxSize size;
1287  MODULE* footprint = m_currentPad->GetParent();
1288 
1289  if( footprint )
1290  {
1291  footprint->SetLastEditTime();
1292 
1293  // compute the pos 0 value, i.e. pad position for footprint with orientation = 0
1294  // i.e. relative to footprint origin (footprint position)
1295  wxPoint pt = m_currentPad->GetPosition() - footprint->GetPosition();
1296  RotatePoint( &pt, -footprint->GetOrientation() );
1297  m_currentPad->SetPos0( pt );
1299  + footprint->GetOrientation() );
1300  }
1301 
1303 
1304  size = m_padMaster->GetDelta();
1305  size.y *= isign;
1306  m_currentPad->SetDelta( size );
1307 
1310 
1311  wxPoint offset = m_padMaster->GetOffset();
1312  offset.y *= isign;
1313  m_currentPad->SetOffset( offset );
1314 
1316 
1319 
1320 
1323 
1324  if( m_isFlipped )
1325  {
1328  }
1329 
1331  {
1332  rastnestIsChanged = true;
1334  }
1335 
1336  if( m_isFlipped )
1337  {
1339  }
1340 
1342 
1343  wxString padNetname;
1344 
1345  // For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
1347  padNetname = m_PadNetNameCtrl->GetValue();
1348 
1349  if( m_currentPad->GetNetname() != padNetname )
1350  {
1351  const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname );
1352 
1353  if( !padNetname.IsEmpty() && netinfo == NULL )
1354  {
1355  DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
1356  }
1357  else if( netinfo )
1358  {
1359  rastnestIsChanged = true;
1360  m_currentPad->SetNetCode( netinfo->GetNet() );
1361  }
1362  }
1363 
1372 
1373  // rounded rect pads with radius ratio = 0 are in fact rect pads.
1374  // So set the right shape (and perhaps issues with a radius = 0)
1377  {
1379  }
1380 
1381  // define the way the clearnce area is defined in zones
1383 
1384  if( footprint )
1385  footprint->CalculateBoundingBox();
1386 
1388 
1389  // redraw the area where the pad was
1391 
1392  commit.Push( _( "Modify pad" ) );
1393 
1394  if( rastnestIsChanged ) // The net ratsnest must be recalculated
1395  m_board->m_Status_Pcb = 0;
1396 
1397  return true;
1398 }
1399 
1400 
1402 {
1403  wxString msg;
1404  int x, y;
1405 
1406  if( !Validate() )
1407  return true;
1408  if( !m_panelGeneral->Validate() )
1409  return true;
1410  if( !m_localSettingsPanel->Validate() )
1411  return true;
1412 
1413  m_OrientValidator.TransferFromWindow();
1414 
1415  aPad->SetAttribute( code_type[m_PadType->GetSelection()] );
1416  aPad->SetShape( code_shape[m_PadShape->GetSelection()] );
1419 
1420  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1421  aPad->SetPrimitives( m_primitives );
1422 
1423  // Read pad clearances values:
1429  double dtmp = 0.0;
1430  msg = m_SolderPasteMarginRatioCtrl->GetValue();
1431  msg.ToDouble( &dtmp );
1432 
1433  // A -50% margin ratio means no paste on a pad, the ratio must be >= -50%
1434  if( dtmp < -50.0 )
1435  dtmp = -50.0;
1436  // A margin ratio is always <= 0
1437  // 0 means use full pad copper area
1438  if( dtmp > 0.0 )
1439  dtmp = 0.0;
1440 
1441  aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 );
1442 
1443  switch( m_ZoneConnectionChoice->GetSelection() )
1444  {
1445  default:
1446  case 0:
1448  break;
1449 
1450  case 1:
1452  break;
1453 
1454  case 2:
1456  break;
1457 
1458  case 3:
1460  break;
1461  }
1462 
1463  // Read pad position:
1466 
1467  aPad->SetPosition( wxPoint( x, y ) );
1468  aPad->SetPos0( wxPoint( x, y ) );
1469 
1470  // Read pad drill:
1473 
1474  if( m_DrillShapeCtrl->GetSelection() == 0 )
1475  {
1477  y = x;
1478  }
1479  else
1481 
1482  aPad->SetDrillSize( wxSize( x, y ) );
1483 
1484  // Read pad shape size:
1487 
1488  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1489  y = x;
1490 
1491  // for custom shped pads, the pad size is the anchor pad size:
1492  if( aPad->GetShape() == PAD_SHAPE_CUSTOM && aPad->GetAnchorPadShape() == PAD_SHAPE_CIRCLE )
1493  y = x;
1494 
1495  aPad->SetSize( wxSize( x, y ) );
1496 
1497  // Read pad length die
1499 
1500  // For a trapezoid, test delta value (be sure delta is not too large for pad size)
1501  // remember DeltaSize.x is the Y size variation
1502  bool error = false;
1503 
1504  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
1505  {
1506  wxSize delta;
1507 
1508  // For a trapezoid, only one of delta.x or delta.y is not 0, depending on
1509  // the direction.
1510  if( m_trapDeltaDirChoice->GetSelection() == 0 )
1511  delta.x = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
1512  else
1513  delta.y = ValueFromTextCtrl( *m_ShapeDelta_Ctrl );
1514 
1515  if( delta.x < 0 && delta.x <= -aPad->GetSize().y )
1516  {
1517  delta.x = -aPad->GetSize().y + 2;
1518  error = true;
1519  }
1520 
1521  if( delta.x > 0 && delta.x >= aPad->GetSize().y )
1522  {
1523  delta.x = aPad->GetSize().y - 2;
1524  error = true;
1525  }
1526 
1527  if( delta.y < 0 && delta.y <= -aPad->GetSize().x )
1528  {
1529  delta.y = -aPad->GetSize().x + 2;
1530  error = true;
1531  }
1532 
1533  if( delta.y > 0 && delta.y >= aPad->GetSize().x )
1534  {
1535  delta.y = aPad->GetSize().x - 2;
1536  error = true;
1537  }
1538 
1539  aPad->SetDelta( delta );
1540  }
1541 
1542  // Read pad shape offset:
1545  aPad->SetOffset( wxPoint( x, y ) );
1546 
1547  aPad->SetOrientation( m_OrientValue * 10.0 );
1548  aPad->SetName( m_PadNumCtrl->GetValue() );
1549 
1550  // Check if user has set an existing net name
1551  const NETINFO_ITEM* netinfo = m_board->FindNet( m_PadNetNameCtrl->GetValue() );
1552 
1553  if( netinfo != NULL )
1554  aPad->SetNetCode( netinfo->GetNet() );
1555  else
1557 
1558  // Clear some values, according to the pad type and shape
1559  switch( aPad->GetShape() )
1560  {
1561  case PAD_SHAPE_CIRCLE:
1562  aPad->SetOffset( wxPoint( 0, 0 ) );
1563  aPad->SetDelta( wxSize( 0, 0 ) );
1564  x = aPad->GetSize().x;
1565  aPad->SetSize( wxSize( x, x ) );
1566  break;
1567 
1568  case PAD_SHAPE_RECT:
1569  aPad->SetDelta( wxSize( 0, 0 ) );
1570  break;
1571 
1572  case PAD_SHAPE_OVAL:
1573  aPad->SetDelta( wxSize( 0, 0 ) );
1574  break;
1575 
1576  case PAD_SHAPE_TRAPEZOID:
1577  break;
1578 
1579  case PAD_SHAPE_ROUNDRECT:
1580  aPad->SetDelta( wxSize( 0, 0 ) );
1581  break;
1582 
1583  case PAD_SHAPE_CUSTOM:
1584  aPad->SetOffset( wxPoint( 0, 0 ) );
1585  aPad->SetDelta( wxSize( 0, 0 ) );
1586 
1587  // The pad custom has a "anchor pad" (a basic shape: round or rect pad)
1588  // that is the minimal area of this pad, and is usefull to ensure a hole
1589  // diameter is acceptable, and is used in Gerber files as flashed area
1590  // reference
1591  if( aPad->GetAnchorPadShape() == PAD_SHAPE_CIRCLE )
1592  {
1593  x = aPad->GetSize().x;
1594  aPad->SetSize( wxSize( x, x ) );
1595  }
1596 
1597  // define the way the clearance area is defined in zones
1598  aPad->SetCustomShapeInZoneOpt( m_ZoneCustomPadShape->GetSelection() == 0 ?
1601 
1602  break;
1603 
1604  default:
1605  ;
1606  }
1607 
1608  switch( aPad->GetAttribute() )
1609  {
1610  case PAD_ATTRIB_STANDARD:
1611  break;
1612 
1613  case PAD_ATTRIB_CONN:
1614  case PAD_ATTRIB_SMD:
1615  // SMD and PAD_ATTRIB_CONN has no hole.
1616  // basically, SMD and PAD_ATTRIB_CONN are same type of pads
1617  // PAD_ATTRIB_CONN has just a default non technical layers that differs from SMD
1618  // and are intended to be used in virtual edge board connectors
1619  // However we can accept a non null offset,
1620  // mainly to allow complex pads build from a set of basic pad shapes
1621  aPad->SetDrillSize( wxSize( 0, 0 ) );
1622  break;
1623 
1625  // Mechanical purpose only:
1626  // no offset, no net name, no pad name allowed
1627  aPad->SetOffset( wxPoint( 0, 0 ) );
1628  aPad->SetName( wxEmptyString );
1630  break;
1631 
1632  default:
1633  DisplayError( NULL, wxT( "Error: unknown pad type" ) );
1634  break;
1635  }
1636 
1637  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
1638  {
1639  wxString value = m_tcCornerSizeRatio->GetValue();
1640  double rrRadiusRatioPercent;
1641 
1642  if( value.ToDouble( &rrRadiusRatioPercent ) )
1643  aPad->SetRoundRectRadiusRatio( rrRadiusRatioPercent / 100.0 );
1644  }
1645 
1646  LSET padLayerMask;
1647 
1648  switch( m_rbCopperLayersSel->GetSelection() )
1649  {
1650  case 0:
1651  padLayerMask.set( F_Cu );
1652  break;
1653 
1654  case 1:
1655  padLayerMask.set( B_Cu );
1656  break;
1657 
1658  case 2:
1659  padLayerMask |= LSET::AllCuMask();
1660  break;
1661 
1662  case 3: // No copper layers
1663  break;
1664  }
1665 
1666  if( m_PadLayerAdhCmp->GetValue() )
1667  padLayerMask.set( F_Adhes );
1668 
1669  if( m_PadLayerAdhCu->GetValue() )
1670  padLayerMask.set( B_Adhes );
1671 
1672  if( m_PadLayerPateCmp->GetValue() )
1673  padLayerMask.set( F_Paste );
1674 
1675  if( m_PadLayerPateCu->GetValue() )
1676  padLayerMask.set( B_Paste );
1677 
1678  if( m_PadLayerSilkCmp->GetValue() )
1679  padLayerMask.set( F_SilkS );
1680 
1681  if( m_PadLayerSilkCu->GetValue() )
1682  padLayerMask.set( B_SilkS );
1683 
1684  if( m_PadLayerMaskCmp->GetValue() )
1685  padLayerMask.set( F_Mask );
1686 
1687  if( m_PadLayerMaskCu->GetValue() )
1688  padLayerMask.set( B_Mask );
1689 
1690  if( m_PadLayerECO1->GetValue() )
1691  padLayerMask.set( Eco1_User );
1692 
1693  if( m_PadLayerECO2->GetValue() )
1694  padLayerMask.set( Eco2_User );
1695 
1696  if( m_PadLayerDraft->GetValue() )
1697  padLayerMask.set( Dwgs_User );
1698 
1699  aPad->SetLayerSet( padLayerMask );
1700 
1701  return error;
1702 }
1703 
1704 
1705 void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event )
1706 {
1707  if( m_canUpdate )
1708  {
1710  // If the pad size has changed, update the displayed values
1711  // for rounded rect pads
1713 
1714  redraw();
1715  }
1716 }
1717 
1719 {
1720  long select = m_listCtrlPrimitives->GetFirstSelected();
1721 
1722  if( select < 0 )
1723  {
1724  wxMessageBox( _( "No shape selected" ) );
1725  return;
1726  }
1727 
1728  PAD_CS_PRIMITIVE& shape = m_primitives[select];
1729 
1730  if( shape.m_Shape == S_POLYGON )
1731  {
1732  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, &shape );
1733 
1734  if( dlg.ShowModal() != wxID_OK )
1735  return;
1736 
1737  dlg.TransferDataFromWindow();
1738  }
1739 
1740  else
1741  {
1742  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, &shape );
1743 
1744  if( dlg.ShowModal() != wxID_OK )
1745  return;
1746 
1747  dlg.TransferDataFromWindow();
1748  }
1749 
1751 
1752  if( m_canUpdate )
1753  {
1755  redraw();
1756  }
1757 }
1758 
1759 
1761 {
1762  // Called on a double click on the basic shapes list
1763  // To Do: highligth the primitive(s) currently selected.
1764  redraw();
1765 }
1766 
1767 
1769 void DIALOG_PAD_PROPERTIES::onPrimitiveDClick( wxMouseEvent& event )
1770 {
1771  editPrimitive();
1772 }
1773 
1774 
1775 // Called on a click on basic shapes list panel button
1776 void DIALOG_PAD_PROPERTIES::onEditPrimitive( wxCommandEvent& event )
1777 {
1778  editPrimitive();
1779 }
1780 
1781 // Called on a click on basic shapes list panel button
1782 void DIALOG_PAD_PROPERTIES::onDeletePrimitive( wxCommandEvent& event )
1783 {
1784  long select = m_listCtrlPrimitives->GetFirstSelected();
1785 
1786  if( select < 0 )
1787  return;
1788 
1789  // Multiple selections are allowed. get them and remove corresponding shapes
1790  std::vector<long> indexes;
1791  indexes.push_back( select );
1792 
1793  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1794  indexes.push_back( select );
1795 
1796  // Erase all select shapes
1797  for( unsigned ii = indexes.size(); ii > 0; --ii )
1798  m_primitives.erase( m_primitives.begin() + indexes[ii-1] );
1799 
1801 
1802  if( m_canUpdate )
1803  {
1805  redraw();
1806  }
1807 }
1808 
1809 
1810 void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
1811 {
1812  // Ask user for shape type
1813  wxString shapelist[] =
1814  {
1815  _( "Segment" ), _( "Arc" ), _( "ring/circle" ), _( "polygon" )
1816  };
1817 
1818  int type = wxGetSingleChoiceIndex( wxEmptyString, _( "Select shape type:" ),
1819  DIM( shapelist ), shapelist, 0 );
1820 
1821  STROKE_T listtype[] =
1822  {
1824  };
1825 
1826  PAD_CS_PRIMITIVE primitive( listtype[type] );
1827 
1828  if( listtype[type] == S_POLYGON )
1829  {
1830  DIALOG_PAD_PRIMITIVE_POLY_PROPS dlg( this, &primitive );
1831 
1832  if( dlg.ShowModal() != wxID_OK )
1833  return;
1834  }
1835  else
1836  {
1837  DIALOG_PAD_PRIMITIVES_PROPERTIES dlg( this, &primitive );
1838 
1839  if( dlg.ShowModal() != wxID_OK )
1840  return;
1841  }
1842 
1843  m_primitives.push_back( primitive );
1844 
1846 
1847  if( m_canUpdate )
1848  {
1850  redraw();
1851  }
1852 }
1853 
1854 
1855 void DIALOG_PAD_PROPERTIES::onImportPrimitives( wxCommandEvent& event )
1856 {
1857  wxMessageBox( "Not yet available" );
1858 }
1859 
1860 
1861 void DIALOG_PAD_PROPERTIES::onGeometryTransform( wxCommandEvent& event )
1862 {
1863  long select = m_listCtrlPrimitives->GetFirstSelected();
1864 
1865  if( select < 0 )
1866  {
1867  wxMessageBox( _( "No shape selected" ) );
1868  return;
1869  }
1870 
1871  // Multiple selections are allowed. Build selected shapes list
1872  std::vector<long> indexes;
1873  indexes.push_back( select );
1874 
1875  std::vector<PAD_CS_PRIMITIVE*> shapeList;
1876  shapeList.push_back( &m_primitives[select] );
1877 
1878  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1879  {
1880  indexes.push_back( select );
1881  shapeList.push_back( &m_primitives[select] );
1882  }
1883 
1884  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, shapeList, false );
1885 
1886  if( dlg.ShowModal() != wxID_OK )
1887  return;
1888 
1889  // Transfert new settings:
1890  dlg.Transform();
1891 
1893 
1894  if( m_canUpdate )
1895  {
1897  redraw();
1898  }
1899 }
1900 
1901 
1902 void DIALOG_PAD_PROPERTIES::onDuplicatePrimitive( wxCommandEvent& event )
1903 {
1904  long select = m_listCtrlPrimitives->GetFirstSelected();
1905 
1906  if( select < 0 )
1907  {
1908  wxMessageBox( _( "No shape selected" ) );
1909  return;
1910  }
1911 
1912  // Multiple selections are allowed. Build selected shapes list
1913  std::vector<long> indexes;
1914  indexes.push_back( select );
1915 
1916  std::vector<PAD_CS_PRIMITIVE*> shapeList;
1917  shapeList.push_back( &m_primitives[select] );
1918 
1919  while( ( select = m_listCtrlPrimitives->GetNextSelected( select ) ) >= 0 )
1920  {
1921  indexes.push_back( select );
1922  shapeList.push_back( &m_primitives[select] );
1923  }
1924 
1925  DIALOG_PAD_PRIMITIVES_TRANSFORM dlg( this, shapeList, true );
1926 
1927  if( dlg.ShowModal() != wxID_OK )
1928  return;
1929 
1930  // Transfert new settings:
1931  dlg.Transform( &m_primitives, dlg.GetDuplicateCount() );
1932 
1934 
1935  if( m_canUpdate )
1936  {
1938  redraw();
1939  }
1940 }
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:646
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:117
#define DIM(x)
of elements in an array
Definition: macros.h:98
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:196
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:491
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 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
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:398
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
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:337
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.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
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.
const wxPoint & GetPosition() const override
Definition: class_module.h:155
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:203
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
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:305
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
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
ITERATOR Iterate(int aFirst, int aLast, bool aIterateHoles=false)
Function Iterate returns an object to iterate through the points of the polygons between aFirst and a...
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:282
const Vec & GetSize() const
Definition: box2.h:177
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:833
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
smd pads, back layer
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:777
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
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
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
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
Definition: class_pad.cpp:1283
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:267
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:161
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
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:784
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:182
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:160
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.
const wxPoint & GetPosition() const override
Definition: class_pad.h:220
Arcs (with rounded ends)
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit)
Definition: base_units.cpp:479
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.
Definition: colors.h:59
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:606
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.
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:862
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
SHAPE_POLY_SET & GetPolyShape()
void SetPadToDieLength(int aLength)
Definition: class_pad.h:400
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
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:384
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 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
virtual void Move(const wxPoint &aMoveVector) override
Function Move move this object.
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
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:265
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 GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:592
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:791
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
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:268
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:870
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)
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:229
Module description (excepted pads)
Definition: colors.h:45
bool m_Display_netname
Definition: class_pad.h:76
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:71
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 ...
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:873
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
void SetWidth(int aWidth)