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-2020 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 
44  PCB_BASE_FRAME* aFrame,
45  PCB_SHAPE* aShape ) :
47  m_shape( aShape ),
48  m_startX( aFrame, m_startXLabel, m_startXCtrl, m_startXUnits, true ),
49  m_startY( aFrame, m_startYLabel, m_startYCtrl, m_startYUnits, true ),
50  m_ctrl1X( aFrame, m_ctrl1XLabel, m_ctrl1XCtrl, m_ctrl1XUnits, true ),
51  m_ctrl1Y( aFrame, m_ctrl1YLabel, m_ctrl1YCtrl, m_ctrl1YUnits, true ),
52  m_ctrl2X( aFrame, m_ctrl2XLabel, m_ctrl2XCtrl, m_ctrl2XUnits, true ),
53  m_ctrl2Y( aFrame, m_ctrl2YLabel, m_ctrl2YCtrl, m_ctrl2YUnits, true ),
54  m_endX( aFrame, m_endXLabel, m_endXCtrl, m_endXUnits, true ),
55  m_endY( aFrame, m_endYLabel, m_endYCtrl, m_endYUnits, true ),
56  m_radius( aFrame, m_radiusLabel, m_radiusCtrl, m_radiusUnits, true ),
57  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
58 {
60 
62 
63  m_sdbSizerOK->SetDefault();
64 
66 }
67 
69 {
70  if( m_shape == NULL )
71  return false;
72 
74  m_filledCtrl->SetValue( m_shape->IsFilled() );
75 
76  switch( m_shape->GetShape() )
77  {
78  case S_SEGMENT: // Segment with rounded ends
79  SetTitle( _( "Segment" ) );
82  m_endX.SetValue( m_shape->GetEnd().x );
83  m_endY.SetValue( m_shape->GetEnd().y );
84  m_ctrl1X.Show( false, true );
85  m_ctrl1Y.Show( false, true );
86  m_ctrl2X.Show( false, true );
87  m_ctrl2Y.Show( false, true );
88  m_staticTextPosCtrl1->Show( false );
89  m_staticTextPosCtrl1->SetSize( 0, 0 );
90  m_staticTextPosCtrl2->Show( false );
91  m_staticTextPosCtrl2->SetSize( 0, 0 );
92  m_radius.Show( false );
93  m_filledCtrl->Show( false );
94  break;
95 
96  case S_CURVE: // Bezier line
97  SetTitle( _( "Bezier" ) );
100  m_endX.SetValue( m_shape->GetEnd().x );
101  m_endY.SetValue( m_shape->GetEnd().y );
106  m_radius.Show( false );
107  m_filledCtrl->Show( false );
108  break;
109 
110  case S_ARC: // Arc with rounded ends
111  SetTitle( _( "Arc" ) );
112  m_startX.SetValue( m_shape->GetEnd().x ); // confusingly, the start point of the arc
114  m_staticTextPosEnd->SetLabel( _( "Center" ) );
115  m_endX.SetValue( m_shape->GetStart().x ); // arc center
117  m_radiusLabel->SetLabel( _( "Angle:" ) );
120  m_ctrl1X.Show( false, true );
121  m_ctrl1Y.Show( false, true );
122  m_ctrl2X.Show( false, true );
123  m_ctrl2Y.Show( false, true );
124  m_staticTextPosCtrl1->Show( false );
125  m_staticTextPosCtrl1->SetSize( 0, 0 );
126  m_staticTextPosCtrl2->Show( false );
127  m_staticTextPosCtrl2->SetSize( 0, 0 );
128  m_filledCtrl->Show( false );
129  break;
130 
131  case S_CIRCLE: // ring or circle
132  if( m_shape->GetWidth() )
133  SetTitle( _( "Ring" ) );
134  else
135  SetTitle( _( "Circle" ) );
136 
137  // End point does not exist for a circle or ring:
138  m_staticTextPosEnd->Show( false );
139  m_endX.Show( false );
140  m_endY.Show( false );
141 
142  // Circle center uses position controls:
143  m_staticTextPosStart->SetLabel( _( "Center:" ) );
147  m_ctrl1X.Show( false, true );
148  m_ctrl1Y.Show( false, true );
149  m_ctrl2X.Show( false, true );
150  m_ctrl2Y.Show( false, true );
151  m_staticTextPosCtrl1->Show( false );
152  m_staticTextPosCtrl1->SetSize( 0, 0 );
153  m_staticTextPosCtrl2->Show( false );
154  m_staticTextPosCtrl2->SetSize( 0, 0 );
155  m_filledCtrl->Show( true );
156  break;
157 
158  case S_POLYGON: // polygon
159  // polygon has a specific dialog editor. So nothing here
160  break;
161 
162  default:
163  SetTitle( "Unknown basic shape" );
164  break;
165  }
166 
167  return true;
168 }
169 
171 {
172  if( m_thickness.GetValue() == 0 && !m_filledCtrl->GetValue() )
173  {
174  DisplayError( this, _( "Line width may not be 0 for unfilled shapes." ) );
175  m_thicknessCtrl->SetFocus();
176  return false;
177  }
178 
179  // Transfer data out of the GUI.
181  m_shape->SetFilled( m_filledCtrl->GetValue() );
182 
183  switch( m_shape->GetShape() )
184  {
185  case S_SEGMENT: // Segment with rounded ends
186  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
187  m_shape->SetEnd( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
188  break;
189 
190  case S_CURVE: // Segment with rounded ends
191  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
192  m_shape->SetEnd( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
195  break;
196 
197  case S_ARC: // Arc with rounded ends
198  // NB: we store the center of the arc in m_Start, and, confusingly,
199  // the start point in m_End
200  m_shape->SetStart( wxPoint( m_endX.GetValue(), m_endY.GetValue() ) );
201  m_shape->SetEnd( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
202  // arc angle
204  break;
205 
206  case S_CIRCLE: // ring or circle
207  m_shape->SetStart( wxPoint( m_startX.GetValue(), m_startY.GetValue() ) );
208  m_shape->SetEnd( m_shape->GetStart() + wxPoint( m_radius.GetValue(), 0 ) );
209  break;
210 
211  case S_POLYGON: // polygon
212  // polygon has a specific dialog editor. So nothing here
213  break;
214 
215  default:
216  SetTitle( "Unknown basic shape" );
217  break;
218  }
219 
220  return true;
221 }
222 
223 
225  PCB_BASE_FRAME* aFrame,
226  PCB_SHAPE* aShape ) :
228  m_shape( aShape ),
229  m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
230 {
231  if( !m_shape->GetPolyShape().IsEmpty() )
232  {
233  for( const VECTOR2I& pt : m_shape->GetPolyShape().Outline( 0 ).CPoints() )
234  m_currPoints.emplace_back( pt );
235  }
236 
237  m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
238  m_deleteButton->SetBitmap( KiBitmap( small_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  m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
251 
252  // Now all widgets have the size fixed, call FinishDialogSettings
254 }
255 
256 
258 {
259  m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
260 }
261 
262 
264 {
265  if( m_shape == NULL )
266  return false;
267 
269  m_filledCtrl->SetValue( m_shape->IsFilled() );
270 
271  // Populates the list of corners
272  int extra_rows = m_currPoints.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_currPoints.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_currPoints[row].x );
293  m_gridCornersList->SetCellValue( row, 0, msg );
294 
295  msg = StringFromValue( GetUserUnits(), m_currPoints[row].y );
296  m_gridCornersList->SetCellValue( row, 1, msg );
297  }
298 
299  return true;
300 }
301 
303 {
304  if( !Validate() )
305  return false;
306 
309  m_shape->SetFilled( m_filledCtrl->GetValue() );
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_currPoints.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( m_currPoints, true );
339 
340  // Remove redundant corners:
341  polyline.Simplify();
342 
343  if( polyline.PointCount() < 3 )
344  {
345  m_warningText->SetLabel( _( "Polygon must have at least 3 corners after simplification" ) );
346  valid = false;
347  }
348 
349  if( valid && polyline.SelfIntersecting() )
350  {
351  m_warningText->SetLabel( _( "Polygon can not be self-intersecting" ) );
352  valid = false;
353  }
354 
355  m_warningIcon->Show( !valid );
356  m_warningText->Show( !valid );
357 
358  if( aRemoveRedundantCorners )
359  {
360  if( polyline.PointCount() != (int) m_currPoints.size() )
361  { // Happens after simplification
362  m_currPoints.clear();
363 
364  for( const VECTOR2I& pt : polyline.CPoints() )
365  m_currPoints.emplace_back( pt );
366 
367  m_warningIcon->Show( true );
368  m_warningText->Show( true );
369  m_warningText->SetLabel( _( "Note: redundant corners removed" ) );
370  }
371  }
372 
373  return valid;
374 }
375 
376 
377 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonAdd( wxCommandEvent& event )
378 {
380  return;
381 
382  // Insert a new corner after the currently selected:
383  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
384  int row = -1;
385 
386  if( m_gridCornersList->GetNumberRows() == 0 )
387  row = 0;
388  else if( selections.size() > 0 )
389  row = selections[ selections.size() - 1 ] + 1;
390  else
391  row = m_gridCornersList->GetGridCursorRow() + 1;
392 
393  if( row < 0 )
394  {
395  wxMessageBox( _( "Select a corner to add the new corner after." ) );
396  return;
397  }
398 
399  if( m_currPoints.size() == 0 || row >= (int) m_currPoints.size() )
400  m_currPoints.emplace_back( 0, 0 );
401  else
402  m_currPoints.insert( m_currPoints.begin() + row, wxPoint( 0, 0 ) );
403 
404  Validate();
406 
407  m_gridCornersList->ForceRefresh();
408  // Select the new row
409  m_gridCornersList->SelectRow( row, false );
410 
411  m_panelPoly->Refresh();
412 }
413 
415 {
417  return;
418 
419  wxArrayInt selections = m_gridCornersList->GetSelectedRows();
420 
421  if( m_gridCornersList->GetNumberRows() == 0 )
422  return;
423 
424  if( selections.size() == 0 && m_gridCornersList->GetGridCursorRow() >= 0 )
425  selections.push_back( m_gridCornersList->GetGridCursorRow() );
426 
427  if( selections.size() == 0 )
428  {
429  wxMessageBox( _( "Select a corner to delete." ) );
430  return;
431  }
432 
433  // remove corners:
434  std::sort( selections.begin(), selections.end() );
435 
436  for( int ii = selections.size()-1; ii >= 0 ; --ii )
437  m_currPoints.erase( m_currPoints.begin() + selections[ii] );
438 
439  Validate();
441 
442  m_gridCornersList->ForceRefresh();
443  // select the row previous to the last deleted row
444  m_gridCornersList->SelectRow( std::max( 0, selections[ 0 ] - 1 ) );
445 
446  m_panelPoly->Refresh();
447 }
448 
450 {
451  wxPaintDC dc( m_panelPoly );
452  wxSize dc_size = dc.GetSize();
453  dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 );
454 
455  // Calculate a suitable scale to fit the available draw area
456  int minsize( Millimeter2iu( 0.5 ) );
457 
458  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
459  {
460  minsize = std::max( minsize, std::abs( m_currPoints[ii].x ) );
461  minsize = std::max( minsize, std::abs( m_currPoints[ii].y ) );
462  }
463 
464  // The draw origin is the center of the window.
465  // Therefore the window size is twice the minsize just calculated
466  minsize *= 2;
467  minsize += m_thickness.GetValue();
468 
469  // Give a margin
470  double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;
471 
472  GRResetPenAndBrush( &dc );
473 
474  // Draw X and Y axis. This is particularly useful to show the
475  // reference position of basic shape
476  // Axis are drawn before the polygon to avoid masking segments on axis
477  GRLine( NULL, &dc, -dc_size.x, 0, dc_size.x, 0, 0, LIGHTBLUE ); // X axis
478  GRLine( NULL, &dc, 0, -dc_size.y, 0, dc_size.y, 0, LIGHTBLUE ); // Y axis
479 
480  // Draw polygon.
481  // The selected edge(s) are shown in selectcolor, the others in normalcolor.
482  EDA_COLOR_T normalcolor = WHITE;
483  EDA_COLOR_T selectcolor = RED;
484 
485  for( unsigned ii = 0; ii < m_currPoints.size(); ++ii )
486  {
487  EDA_COLOR_T color = normalcolor;
488 
489  if( m_gridCornersList->IsInSelection (ii, 0) ||
490  m_gridCornersList->IsInSelection (ii, 1) ||
491  m_gridCornersList->GetGridCursorRow() == (int)ii )
492  color = selectcolor;
493 
494  unsigned jj = ii + 1;
495 
496  if( jj >= m_currPoints.size() )
497  jj = 0;
498 
500  }
501 
502  event.Skip();
503 }
504 
506 {
507  m_panelPoly->Refresh();
508  event.Skip();
509 }
510 
511 void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onGridSelect( wxGridRangeSelectEvent& event )
512 {
513  m_panelPoly->Refresh();
514 }
515 
517 {
518  int row = event.GetRow();
519  int col = event.GetCol();
520  wxString msg = event.GetString();
521 
522  if( msg.IsEmpty() )
523  return;
524 
525  if( col == 0 ) // Set the X value
526  m_currPoints[row].x = ValueFromString( GetUserUnits(), msg );
527  else // Set the Y value
528  m_currPoints[row].y = ValueFromString( GetUserUnits(), msg );
529 
530  Validate();
531 
532  m_panelPoly->Refresh();
533 }
534 
535 
536 // A dialog to apply geometry transforms to a shape or set of shapes
537 // (move, rotate around origin, scaling factor, duplication).
539  PCB_BASE_FRAME* aFrame,
540  std::vector<std::shared_ptr<PCB_SHAPE>>& aList,
541  bool aShowDuplicate ) :
543  m_list( aList ),
544  m_vectorX( aFrame, m_xLabel, m_xCtrl, m_xUnits, true ),
545  m_vectorY( aFrame, m_yLabel, m_yCtrl, m_yUnits, true ),
546  m_rotation( aFrame, m_rotationLabel, m_rotationCtrl, m_rotationUnits )
547 {
549 
550  if( !aShowDuplicate ) // means no duplicate transform
551  {
552  m_staticTextDupCnt->Show( false );
553  m_spinCtrlDuplicateCount->Show( false );
554  }
555 
556  m_sdbSizerOK->SetDefault();
557  GetSizer()->SetSizeHints( this );
558 }
559 
560 
561 // A helper function in geometry transform
562 inline void geom_transf( wxPoint& aCoord, const wxPoint& aMove, double aScale, double aRotation )
563 {
564  aCoord.x = KiROUND( aCoord.x * aScale );
565  aCoord.y = KiROUND( aCoord.y * aScale );
566  aCoord += aMove;
567  RotatePoint( &aCoord, aRotation );
568 }
569 
570 
571 void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<std::shared_ptr<PCB_SHAPE>>* aList,
572  int aDuplicateCount )
573 {
574  wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
575  double rotation = m_rotation.GetValue();
577 
578  // Avoid too small / too large scale, which could create issues:
579  if( scale < 0.01 )
580  scale = 0.01;
581 
582  if( scale > 100.0 )
583  scale = 100.0;
584 
585  // Transform shapes
586  // shapes are scaled, then moved then rotated.
587  // if aList != NULL, the initial shape will be duplicated, and transform
588  // applied to the duplicated shape
589 
590  wxPoint currMoveVect = move_vect;
591  double curr_rotation = rotation;
592 
593  do {
594  for( unsigned idx = 0; idx < m_list.size(); ++idx )
595  {
596  std::shared_ptr<PCB_SHAPE> shape;
597 
598  if( aList == NULL )
599  shape = m_list[idx];
600  else
601  {
602  aList->emplace_back( std::make_shared<PCB_SHAPE>( *m_list[idx] ) );
603  shape = aList->back();
604  }
605 
606  // Transform parameters common to all shape types (some can be unused)
607  shape->SetWidth( KiROUND( shape->GetWidth() * scale ) );
608  shape->Move( currMoveVect );
609  shape->Scale( scale );
610  shape->Rotate( wxPoint( 0, 0 ), curr_rotation );
611  }
612 
613  // Prepare new transform on duplication:
614  // Each new item is rotated (or moved) by the transform from the last duplication
615  curr_rotation += rotation;
616  currMoveVect += move_vect;
617  } while( aList && --aDuplicateCount > 0 );
618 }
619 
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:253
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:118
bool IsFilled() const
Definition: pcb_shape.h:96
SHAPE_POLY_SET & GetPolyShape()
Definition: pcb_shape.h:268
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:156
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.
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
void SetFilled(bool aFlag)
Definition: pcb_shape.h:94
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Definition: pcb_shape.h:201
int color
Definition: DXF_plotter.cpp:60
bool IsEmpty() const
int GetWidth() const
Definition: pcb_shape.h:118
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
DIALOG_PAD_PRIMITIVE_POLY_PROPS(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PCB_SHAPE *aShape)
usual segment : line with rounded ends
Definition: board_item.h:50
Arcs (with rounded ends)
Definition: board_item.h:52
void OnButtonDelete(wxCommandEvent &event) override
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
int PointCount() const
Function PointCount()
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:98
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:120
Class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE.
DIALOG_PAD_PRIMITIVES_TRANSFORM(wxWindow *aParent, PCB_BASE_FRAME *aFrame, std::vector< std::shared_ptr< PCB_SHAPE >> &aList, bool aShowDuplicate)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:82
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.
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
bool TransferDataToWindow() override
Function TransferDataToWindow Transfer data into the GUI.
#define NULL
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:451
const BITMAP_OPAQUE dialog_warning_xpm[1]
SHAPE_LINE_CHAIN & Outline(int aIndex)
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:145
void onPolyPanelResize(wxSizeEvent &event) override
DIALOG_PAD_PRIMITIVES_PROPERTIES(wxWindow *aParent, PCB_BASE_FRAME *aFrame, PCB_SHAPE *aShape)
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:182
void SetBezControl1(const wxPoint &aPoint)
Definition: pcb_shape.h:132
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:228
Definition: color4d.h:59
const BITMAP_OPAQUE small_trash_xpm[1]
Definition: small_trash.cpp:23
void onPaintPolyPanel(wxPaintEvent &event) override
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:81
const int scale
void SetStart(const wxPoint &aStart)
Definition: pcb_shape.h:148
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
const wxPoint & GetBezControl2() const
Definition: pcb_shape.h:136
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
double GetAngle() const
Definition: pcb_shape.h:127
void SetWidth(int aWidth)
Definition: pcb_shape.h:117
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:68
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:225
ring
Definition: board_item.h:53
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:130
bool doValidate(bool aRemoveRedundantCorners)
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:338
virtual void SetAngle(double aAngle, bool aUpdateEnd=true)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: pcb_shape.cpp:465
Bezier Curve.
Definition: board_item.h:55
static constexpr int Millimeter2iu(double mm)
const wxPoint & GetBezControl1() const
Definition: pcb_shape.h:133
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
Definition: pcb_shape.cpp:1075
const BITMAP_OPAQUE small_plus_xpm[1]
Definition: small_plus.cpp:18
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
std::vector< std::shared_ptr< PCB_SHAPE > > & m_list
bool TransferDataFromWindow() override
Function TransferDataFromWindow Transfer data out of the GUI.
void SetEnd(const wxPoint &aEnd)
Definition: pcb_shape.h:159
bool Validate() override
test for a valid polygon (a not self intersectiong polygon)
Class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE.