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-2021 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 <confirm.h>
33 #include <trigo.h>
34 #include <pcb_base_frame.h>
35 #include <base_units.h>
36 #include <widgets/wx_grid.h>
37 #include <footprint.h>
38 #include <math/util.h> // for KiROUND
39 
40 #include <dialog_pad_properties.h>
41 #include <bitmaps.h>
42 #include <wx/dcclient.h>
43 
44 
46  PCB_BASE_FRAME* aFrame,
47  PCB_SHAPE* aShape ) :
49  m_shape( aShape ),
50  m_startX( aFrame, m_startXLabel, m_startXCtrl, m_startXUnits ),
51  m_startY( aFrame, m_startYLabel, m_startYCtrl, m_startYUnits ),
52  m_ctrl1X( aFrame, m_ctrl1XLabel, m_ctrl1XCtrl, m_ctrl1XUnits ),
53  m_ctrl1Y( aFrame, m_ctrl1YLabel, m_ctrl1YCtrl, m_ctrl1YUnits ),
54  m_ctrl2X( aFrame, m_ctrl2XLabel, m_ctrl2XCtrl, m_ctrl2XUnits ),
55  m_ctrl2Y( aFrame, m_ctrl2YLabel, m_ctrl2YCtrl, m_ctrl2YUnits ),
56  m_endX( aFrame, m_endXLabel, m_endXCtrl, m_endXUnits ),
57  m_endY( aFrame, m_endYLabel, m_endYCtrl, m_endYUnits ),
58  m_radius( aFrame, m_radiusLabel, m_radiusCtrl, m_radiusUnits ),
59  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits )
60 {
62 
64 
65  m_sdbSizerOK->SetDefault();
66 
68 }
69 
70 
72 {
73  if( m_shape == nullptr )
74  return false;
75 
77  m_filledCtrl->SetValue( m_shape->IsFilled() );
78 
79  switch( m_shape->GetShape() )
80  {
81  case SHAPE_T::SEGMENT:
82  SetTitle( _( "Segment" ) );
85  m_endX.SetValue( m_shape->GetEnd().x );
86  m_endY.SetValue( m_shape->GetEnd().y );
87  m_ctrl1X.Show( false, true );
88  m_ctrl1Y.Show( false, true );
89  m_ctrl2X.Show( false, true );
90  m_ctrl2Y.Show( false, true );
91  m_staticTextPosCtrl1->Show( false );
92  m_staticTextPosCtrl1->SetSize( 0, 0 );
93  m_staticTextPosCtrl2->Show( false );
94  m_staticTextPosCtrl2->SetSize( 0, 0 );
95  m_radius.Show( false );
96  m_filledCtrl->Show( false );
97  break;
98 
99  case SHAPE_T::BEZIER:
100  SetTitle( _( "Bezier" ) );
103  m_endX.SetValue( m_shape->GetEnd().x );
104  m_endY.SetValue( m_shape->GetEnd().y );
109  m_radius.Show( false );
110  m_filledCtrl->Show( false );
111  break;
112 
113  case SHAPE_T::ARC:
114  SetTitle( _( "Arc" ) );
117  m_staticTextPosEnd->SetLabel( _( "Center" ) );
120  m_radiusLabel->SetLabel( _( "Angle:" ) );
123  m_ctrl1X.Show( false, true );
124  m_ctrl1Y.Show( false, true );
125  m_ctrl2X.Show( false, true );
126  m_ctrl2Y.Show( false, true );
127  m_staticTextPosCtrl1->Show( false );
128  m_staticTextPosCtrl1->SetSize( 0, 0 );
129  m_staticTextPosCtrl2->Show( false );
130  m_staticTextPosCtrl2->SetSize( 0, 0 );
131  m_filledCtrl->Show( false );
132  break;
133 
134  case SHAPE_T::CIRCLE:
135  if( m_shape->GetWidth() )
136  SetTitle( _( "Ring" ) );
137  else
138  SetTitle( _( "Circle" ) );
139 
140  // End point does not exist for a circle or ring:
141  m_staticTextPosEnd->Show( false );
142  m_endX.Show( false );
143  m_endY.Show( false );
144 
145  // Circle center uses position controls:
146  m_staticTextPosStart->SetLabel( _( "Center:" ) );
150  m_ctrl1X.Show( false, true );
151  m_ctrl1Y.Show( false, true );
152  m_ctrl2X.Show( false, true );
153  m_ctrl2Y.Show( false, true );
154  m_staticTextPosCtrl1->Show( false );
155  m_staticTextPosCtrl1->SetSize( 0, 0 );
156  m_staticTextPosCtrl2->Show( false );
157  m_staticTextPosCtrl2->SetSize( 0, 0 );
158  m_filledCtrl->Show( true );
159  break;
160 
161  case SHAPE_T::POLY:
162  // polygon has a specific dialog editor. So nothing here
163  break;
164 
165  default:
166  SetTitle( "Unknown basic shape" );
167  break;
168  }
169 
170  return true;
171 }
172 
173 
175 {
176  if( m_thickness.GetValue() == 0 && !m_filledCtrl->GetValue() )
177  {
178  DisplayError( this, _( "Line width may not be 0 for unfilled shapes." ) );
179  m_thicknessCtrl->SetFocus();
180  return false;
181  }
182 
183  // Transfer data out of the GUI.
185  m_shape->SetFilled( m_filledCtrl->GetValue() );
186 
187  switch( m_shape->GetShape() )
188  {
189  case SHAPE_T::SEGMENT:
190  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
191  m_shape->SetEnd( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
192  break;
193 
194  case SHAPE_T::BEZIER:
195  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
196  m_shape->SetEnd( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
199  break;
200 
201  case SHAPE_T::ARC:
202  m_shape->SetCenter( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
203  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
205  break;
206 
207  case SHAPE_T::CIRCLE:
208  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
209  m_shape->SetEnd( m_shape->GetStart() + wxPoint( m_radius.GetValue(), 0 ) );
210  break;
211 
212  case SHAPE_T::POLY:
213  // polygon has a specific dialog editor. So nothing here
214  break;
215 
216  default:
217  SetTitle( "Unknown basic shape" );
218  break;
219  }
220 
221  return true;
222 }
223 
224 
226  PCB_BASE_FRAME* aFrame,
227  PCB_SHAPE* aShape ) :
229  m_shape( aShape ),
230  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits )
231 {
232  if( !m_shape->GetPolyShape().IsEmpty() )
233  {
234  for( const VECTOR2I& pt : m_shape->GetPolyShape().Outline( 0 ).CPoints() )
235  m_currPoints.emplace_back( pt );
236  }
237 
238  m_addButton->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
241 
242  // Test for acceptable polygon (more than 2 corners, and not self-intersecting) and
243  // remove any redundant corners. A warning message is displayed if not OK.
244  doValidate( true );
245 
247 
248  m_sdbSizerOK->SetDefault();
249  GetSizer()->SetSizeHints( this );
250 
251  m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
253  nullptr, this );
254 
255  // Now all widgets have the size fixed, call FinishDialogSettings
257 }
258 
259 
261 {
262  m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING,
264  nullptr, this );
265 }
266 
267 
269 {
270  if( m_shape == nullptr )
271  return false;
272 
274  m_filledCtrl->SetValue( m_shape->IsFilled() );
275 
276  // Populates the list of corners
277  int extra_rows = m_currPoints.size() - m_gridCornersList->GetNumberRows();
278 
279  if( extra_rows > 0 )
280  {
281  m_gridCornersList->AppendRows( extra_rows );
282  }
283  else if( extra_rows < 0 )
284  {
285  extra_rows = -extra_rows;
286  m_gridCornersList->DeleteRows( 0, extra_rows );
287  }
288 
289  // enter others corner coordinates
290  wxString msg;
291 
292  for( unsigned row = 0; row < m_currPoints.size(); ++row )
293  {
294  // Row label is "Corner x"
295  msg.Printf( "Corner %d", row+1 );
296  m_gridCornersList->SetRowLabelValue( row, msg );
297 
298  msg = StringFromValue( GetUserUnits(), m_currPoints[row].x );
299  m_gridCornersList->SetCellValue( row, 0, msg );
300 
301  msg = StringFromValue( GetUserUnits(), m_currPoints[row].y );
302  m_gridCornersList->SetCellValue( row, 1, msg );
303  }
304 
305  return true;
306 }
307 
309 {
310  if( !Validate() )
311  return false;
312 
315  m_shape->SetFilled( m_filledCtrl->GetValue() );
316 
317  return true;
318 }
319 
320 
322 {
323  // Don't remove redundant corners while user is editing corner list
324  return doValidate( false );
325 }
326 
327 
328 bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
329 {
331  return false;
332 
333  if( m_currPoints.size() < 3 )
334  {
335  m_warningText->SetLabel( _("Polygon must have at least 3 corners" ) );
336  m_warningText->Show( true );
337  m_warningIcon->Show( true );
338  return false;
339  }
340 
341  bool valid = true;
342 
343  SHAPE_LINE_CHAIN polyline( m_currPoints, true );
344 
345  // Remove redundant corners:
346  polyline.Simplify();
347 
348  if( polyline.PointCount() < 3 )
349  {
350  m_warningText->SetLabel( _( "Polygon must have at least 3 corners after simplification" ) );
351  valid = false;
352  }
353 
354  if( valid && polyline.SelfIntersecting() )
355  {
356  m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
357  valid = false;
358  }
359 
360  m_warningIcon->Show( !valid );
361  m_warningText->Show( !valid );
362 
363  if( aRemoveRedundantCorners )
364  {
365  if( polyline.PointCount() != (int) m_currPoints.size() )
366  { // Happens after simplification
367  m_currPoints.clear();
368 
369  for( const VECTOR2I& pt : polyline.CPoints() )
370  m_currPoints.emplace_back( pt );
371 
372  m_warningIcon->Show( true );
373  m_warningText->Show( true );
374  m_warningText->SetLabel( _( "Note: redundant corners removed" ) );
375  }
376  }
377 
378  return valid;
379 }
380 
381 
382 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonAdd( wxCommandEvent& event )
383 {
385  return;
386 
387  // Insert a new corner after the currently selected:
388  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
389  int row = -1;
390 
391  if( m_gridCornersList->GetNumberRows() == 0 )
392  row = 0;
393  else if( selections.size() > 0 )
394  row = selections[ selections.size() - 1 ] + 1;
395  else
396  row = m_gridCornersList->GetGridCursorRow() + 1;
397 
398  if( row < 0 )
399  {
400  wxMessageBox( _( "Select a corner to add the new corner after." ) );
401  return;
402  }
403 
404  if( m_currPoints.size() == 0 || row >= (int) m_currPoints.size() )
405  m_currPoints.emplace_back( 0, 0 );
406  else
407  m_currPoints.insert( m_currPoints.begin() + row, wxPoint( 0, 0 ) );
408 
409  Validate();
411 
412  m_gridCornersList->ForceRefresh();
413  // Select the new row
414  m_gridCornersList->SelectRow( row, false );
415 
416  m_panelPoly->Refresh();
417 }
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_currPoints.erase( m_currPoints.begin() + selections[ii] );
444 
445  Validate();
447 
448  m_gridCornersList->ForceRefresh();
449 
450  // select the row previous to the last deleted row
451  m_gridCornersList->SelectRow( std::max( 0, selections[ 0 ] - 1 ) );
452 
453  m_panelPoly->Refresh();
454 }
455 
456 
458 {
459  wxPaintDC dc( m_panelPoly );
460  wxSize dc_size = dc.GetSize();
461  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
462 
463  // Calculate a suitable scale to fit the available draw area
464  int minsize( Millimeter2iu( 0.5 ) );
465 
466  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
467  {
468  minsize = std::max( minsize, std::abs( m_currPoints[ii].x ) );
469  minsize = std::max( minsize, std::abs( m_currPoints[ii].y ) );
470  }
471 
472  // The draw origin is the center of the window.
473  // Therefore the window size is twice the minsize just calculated
474  minsize *= 2;
475  minsize += m_thickness.GetValue();
476 
477  // Give a margin
478  double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;
479 
480  GRResetPenAndBrush( &dc );
481 
482  // Draw X and Y axis. This is particularly useful to show the
483  // reference position of basic shape
484  // Axis are drawn before the polygon to avoid masking segments on axis
485  GRLine( nullptr, &dc, -dc_size.x, 0, dc_size.x, 0, 0, LIGHTBLUE ); // X axis
486  GRLine( nullptr, &dc, 0, -dc_size.y, 0, dc_size.y, 0, LIGHTBLUE ); // Y axis
487 
488  // Draw polygon.
489  // The selected edge(s) are shown in selectcolor, the others in normalcolor.
490  EDA_COLOR_T normalcolor = WHITE;
491  EDA_COLOR_T selectcolor = RED;
492 
493  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
494  {
495  EDA_COLOR_T color = normalcolor;
496 
497  if( m_gridCornersList->IsInSelection (ii, 0) ||
498  m_gridCornersList->IsInSelection (ii, 1) ||
499  m_gridCornersList->GetGridCursorRow() == (int)ii )
500  color = selectcolor;
501 
502  unsigned jj = ii + 1;
503 
504  if( jj >= m_currPoints.size() )
505  jj = 0;
506 
507  GRLine( nullptr, &dc, m_currPoints[ii] * scale, m_currPoints[jj] * scale,
509  }
510 
511  event.Skip();
512 }
513 
514 
516 {
517  m_panelPoly->Refresh();
518  event.Skip();
519 }
520 
521 
522 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onGridSelect( wxGridRangeSelectEvent& event )
523 {
524  m_panelPoly->Refresh();
525 }
526 
527 
529 {
530  int row = event.GetRow();
531  int col = event.GetCol();
532  wxString msg = event.GetString();
533 
534  if( msg.IsEmpty() )
535  return;
536 
537  if( col == 0 ) // Set the X value
538  m_currPoints[row].x = ValueFromString( GetUserUnits(), msg );
539  else // Set the Y value
540  m_currPoints[row].y = ValueFromString( GetUserUnits(), msg );
541 
542  Validate();
543 
544  m_panelPoly->Refresh();
545 }
546 
547 
549  PCB_BASE_FRAME* aFrame,
550  std::vector<std::shared_ptr<PCB_SHAPE>>& aList,
551  bool aShowDuplicate ) :
553  m_list( aList ),
554  m_vectorX( aFrame, m_xLabel, m_xCtrl, m_xUnits ),
555  m_vectorY( aFrame, m_yLabel, m_yCtrl, m_yUnits ),
556  m_rotation( aFrame, m_rotationLabel, m_rotationCtrl, m_rotationUnits )
557 {
559 
560  if( !aShowDuplicate ) // means no duplicate transform
561  {
562  m_staticTextDupCnt->Show( false );
563  m_spinCtrlDuplicateCount->Show( false );
564  }
565 
566  m_sdbSizerOK->SetDefault();
567  GetSizer()->SetSizeHints( this );
568 }
569 
570 
571 // A helper function in geometry transform
572 inline void geom_transf( wxPoint& aCoord, const wxPoint& aMove, double aScale, double aRotation )
573 {
574  aCoord.x = KiROUND( aCoord.x * aScale );
575  aCoord.y = KiROUND( aCoord.y * aScale );
576  aCoord += aMove;
577  RotatePoint( &aCoord, aRotation );
578 }
579 
580 
581 void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<std::shared_ptr<PCB_SHAPE>>* aList,
582  int aDuplicateCount )
583 {
584  wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
585  double rotation = m_rotation.GetValue();
587 
588  // Avoid too small / too large scale, which could create issues:
589  if( scale < 0.01 )
590  scale = 0.01;
591 
592  if( scale > 100.0 )
593  scale = 100.0;
594 
595  // Transform shapes
596  // shapes are scaled, then moved then rotated.
597  // if aList != NULL, the initial shape will be duplicated, and transform
598  // applied to the duplicated shape
599 
600  wxPoint currMoveVect = move_vect;
601  double curr_rotation = rotation;
602 
603  do {
604  for( unsigned idx = 0; idx < m_list.size(); ++idx )
605  {
606  std::shared_ptr<PCB_SHAPE> shape;
607 
608  if( aList == nullptr )
609  {
610  shape = m_list[idx];
611  }
612  else
613  {
614  aList->emplace_back( std::make_shared<PCB_SHAPE>( *m_list[idx] ) );
615  shape = aList->back();
616  }
617 
618  // Transform parameters common to all shape types (some can be unused)
619  shape->SetWidth( KiROUND( shape->GetWidth() * scale ) );
620  shape->Move( currMoveVect );
621  shape->Scale( scale );
622  shape->Rotate( wxPoint( 0, 0 ), curr_rotation );
623  }
624 
625  // Prepare new transform on duplication:
626  // Each new item is rotated (or moved) by the transform from the last duplication
627  curr_rotation += rotation;
628  currMoveVect += move_vect;
629  } while( aList && --aDuplicateCount > 0 );
630 }
631 
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:279
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:111
int GetWidth() const
Definition: eda_shape.h:89
void SetFilled(bool aFlag)
Definition: eda_shape.h:83
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:126
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.
const wxPoint & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:97
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
int color
Definition: DXF_plotter.cpp:57
bool IsEmpty() const
double GetArcAngle() const
Definition: eda_shape.cpp:497
DIALOG_PAD_PRIMITIVE_POLY_PROPS(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PCB_SHAPE *aShape)
void SetArcAngleAndEnd(double aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
Definition: eda_shape.cpp:508
void OnButtonDelete(wxCommandEvent &event) override
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
int PointCount() const
Return the number of points (vertices) in this line chain.
const OPT< INTERSECTION > SelfIntersecting() const
Check if the line chain is self-intersecting.
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:97
void SetBezierC1(const wxPoint &aPt)
Definition: eda_shape.h:144
bool TransferDataFromWindow() override
Transfer data out of the GUI.
Classes used in Pcbnew, CvPcb and GerbView.
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
Class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE.
bool IsFilled() const
Definition: eda_shape.h:81
DIALOG_PAD_PRIMITIVES_TRANSFORM(wxWindow *aParent, PCB_BASE_FRAME *aFrame, std::vector< std::shared_ptr< PCB_SHAPE >> &aList, bool aShowDuplicate)
void SetStart(const wxPoint &aStart)
Definition: eda_shape.h:101
const wxPoint & GetBezierC1() const
Definition: eda_shape.h:145
void Transform(std::vector< std::shared_ptr< PCB_SHAPE >> *aList=nullptr, int aDuplicateCount=0)
Apply geometric transform (rotation, move, scale) defined in dialog aDuplicate = 1 .
bool TransferDataToWindow() override
Function TransferDataToWindow Transfer data into the GUI.
const wxPoint & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:122
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
bool TransferDataToWindow() override
Transfer data into the GUI.
void onGridSelect(wxGridRangeSelectEvent &event) override
const std::vector< VECTOR2I > & CPoints() const
long long int ValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application.
Definition: base_units.cpp:416
SHAPE_LINE_CHAIN & Outline(int aIndex)
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.h:79
const wxPoint & GetBezierC2() const
Definition: eda_shape.h:148
void onPolyPanelResize(wxSizeEvent &event) override
#define _(s)
DIALOG_PAD_PRIMITIVES_PROPERTIES(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PCB_SHAPE *aShape)
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:212
void SetWidth(int aWidth)
Definition: eda_shape.h:88
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:190
void SetCenter(const wxPoint &aCenter)
Definition: eda_shape.cpp:418
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
Definition: color4d.h:59
void onPaintPolyPanel(wxPaintEvent &event) override
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:207
void geom_transf(wxPoint &aCoord, const wxPoint &aMove, double aScale, double aRotation)
EDA_COLOR_T
Legacy color enumeration.
Definition: color4d.h:41
void OnButtonAdd(wxCommandEvent &event) override
Definition: color4d.h:48
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
Definition: unit_binder.cpp:92
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
Definition: eda_shape.cpp:1034
const int scale
Represent a polyline (an zero-thickness chain of connected line segments).
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
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:73
virtual long long int GetValue()
Return the current value in Internal Units.
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:204
SHAPE_T GetShape() const
Definition: eda_shape.h:92
bool doValidate(bool aRemoveRedundantCorners)
int GetRadius() const
Definition: eda_shape.cpp:465
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:307
static constexpr int Millimeter2iu(double mm)
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
std::vector< std::shared_ptr< PCB_SHAPE > > & m_list
bool TransferDataFromWindow() override
Transfer data out of the GUI.
bool Validate() override
Test for a valid polygon (a not self intersectiong polygon).
Class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE.