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) 2018 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your 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 <class_drawpanel.h>
33 #include <pcb_base_edit_frame.h>
34 #include <wx/valnum.h>
35 #include <board_commit.h>
36 #include <pcb_layer_box_selector.h>
37 #include <html_messagebox.h>
38 #include <class_board.h>
39 #include <class_drawsegment.h>
40 #include <class_edge_mod.h>
41 #include <widgets/unit_binder.h>
42 
44 
46 {
47 private:
51 
58 
59  wxFloatingPointValidator<double> m_AngleValidator;
60  double m_AngleValue;
61 
62 public:
65 
66 private:
67  bool TransferDataToWindow() override;
68  bool TransferDataFromWindow() override;
69 
70  void OnInitDlg( wxInitDialogEvent& event ) override
71  {
72  // Call the default wxDialog handler of a wxInitDialogEvent
74 
75  // Now all widgets have the size fixed, call FinishDialogSettings
77  }
78 
79  bool Validate() override;
80 };
81 
83  BOARD_ITEM* aItem ):
96  m_AngleValue( 0.0 )
97 {
98  m_parent = aParent;
99  m_item = dynamic_cast<DRAWSEGMENT*>( aItem );
100  m_moduleItem = dynamic_cast<EDGE_MODULE*>( aItem );
101 
103  m_AngleValidator.SetRange( -360.0, 360.0 );
104  m_angleCtrl->SetValidator( m_AngleValidator );
105  m_AngleValidator.SetWindow( m_angleCtrl );
106 
107  // Configure the layers list selector
108  if( m_moduleItem )
110 
114 
116 
117  m_StandardButtonsSizerOK->SetDefault();
118 }
119 
120 
122 {
123  wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
124 
125  m_canvas->SetIgnoreMouseEvents( true );
126  DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem );
127  dlg.ShowModal();
128  m_canvas->MoveCursorToCrossHair();
129  m_canvas->SetIgnoreMouseEvents( false );
130  m_canvas->Refresh();
131 }
132 
133 
135 {
136  if( !m_item )
137  return false;
138 
139  // Only an arc has a angle parameter. So do not show this parameter for other shapes
140  if( m_item->GetShape() != S_ARC )
141  m_angle.Show( false );
142 
143  // Only a Bezeier curve has control points. So do not show these parameters for other shapes
144  if( m_item->GetShape() != S_CURVE )
145  {
146  m_bezierCtrl1X.Show( false );
147  m_bezierCtrl1Y.Show( false );
148  m_bezierCtrl2X.Show( false );
149  m_bezierCtrl2Y.Show( false );
150  }
151 
152  // Change texts according to the segment shape:
153  switch( m_item->GetShape() )
154  {
155  case S_CIRCLE:
156  SetTitle( _( "Circle Properties" ) );
157  m_startXLabel->SetLabel( _( "Center X:" ) );
158  m_startYLabel->SetLabel( _( "Center Y:" ) );
159  m_endXLabel->SetLabel( _( "Radius:" ) );
160  m_endY.Show( false );
161  break;
162 
163  case S_ARC:
164  SetTitle( _( "Arc Properties" ) );
165  m_startXLabel->SetLabel( _( "Center X:" ) );
166  m_startYLabel->SetLabel( _( "Center Y:" ) );
167  m_endXLabel->SetLabel( _( "Start Point X:" ) );
168  m_endYLabel->SetLabel( _( "Start Point Y:" ) );
169 
170  m_AngleValue = m_item->GetAngle() / 10.0;
171  break;
172 
173  case S_POLYGON:
174  SetTitle( _( "Polygon Properties" ) );
175  m_fgUpperLeftGridSizer->Show( false );
176  break;
177 
178  case S_SEGMENT:
179  SetTitle( _( "Line Segment Properties" ) );
180  break;
181 
182  default:
183  break;
184  }
185 
188 
189  if( m_item->GetShape() == S_CIRCLE )
190  {
192  }
193  else
194  {
195  m_endX.SetValue( m_item->GetEnd().x );
196  m_endY.SetValue( m_item->GetEnd().y );
197  }
198 
199  // For Bezier curve:
204 
206 
208  {
209  wxMessageBox( _( "This item was on a forbidden or non-existing layer.\n"
210  "It has been moved to the first allowed layer." ) );
211  m_LayerSelectionCtrl->SetSelection( F_SilkS );
212  }
213 
214  return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow();
215 }
216 
217 
219 {
220  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
221  return false;
222 
224 
225  BOARD_COMMIT commit( m_parent );
226  commit.Modify( m_item );
227 
230 
231  if( m_item->GetShape() == S_CIRCLE )
232  {
234  }
235  else
236  {
239  }
240 
241  // For Bezier curve: Set the two control points
242  if( m_item->GetShape() == S_CURVE )
243  {
246  }
247 
248  if( m_moduleItem )
249  { // We are editing a footprint.
250  // Init the item coordinates relative to the footprint anchor,
251  // that are coordinate references
254 
255  if( m_moduleItem->GetShape() == S_CURVE )
256  {
259  }
260  }
261 
263  m_item->SetLayer( ToLAYER_ID( layer ) );
264 
265  if( m_item->GetShape() == S_ARC )
266  m_item->SetAngle( m_AngleValue * 10.0 );
267 
269 
270  commit.Push( _( "Modify drawing properties" ) );
271 
273 
274  return true;
275 }
276 
277 
279 {
280  wxArrayString error_msgs;
281 
282  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() )
283  return false;
284 
285  // Type specific checks.
286  switch( m_item->GetShape() )
287  {
288  case S_ARC:
289  // Check angle of arc.
290  if( m_angle.GetValue() == 0 )
291  error_msgs.Add( _( "The arc angle cannot be zero." ) );
292  // Fall through.
293 
294  case S_CIRCLE:
295  // Check radius.
297  error_msgs.Add( _( "The radius must be greater than zero." ) );
298  break;
299 
300  case S_POLYGON:
301  break;
302 
303  default:
304  // Check start and end are not the same.
306  error_msgs.Add( _( "The start and end points cannot be the same." ) );
307  break;
308  }
309 
310  // Check the item thickness. Note the polygon outline thickness is allowed
311  // to be set to 0, because if the shape is exactly the polygon, its outline
312  // thickness must be 0
313  int thickness = m_thickness.GetValue();
314 
315  if( m_item->GetShape() == S_POLYGON )
316  {
317  if( thickness < 0 )
318  error_msgs.Add( _( "The polygon outline thickness must be >= 0." ) );
319  }
320  else
321  {
322  if( thickness <= 0 )
323  error_msgs.Add( _( "The item thickness must be greater than zero." ) );
324  }
325 
326  if( error_msgs.GetCount() )
327  {
328  HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
329  dlg.ListSet( error_msgs );
330  dlg.ShowModal();
331  }
332 
333  return error_msgs.GetCount() == 0;
334 }
void SetEnd0(const wxPoint &aPoint)
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
const wxPoint & GetBezControl2() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
Class 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:786
void SetNotAllowedLayerSet(LSET aMask)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetBezier0_C1(const wxPoint &aPoint)
void SetStartY(int y)
Class BOARD to handle a board.
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
virtual void SetUnits(EDA_UNITS_T aUnits, bool aUseMils=false)
Function SetUnits Normally not needed (as the UNIT_BINDER inherits from the parent frame)...
Definition: unit_binder.cpp:64
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
void SetBezControl2(const wxPoint &aPoint)
wxFloatingPointValidator< double > m_AngleValidator
This file contains miscellaneous commonly used macros and functions.
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
STROKE_T GetShape() const
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
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)
Function ListSet Add a list of items.
Arcs (with rounded ends)
void Show(bool aShow)
Function Show Shows/hides the label, widget and units label.
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
void SetEndY(int y)
int SetLayerSelection(LAYER_NUM layer)
const wxPoint & GetBezControl1() const
Bezier Curve.
Class HTML_MESSAGE_BOX.
DIALOG_GRAPHIC_ITEM_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, BOARD_ITEM *aItem)
bool SetLayersHotkeys(bool value)
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.
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
LAYER_NUM GetLayerSelection() const
void SetStart0(const wxPoint &aPoint)
int GetWidth() const
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
void SetEndX(int x)
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...
void SetStartX(int x)
Class DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE.
EDGE_MODULE class definition.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
void OnInitDlg(wxInitDialogEvent &event) override
void SetBezControl1(const wxPoint &aPoint)
void SetWidth(int aWidth)