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 
105  m_AngleValidator.SetRange( -360.0, 360.0 );
106  m_angleCtrl->SetValidator( m_AngleValidator );
107  m_AngleValidator.SetWindow( m_angleCtrl );
108 
109  // Configure the layers list selector
110  if( m_moduleItem )
111  {
112  LSET forbiddenLayers = LSET::ForbiddenFootprintLayers();
113 
114  // If someone went to the trouble of setting the layer in a text editor, then there's
115  // very little sense in nagging them about it.
116  forbiddenLayers.set( m_moduleItem->GetLayer(), false );
117 
118  m_LayerSelectionCtrl->SetNotAllowedLayerSet( forbiddenLayers );
119  }
120 
124 
126 
127  m_StandardButtonsSizerOK->SetDefault();
128 }
129 
130 
132 {
133  wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
134 
135  DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem );
136  dlg.ShowModal();
137 }
138 
139 
141 {
142  if( !m_item )
143  return false;
144 
145  // Only an arc has a angle parameter. So do not show this parameter for other shapes
146  if( m_item->GetShape() != S_ARC )
147  m_angle.Show( false );
148 
149  // Only a Bezeier curve has control points. So do not show these parameters for other shapes
150  if( m_item->GetShape() != S_CURVE )
151  {
152  m_bezierCtrlPt1Label->Show( false );
153  m_bezierCtrl1X.Show( false );
154  m_bezierCtrl1Y.Show( false );
155  m_bezierCtrlPt2Label->Show( false );
156  m_bezierCtrl2X.Show( false );
157  m_bezierCtrl2Y.Show( false );
158  }
159 
160  // Change texts according to the segment shape:
161  switch( m_item->GetShape() )
162  {
163  case S_CIRCLE:
164  SetTitle( _( "Circle Properties" ) );
165  m_startPointLabel->SetLabel( _( "Center" ) );
166  m_endPointLabel->SetLabel( _( "Radius" ) );
167  m_endY.Show( false );
168  break;
169 
170  case S_ARC:
171  SetTitle( _( "Arc Properties" ) );
172  m_startPointLabel->SetLabel( _( "Center" ) );
173  m_endPointLabel->SetLabel( _( "Start Point" ) );
174 
175  m_AngleValue = m_item->GetAngle() / 10.0;
176  break;
177 
178  case S_POLYGON:
179  SetTitle( _( "Polygon Properties" ) );
180  m_sizerLeft->Show( false );
181  break;
182 
183  case S_RECT:
184  SetTitle( _( "Rectangle Properties" ) );
185  break;
186 
187  case S_SEGMENT:
188  if( m_item->GetStart().x == m_item->GetEnd().x )
190  else
192 
193  SetTitle( _( "Line Segment Properties" ) );
194  break;
195 
196  default:
197  break;
198  }
199 
200  if( m_flipStartEnd )
201  {
204  }
205  else
206  {
209  }
210 
211  if( m_item->GetShape() == S_CIRCLE )
212  {
214  }
215  else if( m_flipStartEnd )
216  {
219  }
220  else
221  {
222  m_endX.SetValue( m_item->GetEnd().x );
223  m_endY.SetValue( m_item->GetEnd().y );
224  }
225 
226  // For Bezier curve:
231 
233 
235  {
236  wxMessageBox( _( "This item was on a non-existing or forbidden layer.\n"
237  "It has been moved to the first allowed layer. Please fix it." ) );
238  m_LayerSelectionCtrl->SetSelection( 0 );
239  }
240 
241  return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow();
242 }
243 
244 
246 {
247  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
248  return false;
249 
251 
252  BOARD_COMMIT commit( m_parent );
253  commit.Modify( m_item );
254 
255  if( m_flipStartEnd )
256  {
259  }
260  else
261  {
264  }
265 
266  if( m_item->GetShape() == S_CIRCLE )
267  {
269  }
270  else if( m_flipStartEnd )
271  {
274  }
275  else
276  {
279  }
280 
281  // For Bezier curve: Set the two control points
282  if( m_item->GetShape() == S_CURVE )
283  {
286  }
287 
288  if( m_moduleItem )
289  { // We are editing a footprint.
290  // Init the item coordinates relative to the footprint anchor,
291  // that are coordinate references
294 
295  if( m_moduleItem->GetShape() == S_CURVE )
296  {
299  }
300  }
301 
303  m_item->SetLayer( ToLAYER_ID( layer ) );
304 
305  if( m_item->GetShape() == S_ARC )
306  m_item->SetAngle( m_AngleValue * 10.0 );
307 
309 
310  commit.Push( _( "Modify drawing properties" ) );
311 
313 
314  return true;
315 }
316 
317 
319 {
320  wxArrayString error_msgs;
321 
322  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() )
323  return false;
324 
325  // Type specific checks.
326  switch( m_item->GetShape() )
327  {
328  case S_ARC:
329  // Check angle of arc.
330  if( m_angle.GetValue() == 0 )
331  error_msgs.Add( _( "The arc angle cannot be zero." ) );
332 
334 
335  case S_CIRCLE:
336  // Check radius.
338  error_msgs.Add( _( "The radius must be greater than zero." ) );
339  break;
340 
341  case S_RECT:
342  // Check for null rect.
344  error_msgs.Add( _( "The rectangle can not be empty." ) );
345  break;
346 
347  case S_POLYGON:
348  case S_SEGMENT:
349  case S_CURVE:
350  break;
351 
352  default:
353  wxASSERT_MSG( false, "DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate not implemented for shape"
355  break;
356  }
357 
358  if( error_msgs.GetCount() )
359  {
360  HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
361  dlg.ListSet( error_msgs );
362  dlg.ShowModal();
363  }
364 
365  return error_msgs.GetCount() == 0;
366 }
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
#define KI_FALLTHROUGH
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()
Function ForbiddenFootprintLayers Layers which are not allowed within footprint definitions.
Definition: lset.cpp:825
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
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)
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
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
Type LAYER_NUM 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)
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
const wxPoint & GetBezControl1() const
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:849
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:79
void OnInitDlg(wxInitDialogEvent &event) override
void SetBezControl1(const wxPoint &aPoint)
void SetWidth(int aWidth)