KiCad PCB EDA Suite
dialog_graphic_item_properties.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 /*
26  * Edit properties of Lines, Circles, Arcs and Polygons for PCBNew and ModEdit
27  */
28 
29 #include <fctsys.h>
30 #include <macros.h>
31 #include <confirm.h>
32 #include <pcb_base_edit_frame.h>
33 #include <wx/valnum.h>
34 #include <board_commit.h>
35 #include <pcb_layer_box_selector.h>
36 #include <html_messagebox.h>
37 #include <class_board.h>
38 #include <class_drawsegment.h>
39 #include <class_edge_mod.h>
40 #include <widgets/unit_binder.h>
41 
43 
45 {
46 private:
50 
57 
59 
60  wxFloatingPointValidator<double> m_AngleValidator;
61  double m_AngleValue;
62 
63 public:
66 
67 private:
68  bool TransferDataToWindow() override;
69  bool TransferDataFromWindow() override;
70 
71  void OnInitDlg( wxInitDialogEvent& event ) override
72  {
73  // Call the default wxDialog handler of a wxInitDialogEvent
75 
76  // Now all widgets have the size fixed, call FinishDialogSettings
78  }
79 
80  bool Validate() override;
81 };
82 
84  BOARD_ITEM* aItem ):
86  m_startX( aParent, m_startXLabel, m_startXCtrl, m_startXUnits ),
87  m_startY( aParent, m_startYLabel, m_startYCtrl, m_startYUnits ),
88  m_endX( aParent, m_endXLabel, m_endXCtrl, m_endXUnits ),
89  m_endY( aParent, m_endYLabel, m_endYCtrl, m_endYUnits ),
90  m_angle( aParent, m_angleLabel, m_angleCtrl, m_angleUnits ),
91  m_thickness( aParent, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true ),
92  m_bezierCtrl1X( aParent, m_BezierPointC1XLabel, m_BezierC1X_Ctrl, m_BezierPointC1XUnit ),
93  m_bezierCtrl1Y( aParent, m_BezierPointC1YLabel, m_BezierC1Y_Ctrl, m_BezierPointC1YUnit ),
94  m_bezierCtrl2X( aParent, m_BezierPointC2XLabel, m_BezierC2X_Ctrl, m_BezierPointC2XUnit ),
95  m_bezierCtrl2Y( aParent, m_BezierPointC2YLabel, m_BezierC2Y_Ctrl, m_BezierPointC2YUnit ),
96  m_flipStartEnd( false ),
97  m_AngleValidator( 1, &m_AngleValue ),
98  m_AngleValue( 0.0 )
99 {
100  m_parent = aParent;
101  m_item = dynamic_cast<DRAWSEGMENT*>( aItem );
102  m_moduleItem = dynamic_cast<EDGE_MODULE*>( aItem );
103 
104  // Configure display origin transforms
113 
115  m_AngleValidator.SetRange( -360.0, 360.0 );
116  m_angleCtrl->SetValidator( m_AngleValidator );
117  m_AngleValidator.SetWindow( m_angleCtrl );
118 
119  // Configure the layers list selector
120  if( m_moduleItem )
121  {
122  LSET forbiddenLayers = LSET::ForbiddenFootprintLayers();
123 
124  // If someone went to the trouble of setting the layer in a text editor, then there's
125  // very little sense in nagging them about it.
126  forbiddenLayers.set( m_moduleItem->GetLayer(), false );
127 
128  m_LayerSelectionCtrl->SetNotAllowedLayerSet( forbiddenLayers );
129  }
130 
134 
136 
137  m_StandardButtonsSizerOK->SetDefault();
138 }
139 
140 
142 {
143  wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
144 
145  DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem );
146  dlg.ShowModal();
147 }
148 
149 
151 {
152  if( !m_item )
153  return false;
154 
155  // Only an arc has a angle parameter. So do not show this parameter for other shapes
156  if( m_item->GetShape() != S_ARC )
157  m_angle.Show( false );
158 
159  // Only a Bezeier curve has control points. So do not show these parameters for other shapes
160  if( m_item->GetShape() != S_CURVE )
161  {
162  m_bezierCtrlPt1Label->Show( false );
163  m_bezierCtrl1X.Show( false );
164  m_bezierCtrl1Y.Show( false );
165  m_bezierCtrlPt2Label->Show( false );
166  m_bezierCtrl2X.Show( false );
167  m_bezierCtrl2Y.Show( false );
168  }
169 
170  // Change texts according to the segment shape:
171  switch( m_item->GetShape() )
172  {
173  case S_CIRCLE:
174  SetTitle( _( "Circle Properties" ) );
175  m_startPointLabel->SetLabel( _( "Center" ) );
176  m_endPointLabel->SetLabel( _( "Radius" ) );
178  m_endY.Show( false );
179  break;
180 
181  case S_ARC:
182  SetTitle( _( "Arc Properties" ) );
183  m_startPointLabel->SetLabel( _( "Center" ) );
184  m_endPointLabel->SetLabel( _( "Start Point" ) );
185 
186  m_AngleValue = m_item->GetAngle() / 10.0;
187  break;
188 
189  case S_POLYGON:
190  SetTitle( _( "Polygon Properties" ) );
191  m_sizerLeft->Show( false );
192  break;
193 
194  case S_RECT:
195  SetTitle( _( "Rectangle Properties" ) );
196  break;
197 
198  case S_SEGMENT:
199  if( m_item->GetStart().x == m_item->GetEnd().x )
201  else
203 
204  SetTitle( _( "Line Segment Properties" ) );
205  break;
206 
207  default:
208  break;
209  }
210 
211  if( m_flipStartEnd )
212  {
215  }
216  else
217  {
220  }
221 
222  if( m_item->GetShape() == S_CIRCLE )
223  {
225  }
226  else if( m_flipStartEnd )
227  {
230  }
231  else
232  {
233  m_endX.SetValue( m_item->GetEnd().x );
234  m_endY.SetValue( m_item->GetEnd().y );
235  }
236 
237  // For Bezier curve:
242 
244 
246  {
247  wxMessageBox( _( "This item was on a non-existing or forbidden layer.\n"
248  "It has been moved to the first allowed layer. Please fix it." ) );
249  m_LayerSelectionCtrl->SetSelection( 0 );
250  }
251 
252  return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow();
253 }
254 
255 
257 {
258  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
259  return false;
260 
262 
263  BOARD_COMMIT commit( m_parent );
264  commit.Modify( m_item );
265 
266  if( m_flipStartEnd )
267  {
270  }
271  else
272  {
275  }
276 
277  if( m_item->GetShape() == S_CIRCLE )
278  {
280  }
281  else if( m_flipStartEnd )
282  {
285  }
286  else
287  {
290  }
291 
292  // For Bezier curve: Set the two control points
293  if( m_item->GetShape() == S_CURVE )
294  {
297  }
298 
299  if( m_moduleItem )
300  { // We are editing a footprint.
301  // Init the item coordinates relative to the footprint anchor,
302  // that are coordinate references
305 
306  if( m_moduleItem->GetShape() == S_CURVE )
307  {
310  }
311  }
312 
314  m_item->SetLayer( ToLAYER_ID( layer ) );
315 
316  if( m_item->GetShape() == S_ARC )
317  m_item->SetAngle( m_AngleValue * 10.0 );
318 
320 
321  commit.Push( _( "Modify drawing properties" ) );
322 
324 
325  return true;
326 }
327 
328 
330 {
331  wxArrayString error_msgs;
332 
333  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() )
334  return false;
335 
336  // Type specific checks.
337  switch( m_item->GetShape() )
338  {
339  case S_ARC:
340  // Check angle of arc.
341  if( m_angle.GetValue() == 0 )
342  error_msgs.Add( _( "The arc angle cannot be zero." ) );
343 
345 
346  case S_CIRCLE:
347  // Check radius.
349  error_msgs.Add( _( "The radius must be greater than zero." ) );
350  break;
351 
352  case S_RECT:
353  // Check for null rect.
355  error_msgs.Add( _( "The rectangle can not be empty." ) );
356  break;
357 
358  case S_POLYGON:
359  case S_SEGMENT:
360  case S_CURVE:
361  break;
362 
363  default:
364  wxASSERT_MSG( false, "DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate not implemented for shape"
366  break;
367  }
368 
369  if( error_msgs.GetCount() )
370  {
371  HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
372  dlg.ListSet( error_msgs );
373  dlg.ShowModal();
374  }
375 
376  return error_msgs.GetCount() == 0;
377 }
void SetEnd0(const wxPoint &aPoint)
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:880
void SetNotAllowedLayerSet(LSET aMask)
STROKE_T GetShape() const
void SetBezier0_C1(const wxPoint &aPoint)
void SetStartY(int y)
void SetBezier0_C2(const wxPoint &aPoint)
polygon (not yet used for tracks, but could be in microwave apps)
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_BezierPoints vertex list that approximate the Bezier curve by a list of segments Has me...
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void InstallGraphicItemPropertiesDialog(BOARD_ITEM *aItem)
usual segment : line with rounded ends
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:88
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:114
void SetBezControl2(const wxPoint &aPoint)
wxFloatingPointValidator< double > m_AngleValidator
This file contains miscellaneous commonly used macros and functions.
LAYER_NUM GetLayerSelection() const
segment with non rounded ends
void Show(bool aShow, bool aResize=false)
Function Show Shows/hides the label, widget and units label.
LSET is a set of PCB_LAYER_IDs.
#define NULL
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void ListSet(const wxString &aList)
Add a list of items.
Arcs (with rounded ends)
void SetEndY(int y)
int SetLayerSelection(LAYER_NUM layer)
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Bezier Curve.
HTML_MESSAGE_BOX.
DIALOG_GRAPHIC_ITEM_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, BOARD_ITEM *aItem)
bool SetLayersHotkeys(bool value)
int GetWidth() const
int LAYER_NUM
This can be replaced with int and removed.
double GetAngle() const
Class to handle a graphic segment.
Common, abstract interface for edit frames.
#define _(s)
Definition: 3d_actions.cpp:33
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
void SetStart0(const wxPoint &aPoint)
const wxPoint & GetBezControl2() const
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
void SetEndX(int x)
virtual long long int GetValue()
Function GetValue Returns the current value in Internal Units.
void SetEnd(const wxPoint &aEnd)
virtual void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
const wxPoint & GetBezControl1() const
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Function SetOriginTransform Sets the current origin transform mode.
Definition: unit_binder.h:171
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
void SetStartX(int x)
Class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE.
EDGE_MODULE class definition.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:904
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:81
void OnInitDlg(wxInitDialogEvent &event) override
void SetBezControl1(const wxPoint &aPoint)
void SetWidth(int aWidth)