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 
250  m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
252  nullptr, this );
253 
254  // Now all widgets have the size fixed, call FinishDialogSettings
256 }
257 
258 
260 {
261  m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING,
263  nullptr, this );
264 }
265 
266 
268 {
269  if( m_shape == nullptr )
270  return false;
271 
273  m_filledCtrl->SetValue( m_shape->IsFilled() );
274 
275  // Populates the list of corners
276  int extra_rows = m_currPoints.size() - m_gridCornersList->GetNumberRows();
277 
278  if( extra_rows > 0 )
279  {
280  m_gridCornersList->AppendRows( extra_rows );
281  }
282  else if( extra_rows < 0 )
283  {
284  extra_rows = -extra_rows;
285  m_gridCornersList->DeleteRows( 0, extra_rows );
286  }
287 
288  // enter others corner coordinates
289  wxString msg;
290 
291  for( unsigned row = 0; row < m_currPoints.size(); ++row )
292  {
293  // Row label is "Corner x"
294  msg.Printf( _( "Corner %d" ), row+1 );
295  m_gridCornersList->SetRowLabelValue( row, msg );
296 
297  msg = StringFromValue( GetUserUnits(), m_currPoints[row].x, true );
298  m_gridCornersList->SetCellValue( row, 0, msg );
299 
300  msg = StringFromValue( GetUserUnits(), m_currPoints[row].y, true );
301  m_gridCornersList->SetCellValue( row, 1, msg );
302  }
303 
304  return true;
305 }
306 
308 {
309  if( !Validate() )
310  return false;
311 
314  m_shape->SetFilled( m_filledCtrl->GetValue() );
315 
316  return true;
317 }
318 
319 
321 {
322  // Don't remove redundant corners while user is editing corner list
323  return doValidate( false );
324 }
325 
326 
327 bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
328 {
330  return false;
331 
332  if( m_currPoints.size() < 3 )
333  {
334  m_warningText->SetLabel( _("Polygon must have at least 3 corners" ) );
335  m_warningText->Show( true );
336  m_warningIcon->Show( true );
337  return false;
338  }
339 
340  bool valid = true;
341 
342  SHAPE_LINE_CHAIN polyline( m_currPoints, true );
343 
344  // Remove redundant corners:
345  polyline.Simplify();
346 
347  if( polyline.PointCount() < 3 )
348  {
349  m_warningText->SetLabel( _( "Polygon must have at least 3 corners after simplification" ) );
350  valid = false;
351  }
352 
353  if( valid && polyline.SelfIntersecting() )
354  {
355  m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
356  valid = false;
357  }
358 
359  m_warningIcon->Show( !valid );
360  m_warningText->Show( !valid );
361 
362  if( aRemoveRedundantCorners )
363  {
364  if( polyline.PointCount() != (int) m_currPoints.size() )
365  { // Happens after simplification
366  m_currPoints.clear();
367 
368  for( const VECTOR2I& pt : polyline.CPoints() )
369  m_currPoints.emplace_back( pt );
370 
371  m_warningIcon->Show( true );
372  m_warningText->Show( true );
373  m_warningText->SetLabel( _( "Note: redundant corners removed" ) );
374  }
375  }
376 
377  return valid;
378 }
379 
380 
381 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonAdd( wxCommandEvent& event )
382 {
384  return;
385 
386  // Insert a new corner after the currently selected:
387  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
388  int row = -1;
389 
390  if( m_gridCornersList->GetNumberRows() == 0 )
391  row = 0;
392  else if( selections.size() > 0 )
393  row = selections[ selections.size() - 1 ] + 1;
394  else
395  row = m_gridCornersList->GetGridCursorRow() + 1;
396 
397  if( row < 0 )
398  {
399  wxMessageBox( _( "Select a corner to add the new corner after." ) );
400  return;
401  }
402 
403  if( m_currPoints.size() == 0 || row >= (int) m_currPoints.size() )
404  m_currPoints.emplace_back( 0, 0 );
405  else
406  m_currPoints.insert( m_currPoints.begin() + row, wxPoint( 0, 0 ) );
407 
408  Validate();
410 
411  m_gridCornersList->ForceRefresh();
412  // Select the new row
413  m_gridCornersList->SelectRow( row, false );
414 
415  m_panelPoly->Refresh();
416 }
417 
418 
420 {
422  return;
423 
424  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
425 
426  if( m_gridCornersList->GetNumberRows() == 0 )
427  return;
428 
429  if( selections.size() == 0 && m_gridCornersList->GetGridCursorRow() >= 0 )
430  selections.push_back( m_gridCornersList->GetGridCursorRow() );
431 
432  if( selections.size() == 0 )
433  {
434  wxMessageBox( _( "Select a corner to delete." ) );
435  return;
436  }
437 
438  // remove corners:
439  std::sort( selections.begin(), selections.end() );
440 
441  for( int ii = selections.size()-1; ii >= 0 ; --ii )
442  m_currPoints.erase( m_currPoints.begin() + selections[ii] );
443 
444  Validate();
446 
447  m_gridCornersList->ForceRefresh();
448 
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 
455 
457 {
458  wxPaintDC dc( m_panelPoly );
459  wxSize dc_size = dc.GetSize();
460  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
461 
462  // Calculate a suitable scale to fit the available draw area
463  int minsize( Millimeter2iu( 0.5 ) );
464 
465  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
466  {
467  minsize = std::max( minsize, std::abs( m_currPoints[ii].x ) );
468  minsize = std::max( minsize, std::abs( m_currPoints[ii].y ) );
469  }
470 
471  // The draw origin is the center of the window.
472  // Therefore the window size is twice the minsize just calculated
473  minsize *= 2;
474  minsize += m_thickness.GetValue();
475 
476  // Give a margin
477  double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;
478 
479  GRResetPenAndBrush( &dc );
480 
481  // Draw X and Y axis. This is particularly useful to show the
482  // reference position of basic shape
483  // Axis are drawn before the polygon to avoid masking segments on axis
484  GRLine( nullptr, &dc, -dc_size.x, 0, dc_size.x, 0, 0, LIGHTBLUE ); // X axis
485  GRLine( nullptr, &dc, 0, -dc_size.y, 0, dc_size.y, 0, LIGHTBLUE ); // Y axis
486 
487  // Draw polygon.
488  // The selected edge(s) are shown in selectcolor, the others in normalcolor.
489  EDA_COLOR_T normalcolor = WHITE;
490  EDA_COLOR_T selectcolor = RED;
491 
492  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
493  {
494  EDA_COLOR_T color = normalcolor;
495 
496  if( m_gridCornersList->IsInSelection (ii, 0) ||
497  m_gridCornersList->IsInSelection (ii, 1) ||
498  m_gridCornersList->GetGridCursorRow() == (int)ii )
499  color = selectcolor;
500 
501  unsigned jj = ii + 1;
502 
503  if( jj >= m_currPoints.size() )
504  jj = 0;
505 
506  GRLine( nullptr, &dc, m_currPoints[ii] * scale, m_currPoints[jj] * scale,
508  }
509 
510  event.Skip();
511 }
512 
513 
515 {
516  m_panelPoly->Refresh();
517  event.Skip();
518 }
519 
520 
521 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onGridSelect( wxGridRangeSelectEvent& event )
522 {
523  m_panelPoly->Refresh();
524 }
525 
526 
528 {
529  int row = event.GetRow();
530  int col = event.GetCol();
531  wxString msg = event.GetString();
532 
533  if( msg.IsEmpty() )
534  return;
535 
536  if( col == 0 ) // Set the X value
537  m_currPoints[row].x = ValueFromString( GetUserUnits(), msg );
538  else // Set the Y value
539  m_currPoints[row].y = ValueFromString( GetUserUnits(), msg );
540 
541  Validate();
542 
543  m_panelPoly->Refresh();
544 }
545 
546 
548  PCB_BASE_FRAME* aFrame,
549  std::vector<std::shared_ptr<PCB_SHAPE>>& aList,
550  bool aShowDuplicate ) :
552  m_list( aList ),
553  m_vectorX( aFrame, m_xLabel, m_xCtrl, m_xUnits ),
554  m_vectorY( aFrame, m_yLabel, m_yCtrl, m_yUnits ),
555  m_rotation( aFrame, m_rotationLabel, m_rotationCtrl, m_rotationUnits )
556 {
558 
559  if( !aShowDuplicate ) // means no duplicate transform
560  {
561  m_staticTextDupCnt->Show( false );
562  m_spinCtrlDuplicateCount->Show( false );
563  }
564 
565  m_sdbSizerOK->SetDefault();
566  GetSizer()->SetSizeHints( this );
567 }
568 
569 
570 // A helper function in geometry transform
571 inline void geom_transf( wxPoint& aCoord, const wxPoint& aMove, double aScale, double aRotation )
572 {
573  aCoord.x = KiROUND( aCoord.x * aScale );
574  aCoord.y = KiROUND( aCoord.y * aScale );
575  aCoord += aMove;
576  RotatePoint( &aCoord, aRotation );
577 }
578 
579 
580 void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<std::shared_ptr<PCB_SHAPE>>* aList,
581  int aDuplicateCount )
582 {
583  wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
584  double rotation = m_rotation.GetValue();
586 
587  // Avoid too small / too large scale, which could create issues:
588  if( scale < 0.01 )
589  scale = 0.01;
590 
591  if( scale > 100.0 )
592  scale = 100.0;
593 
594  // Transform shapes
595  // shapes are scaled, then moved then rotated.
596  // if aList != NULL, the initial shape will be duplicated, and transform
597  // applied to the duplicated shape
598 
599  wxPoint currMoveVect = move_vect;
600  double curr_rotation = rotation;
601 
602  do {
603  for( unsigned idx = 0; idx < m_list.size(); ++idx )
604  {
605  std::shared_ptr<PCB_SHAPE> shape;
606 
607  if( aList == nullptr )
608  {
609  shape = m_list[idx];
610  }
611  else
612  {
613  aList->emplace_back( std::make_shared<PCB_SHAPE>( *m_list[idx] ) );
614  shape = aList->back();
615  }
616 
617  // Transform parameters common to all shape types (some can be unused)
618  shape->SetWidth( KiROUND( shape->GetWidth() * scale ) );
619  shape->Move( currMoveVect );
620  shape->Scale( scale );
621  shape->Rotate( wxPoint( 0, 0 ), curr_rotation );
622  }
623 
624  // Prepare new transform on duplication:
625  // Each new item is rotated (or moved) by the transform from the last duplication
626  curr_rotation += rotation;
627  currMoveVect += move_vect;
628  } while( aList && --aDuplicateCount > 0 );
629 }
630 
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:107
int GetWidth() const
Definition: eda_shape.h:98
void SetFilled(bool aFlag)
Definition: eda_shape.h:92
void SetEnd(const wxPoint &aEnd)
Definition: eda_shape.h:135
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:106
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:536
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:547
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:153
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:90
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:110
const wxPoint & GetBezierC1() const
Definition: eda_shape.h:154
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:131
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:157
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:197
void SetWidth(int aWidth)
Definition: eda_shape.h:97
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:226
void SetCenter(const wxPoint &aCenter)
Definition: eda_shape.cpp:419
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:227
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:1085
const int scale
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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
void SetBezierC2(const wxPoint &aPt)
Definition: eda_shape.h:156
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:101
bool doValidate(bool aRemoveRedundantCorners)
int GetRadius() const
Definition: eda_shape.cpp:472
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.