KiCad PCB EDA Suite
dialog_pad_basicshapes_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) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <algorithm>
31 
32 #include <fctsys.h>
33 #include <common.h>
34 #include <confirm.h>
35 #include <pcbnew.h>
36 #include <trigo.h>
37 #include <macros.h>
38 #include <pcb_base_frame.h>
39 #include <base_units.h>
40 #include <widgets/wx_grid.h>
41 #include <class_board.h>
42 #include <class_module.h>
43 #include <math/util.h> // for KiROUND
44 
45 #include <dialog_pad_properties.h>
46 #include <bitmaps.h>
47 
49  PCB_BASE_FRAME* aFrame,
50  PAD_CS_PRIMITIVE * aShape ) :
52  m_shape( aShape ),
53  m_startX( aFrame, m_startXLabel, m_startXCtrl, m_startXUnits, true ),
54  m_startY( aFrame, m_startYLabel, m_startYCtrl, m_startYUnits, true ),
55  m_ctrl1X( aFrame, m_ctrl1XLabel, m_ctrl1XCtrl, m_ctrl1XUnits, true ),
56  m_ctrl1Y( aFrame, m_ctrl1YLabel, m_ctrl1YCtrl, m_ctrl1YUnits, true ),
57  m_ctrl2X( aFrame, m_ctrl2XLabel, m_ctrl2XCtrl, m_ctrl2XUnits, true ),
58  m_ctrl2Y( aFrame, m_ctrl2YLabel, m_ctrl2YCtrl, m_ctrl2YUnits, true ),
59  m_endX( aFrame, m_endXLabel, m_endXCtrl, m_endXUnits, true ),
60  m_endY( aFrame, m_endYLabel, m_endYCtrl, m_endYUnits, true ),
61  m_radius( aFrame, m_radiusLabel, m_radiusCtrl, m_radiusUnits, true ),
62  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
63 {
65 
67 
68  m_sdbSizerOK->SetDefault();
69 
71 }
72 
74 {
75  if( m_shape == NULL )
76  return false;
77 
78  // Shows the text info about circle or ring only for S_CIRCLE shape
79  if( m_shape->m_Shape != S_CIRCLE )
80  m_staticTextInfo->Show( false );
81 
83 
84  switch( m_shape->m_Shape )
85  {
86  case S_SEGMENT: // Segment with rounded ends
87  SetTitle( _( "Segment" ) );
92  m_ctrl1X.Show( false, true );
93  m_ctrl1Y.Show( false, true );
94  m_ctrl2X.Show( false, true );
95  m_ctrl2Y.Show( false, true );
96  m_staticTextPosCtrl1->Show( false );
97  m_staticTextPosCtrl1->SetSize( 0, 0 );
98  m_staticTextPosCtrl2->Show( false );
99  m_staticTextPosCtrl2->SetSize( 0, 0 );
100  m_radius.Show( false );
101  break;
102 
103  case S_CURVE: // Bezier line
104  SetTitle( _( "Bezier" ) );
113  m_radius.Show( false );
114  break;
115 
116  case S_ARC: // Arc with rounded ends
117  SetTitle( _( "Arc" ) );
118  m_startX.SetValue( m_shape->m_End.x ); // confusingly, the start point of the arc
120  m_staticTextPosEnd->SetLabel( _( "Center" ) );
121  m_endX.SetValue( m_shape->m_Start.x ); // arc center
123  m_radiusLabel->SetLabel( _( "Angle:" ) );
126  m_ctrl1X.Show( false, true );
127  m_ctrl1Y.Show( false, true );
128  m_ctrl2X.Show( false, true );
129  m_ctrl2Y.Show( false, true );
130  m_staticTextPosCtrl1->Show( false );
131  m_staticTextPosCtrl1->SetSize( 0, 0 );
132  m_staticTextPosCtrl2->Show( false );
133  m_staticTextPosCtrl2->SetSize( 0, 0 );
134  break;
135 
136  case S_CIRCLE: // ring or circle
137  if( m_shape->m_Thickness )
138  SetTitle( _( "Ring" ) );
139  else
140  SetTitle( _( "Circle" ) );
141 
142  // End point does not exist for a circle or ring:
143  m_staticTextPosEnd->Show( false );
144  m_endX.Show( false );
145  m_endY.Show( false );
146 
147  // Circle center uses position controls:
148  m_staticTextPosStart->SetLabel( _( "Center:" ) );
152  m_ctrl1X.Show( false, true );
153  m_ctrl1Y.Show( false, true );
154  m_ctrl2X.Show( false, true );
155  m_ctrl2Y.Show( false, true );
156  m_staticTextPosCtrl1->Show( false );
157  m_staticTextPosCtrl1->SetSize( 0, 0 );
158  m_staticTextPosCtrl2->Show( false );
159  m_staticTextPosCtrl2->SetSize( 0, 0 );
160  break;
161 
162  case S_POLYGON: // polygon
163  // polygon has a specific dialog editor. So nothing here
164  break;
165 
166  default:
167  SetTitle( "Unknown basic shape" );
168  break;
169  }
170 
171  return true;
172 }
173 
175 {
176  // Transfer data out of the GUI.
178 
179  switch( m_shape->m_Shape )
180  {
181  case S_SEGMENT: // Segment with rounded ends
186  break;
187 
188  case S_CURVE: // Segment with rounded ends
197  break;
198 
199  case S_ARC: // Arc with rounded ends
200  // NB: we store the center of the arc in m_Start, and, confusingly,
201  // the start point in m_End
206  // arc angle
208  break;
209 
210  case S_CIRCLE: // ring or circle
214  break;
215 
216  case S_POLYGON: // polygon
217  // polygon has a specific dialog editor. So nothing here
218  break;
219 
220  default:
221  SetTitle( "Unknown basic shape" );
222  break;
223  }
224 
225  return true;
226 }
227 
228 
230  PCB_BASE_FRAME* aFrame,
231  PAD_CS_PRIMITIVE * aShape ) :
233  m_shape( aShape ),
234  m_currshape( *m_shape ),
235  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
236 {
237  m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
238  m_deleteButton->SetBitmap( KiBitmap( trash_xpm ) );
239  m_warningIcon->SetBitmap( KiBitmap( dialog_warning_xpm ) );
240 
241  // Test for acceptable polygon (more than 2 corners, and not self-intersecting) and
242  // remove any redundant corners. A warning message is displayed if not OK.
243  doValidate( true );
244 
246 
247  m_sdbSizerOK->SetDefault();
248  GetSizer()->SetSizeHints( this );
249 
250  // TODO: move wxEVT_GRID_CELL_CHANGING in wxFormbuilder, when it support it
251  m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
252 
253  // Now all widgets have the size fixed, call FinishDialogSettings
255 }
256 
257 
259 {
260  m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
261 }
262 
263 
265 {
266  if( m_shape == NULL )
267  return false;
268 
270 
271  // Populates the list of corners
272  int extra_rows = m_currshape.m_Poly.size() - m_gridCornersList->GetNumberRows();
273 
274  if( extra_rows > 0 )
275  {
276  m_gridCornersList->AppendRows( extra_rows );
277  }
278  else if( extra_rows < 0 )
279  {
280  extra_rows = -extra_rows;
281  m_gridCornersList->DeleteRows( 0, extra_rows );
282  }
283 
284  // enter others corner coordinates
285  wxString msg;
286  for( unsigned row = 0; row < m_currshape.m_Poly.size(); ++row )
287  {
288  // Row label is "Corner x"
289  msg.Printf( "Corner %d", row+1 );
290  m_gridCornersList->SetRowLabelValue( row, msg );
291 
292  msg = StringFromValue( GetUserUnits(), m_currshape.m_Poly[row].x, true, true );
293  m_gridCornersList->SetCellValue( row, 0, msg );
294 
295  msg = StringFromValue( GetUserUnits(), m_currshape.m_Poly[row].y, true, true );
296  m_gridCornersList->SetCellValue( row, 1, msg );
297  }
298 
299  return true;
300 }
301 
303 {
304  if( !Validate() )
305  return false;
306 
308 
309  *m_shape = m_currshape;
310 
311  return true;
312 }
313 
314 
316 {
317  // Don't remove redundant corners while user is editing corner list
318  return doValidate( false );
319 }
320 
321 
322 // test for a valid polygon (a not self intersectiong polygon)
323 bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
324 {
326  return false;
327 
328  if( m_currshape.m_Poly.size() < 3 )
329  {
330  m_warningText->SetLabel( _("Polygon must have at least 3 corners" ) );
331  m_warningText->Show( true );
332  m_warningIcon->Show( true );
333  return false;
334  }
335 
336  bool valid = true;
337 
338  SHAPE_LINE_CHAIN polyline;
339 
340  for( unsigned ii = 0; ii < m_currshape.m_Poly.size(); ++ii )
341  polyline.Append( m_currshape.m_Poly[ii].x, m_currshape.m_Poly[ii].y );
342 
343  // The polyline describes a polygon: close it.
344  polyline.SetClosed( true );
345 
346  // Remove redundant corners:
347  polyline.Simplify();
348 
349  if( polyline.PointCount() < 3 )
350  {
351  m_warningText->SetLabel( _( "Polygon must have at least 3 corners after simplification" ) );
352  valid = false;
353  }
354 
355  if( valid && polyline.SelfIntersecting() )
356  {
357  m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
358  valid = false;
359  }
360 
361  m_warningIcon->Show( !valid );
362  m_warningText->Show( !valid );
363 
364  if( aRemoveRedundantCorners )
365  {
366  if( polyline.PointCount() != (int)m_currshape.m_Poly.size() )
367  { // Happens after simplification
368  m_currshape.m_Poly.clear();
369 
370  for( int ii = 0; ii < polyline.PointCount(); ++ii )
371  m_currshape.m_Poly.emplace_back( polyline.CPoint( ii ).x, polyline.CPoint( ii ).y );
372 
373  m_warningIcon->Show( true );
374  m_warningText->Show( true );
375  m_warningText->SetLabel( _( "Note: redundant corners removed" ) );
376  }
377  }
378 
379  return valid;
380 }
381 
382 
383 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonAdd( wxCommandEvent& event )
384 {
386  return;
387 
388  // Insert a new corner after the currently selected:
389  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
390  int row = -1;
391 
392  if( m_gridCornersList->GetNumberRows() == 0 )
393  row = 0;
394  else if( selections.size() > 0 )
395  row = selections[ selections.size() - 1 ] + 1;
396  else
397  row = m_gridCornersList->GetGridCursorRow() + 1;
398 
399  if( row < 0 )
400  {
401  wxMessageBox( _( "Select a corner to add the new corner after." ) );
402  return;
403  }
404 
405  if( m_currshape.m_Poly.size() == 0 || row >= (int) m_currshape.m_Poly.size() )
406  m_currshape.m_Poly.emplace_back( 0, 0 );
407  else
408  m_currshape.m_Poly.insert( m_currshape.m_Poly.begin() + row, wxPoint( 0, 0 ) );
409 
410  Validate();
412 
413  m_gridCornersList->ForceRefresh();
414  // Select the new row
415  m_gridCornersList->SelectRow( row, false );
416 
417  m_panelPoly->Refresh();
418 }
419 
421 {
423  return;
424 
425  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
426 
427  if( m_gridCornersList->GetNumberRows() == 0 )
428  return;
429 
430  if( selections.size() == 0 && m_gridCornersList->GetGridCursorRow() >= 0 )
431  selections.push_back( m_gridCornersList->GetGridCursorRow() );
432 
433  if( selections.size() == 0 )
434  {
435  wxMessageBox( _( "Select a corner to delete." ) );
436  return;
437  }
438 
439  // remove corners:
440  std::sort( selections.begin(), selections.end() );
441 
442  for( int ii = selections.size()-1; ii >= 0 ; --ii )
443  m_currshape.m_Poly.erase( m_currshape.m_Poly.begin() + selections[ii] );
444 
445  Validate();
447 
448  m_gridCornersList->ForceRefresh();
449  // select the row previous to the last deleted row
450  m_gridCornersList->SelectRow( std::max( 0, selections[ 0 ] - 1 ) );
451 
452  m_panelPoly->Refresh();
453 }
454 
456 {
457  wxPaintDC dc( m_panelPoly );
458  wxSize dc_size = dc.GetSize();
459  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
460 
461  // Calculate a suitable scale to fit the available draw area
462  int minsize( Millimeter2iu( 0.5 ) );
463 
464  for( unsigned ii = 0; ii < m_currshape.m_Poly.size(); ++ii )
465  {
466  minsize = std::max( minsize, std::abs( m_currshape.m_Poly[ii].x ) );
467  minsize = std::max( minsize, std::abs( m_currshape.m_Poly[ii].y ) );
468  }
469 
470  // The draw origin is the center of the window.
471  // Therefore the window size is twice the minsize just calculated
472  minsize *= 2;
473  minsize += m_currshape.m_Thickness;
474 
475  // Give a margin
476  double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;
477 
478  GRResetPenAndBrush( &dc );
479 
480  // Draw X and Y axis. This is particularly useful to show the
481  // reference position of basic shape
482  // Axis are drawn before the polygon to avoid masking segments on axis
483  GRLine( NULL, &dc, -dc_size.x, 0, dc_size.x, 0, 0, LIGHTBLUE ); // X axis
484  GRLine( NULL, &dc, 0, -dc_size.y, 0, dc_size.y, 0, LIGHTBLUE ); // Y axis
485 
486  // Draw polygon.
487  // The selected edge(s) are shown in selectcolor, the others in normalcolor.
488  EDA_COLOR_T normalcolor = WHITE;
489  EDA_COLOR_T selectcolor = RED;
490 
491  for( unsigned ii = 0; ii < m_currshape.m_Poly.size(); ++ii )
492  {
493  EDA_COLOR_T color = normalcolor;
494 
495  if( m_gridCornersList->IsInSelection (ii, 0) ||
496  m_gridCornersList->IsInSelection (ii, 1) ||
497  m_gridCornersList->GetGridCursorRow() == (int)ii )
498  color = selectcolor;
499 
500  unsigned jj = ii + 1;
501 
502  if( jj >= m_currshape.m_Poly.size() )
503  jj = 0;
504 
506  }
507 
508  event.Skip();
509 }
510 
512 {
513  m_panelPoly->Refresh();
514  event.Skip();
515 }
516 
517 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onGridSelect( wxGridRangeSelectEvent& event )
518 {
519  m_panelPoly->Refresh();
520 }
521 
523 {
524  int row = event.GetRow();
525  int col = event.GetCol();
526  wxString msg = event.GetString();
527 
528  if( msg.IsEmpty() )
529  return;
530 
531  if( col == 0 ) // Set the X value
532  m_currshape.m_Poly[row].x = ValueFromString( GetUserUnits(), msg, true );
533  else // Set the Y value
534  m_currshape.m_Poly[row].y = ValueFromString( GetUserUnits(), msg, true );
535 
537 
538  Validate();
539 
540  m_panelPoly->Refresh();
541 }
542 
543 
544 // A dialog to apply geometry transforms to a shape or set of shapes
545 // (move, rotate around origin, scaling factor, duplication).
547  PCB_BASE_FRAME* aFrame,
548  std::vector<PAD_CS_PRIMITIVE*>& aList,
549  bool aShowDuplicate ) :
551  m_list( aList ),
552  m_vectorX( aFrame, m_xLabel, m_xCtrl, m_xUnits, true ),
553  m_vectorY( aFrame, m_yLabel, m_yCtrl, m_yUnits, true ),
554  m_rotation( aFrame, m_rotationLabel, m_rotationCtrl, m_rotationUnits )
555 {
557 
558  if( !aShowDuplicate ) // means no duplicate transform
559  {
560  m_staticTextDupCnt->Show( false );
561  m_spinCtrlDuplicateCount->Show( false );
562  }
563 
564  m_sdbSizerOK->SetDefault();
565  GetSizer()->SetSizeHints( this );
566 }
567 
568 
569 // A helper function in geometry transform
570 inline void geom_transf( wxPoint& aCoord, wxPoint& aMove, double aScale, double aRotation )
571 {
572  aCoord.x = KiROUND( aCoord.x * aScale );
573  aCoord.y = KiROUND( aCoord.y * aScale );
574  aCoord += aMove;
575  RotatePoint( &aCoord, aRotation );
576 }
577 
578 
579 void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<PAD_CS_PRIMITIVE>* aList, int aDuplicateCount )
580 {
581  wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
582  double rotation = m_rotation.GetValue();
584 
585  // Avoid too small / too large scale, which could create issues:
586  if( scale < 0.01 )
587  scale = 0.01;
588 
589  if( scale > 100.0 )
590  scale = 100.0;
591 
592  // Transform shapes
593  // shapes are scaled, then moved then rotated.
594  // if aList != NULL, the initial shape will be duplicated, and transform
595  // applied to the duplicated shape
596 
597  wxPoint currMoveVect = move_vect;
598  double curr_rotation = rotation;
599 
600  do {
601  for( unsigned idx = 0; idx < m_list.size(); ++idx )
602  {
603  PAD_CS_PRIMITIVE* shape;
604 
605  if( aList == NULL )
606  shape = m_list[idx];
607  else
608  {
609  PAD_CS_PRIMITIVE new_shape( *m_list[idx] );
610  aList->push_back( new_shape );
611  shape = &aList->back();
612  }
613 
614  // Transform parameters common to all shape types (some can be unused)
615  shape->m_Thickness = KiROUND( shape->m_Thickness * scale );
616  geom_transf( shape->m_Start, currMoveVect, scale, curr_rotation );
617  geom_transf( shape->m_End, currMoveVect, scale, curr_rotation );
618 
619  // specific parameters:
620  switch( shape->m_Shape )
621  {
622  case S_SEGMENT: // Segment with rounded ends
623  break;
624 
625  case S_ARC: // Arc with rounded ends
626  break;
627 
628  case S_CURVE: // Bezier with rounded ends
629  geom_transf( shape->m_Ctrl1, currMoveVect, scale, curr_rotation );
630  geom_transf( shape->m_Ctrl2, currMoveVect, scale, curr_rotation );
631  break;
632 
633  case S_CIRCLE: // ring or circle
634  shape->m_Radius = KiROUND( shape->m_Radius * scale );
635  break;
636 
637  case S_POLYGON: // polygon
638  for( unsigned ii = 0; ii < shape->m_Poly.size(); ++ii )
639  geom_transf( shape->m_Poly[ii], currMoveVect, scale, curr_rotation );
640  break;
641 
642  default:
643  break;
644  }
645  }
646 
647  // Prepare new transform on duplication:
648  // Each new item is rotated (or moved) by the transform from the last duplication
649  curr_rotation += rotation;
650  currMoveVect += move_vect;
651  } while( aList && --aDuplicateCount > 0 );
652 }
653 
DIALOG_PAD_PRIMITIVES_PROPERTIES(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PAD_CS_PRIMITIVE *aShape)
const BITMAP_OPAQUE trash_xpm[1]
Definition: trash.cpp:46
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:120
EDA_COLOR_T
NOTE: EDA_COLOR_T is deprecated and is kept around for compatibility with legacy canvas.
Definition: colors.h:42
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
Class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE.
wxPoint m_Start
angle of an arc, from its starting point, in 0.1 deg
Definition: class_pad.h:98
int color
Definition: DXF_plotter.cpp:61
polygon (not yet used for tracks, but could be in microwave apps)
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:234
usual segment : line with rounded ends
void OnButtonDelete(wxCommandEvent &event) override
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void Transform(std::vector< PAD_CS_PRIMITIVE > *aList=NULL, int aDuplicateCount=0)
Apply geometric transform (rotation, move, scale) defined in dialog aDuplicate = 1 .
int PointCount() const
Function PointCount()
DIALOG_PAD_PRIMITIVES_TRANSFORM(wxWindow *aParent, PCB_BASE_FRAME *aFrame, std::vector< PAD_CS_PRIMITIVE * > &aList, bool aShowDuplicate)
const OPT< INTERSECTION > SelfIntersecting() const
Function SelfIntersecting()
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
wxPoint m_Ctrl1
is also the start point of the arc
Definition: class_pad.h:100
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
This file contains miscellaneous commonly used macros and functions.
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
Classes used in Pcbnew, CvPcb and GerbView.
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:132
Class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE.
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:80
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void SetClosed(bool aClosed)
Function SetClosed()
bool TransferDataToWindow() override
Function TransferDataToWindow Transfer data into the GUI.
void geom_transf(wxPoint &aCoord, wxPoint &aMove, double aScale, double aRotation)
void Show(bool aShow, bool aResize=false)
Function Show Shows/hides the label, widget and units label.
bool TransferDataToWindow() override
Function TransferDataToWindow Transfer data into the GUI.
int m_Radius
thickness of segment or outline For filled S_CIRCLE shape, thickness = 0.
Definition: class_pad.h:96
std::vector< wxPoint > m_Poly
Bezier Control point 2.
Definition: class_pad.h:102
#define NULL
void onGridSelect(wxGridRangeSelectEvent &event) override
const BITMAP_OPAQUE dialog_warning_xpm[1]
Arcs (with rounded ends)
Helper class to handle a primitive (basic shape: polygon, segment, circle or arc) to build a custom p...
Definition: class_pad.h:89
DIALOG_PAD_PRIMITIVE_POLY_PROPS(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PAD_CS_PRIMITIVE *aShape)
void onPolyPanelResize(wxSizeEvent &event) override
Definition: colors.h:60
Bezier Curve.
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:172
wxPoint m_End
is also the center of the circle and arc
Definition: class_pad.h:99
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:230
STROKE_T m_Shape
Definition: class_pad.h:92
void onPaintPolyPanel(wxPaintEvent &event) override
wxPoint m_Ctrl2
Bezier Control point 1.
Definition: class_pad.h:101
void OnButtonAdd(wxCommandEvent &event) override
int m_Thickness
S_SEGMENT, S_ARC, S_CIRCLE, S_POLYGON only (same as DRAWSEGMENT)
Definition: class_pad.h:93
const int scale
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
std::vector< PAD_CS_PRIMITIVE * > & m_list
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
The common library.
Definition: colors.h:49
virtual long long int GetValue()
Function GetValue Returns the current value in Internal Units.
long long int ValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, bool aUseMils)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: base_units.cpp:444
Module description (excepted pads)
bool doValidate(bool aRemoveRedundantCorners)
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, bool aUseMils)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:331
const BITMAP_OPAQUE small_plus_xpm[1]
Definition: small_plus.cpp:20
PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
double m_ArcAngle
radius of a circle
Definition: class_pad.h:97
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
virtual void SetUnits(EDA_UNITS aUnits, bool aUseMils=false)
Function SetUnits Normally not needed (as the UNIT_BINDER inherits from the parent frame),...
Definition: unit_binder.cpp:68
bool Validate() override
test for a valid polygon (a not self intersectiong polygon)
Class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE.