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 
29 /* Edit parameters values of graphic items type DRAWSEGMENTS:
30  * Lines
31  * Circles
32  * Arcs
33  * polygon (only layer and contour thickness)
34  * used as graphic elements found on non copper layers in boards
35  * items on edge layers are considered as graphic items
36  * Pcb texts are not always graphic items and are not handled here
37  */
38 #include <fctsys.h>
39 #include <macros.h>
40 #include <gr_basic.h>
41 #include <confirm.h>
42 #include <class_drawpanel.h>
43 #include <pcbnew.h>
44 #include <pcb_edit_frame.h>
45 #include <board_design_settings.h>
46 #include <base_units.h>
47 #include <wx/valnum.h>
48 #include <board_commit.h>
49 #include <widgets/text_ctrl_eval.h>
50 
51 #include <class_board.h>
52 #include <class_drawsegment.h>
53 
55 #include <pcb_layer_box_selector.h>
56 #include <html_messagebox.h>
57 #include <widgets/text_ctrl_eval.h>
58 
59 
61 {
62 private:
64  wxDC* m_DC;
67 
68  wxFloatingPointValidator<double> m_AngleValidator;
69  double m_AngleValue;
70 
71 public:
72  DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent, DRAWSEGMENT* aItem, wxDC* aDC );
74 
75 private:
76  bool TransferDataToWindow() override;
77  bool TransferDataFromWindow() override;
78  void OnLayerChoice( wxCommandEvent& event );
79 
80  void OnInitDlg( wxInitDialogEvent& event ) override
81  {
82  // Call the default wxDialog handler of a wxInitDialogEvent
84 
85  // Now all widgets have the size fixed, call FinishDialogSettings
87  }
88 
89  bool Validate() override;
90 };
91 
93  DRAWSEGMENT* aItem, wxDC* aDC ):
96  m_AngleValue( 0.0 )
97 {
98  m_parent = aParent;
99  m_DC = aDC;
100  m_item = aItem;
102 
103  m_AngleValidator.SetRange( -360.0, 360.0 );
104  m_AngleCtrl->SetValidator( m_AngleValidator );
105  m_AngleValidator.SetWindow( m_AngleCtrl );
106 
107  m_StandardButtonsSizerOK->SetDefault();
108 
109 }
110 
111 
113 {
114  wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
115 
116  m_canvas->SetIgnoreMouseEvents( true );
117  DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem, aDC );
118  dlg.ShowModal();
119  m_canvas->MoveCursorToCrossHair();
120  m_canvas->SetIgnoreMouseEvents( false );
121 }
122 
123 
125 {
126  // Set unit symbol
127  wxStaticText* texts_unit[] =
128  {
135  };
136 
137  for( size_t ii = 0; ii < DIM( texts_unit ); ii++ )
138  {
139  texts_unit[ii]->SetLabel( GetAbbreviatedUnitsLabel() );
140  }
141 
142  // Only an arc has a angle parameter. So do not show this parameter for other shapes
143  if( m_item->GetShape() != S_ARC )
144  {
145  m_AngleText->Show( false );
146  m_AngleCtrl->Show( false );
147  m_AngleUnit->Show( false );
148  }
149 
150  wxString msg;
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_StartPointXLabel->SetLabel( _( "Center X:" ) );
158  m_StartPointYLabel->SetLabel( _( "Center Y:" ) );
159  m_EndPointXLabel->SetLabel( _( "Point X:" ) );
160  m_EndPointYLabel->SetLabel( _( "Point Y:" ) );
161  break;
162 
163  case S_ARC:
164  SetTitle( _( "Arc Properties" ) );
165  m_StartPointXLabel->SetLabel( _( "Center X:" ) );
166  m_StartPointYLabel->SetLabel( _( "Center Y:" ) );
167  m_EndPointXLabel->SetLabel( _( "Start Point X:" ) );
168  m_EndPointYLabel->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 
187 
189 
191 
193 
195 
196  int thickness;
197 
198  if( m_item->GetLayer() == Edge_Cuts )
199  thickness = m_brdSettings.m_EdgeSegmentWidth;
200  else
201  thickness = m_brdSettings.m_DrawSegmentWidth;
202 
204 
205  // Configure the layers list selector
210 
212  {
213  wxMessageBox( _( "This item was on a not allowed or non existing layer.\n"
214  "It has been moved to the first allowed layer.\n\n"
215  "Please fix it." ) );
216  //m_LayerSelectionCtrl->SetLayerSelection( Dwgs_User );
217  m_LayerSelectionCtrl->SetSelection( 0 );
218  }
219 
220  return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow();
221 }
222 
223 
225 {
226  int thickness;
227 
229  thickness = m_brdSettings.m_EdgeSegmentWidth;
230  else
231  thickness = m_brdSettings.m_DrawSegmentWidth;
232 
234 }
235 
236 
238 {
239  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
240  return false;
241 
242  BOARD_COMMIT commit( m_parent );
243  commit.Modify( m_item );
244 
245  wxString msg;
246 
247  if( m_DC )
249 
250  msg = m_Center_StartXCtrl->GetValue();
252 
253  msg = m_Center_StartYCtrl->GetValue();
255 
256  msg = m_EndX_Radius_Ctrl->GetValue();
258 
259  msg = m_EndY_Ctrl->GetValue();
261 
262  msg = m_ThicknessCtrl->GetValue();
264 
265  msg = m_DefaultThicknessCtrl->GetValue();
266  int thickness = ValueFromString( g_UserUnit, msg );
267 
269 
270  if( m_item->GetLayer() == Edge_Cuts )
271  m_brdSettings.m_EdgeSegmentWidth = thickness;
272  else
273  m_brdSettings.m_DrawSegmentWidth = thickness;
274 
275  if( m_item->GetShape() == S_ARC )
276  {
277  m_item->SetAngle( m_AngleValue * 10.0 );
278  }
279 
280  commit.Push( _( "Modify drawing properties" ) );
281 
282  if( m_DC )
284 
286 
288  m_parent->OnModify();
289 
290  return true;
291 }
292 
293 
295 {
296  wxArrayString error_msgs;
297 
298  if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() )
299  return false;
300 
301  // Load the start and end points -- all types use these in the checks.
302  int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() );
303  int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() );
304  int endx = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() );
305  int endy = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() );
306 
307  // Type specific checks.
308  switch( m_item->GetShape() )
309  {
310  case S_ARC:
311  // Check angle of arc.
312  if( m_AngleValue == 0.0 )
313  {
314  error_msgs.Add( _( "The arc angle must be greater than zero." ) );
315  }
316 
317  // Fall through.
318  case S_CIRCLE:
319  // Check radius.
320  if( (startx == endx) && (starty == endy) )
321  {
322  error_msgs.Add( _( "The radius must be greater than zero." ) );
323  }
324 
325  break;
326 
327  case S_POLYGON:
328  break;
329 
330  default:
331  // Check start and end are not the same.
332  if( (startx == endx) && (starty == endy) )
333  {
334  error_msgs.Add( _( "The start and end points cannot be the same." ) );
335  }
336 
337  break;
338  }
339 
340  // Check the item thickness. Note the polygon outline thickness is allowed
341  // to be set to 0, because if the shape is exactly the polygon, its outline
342  // thickness must be 0
343  int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() );
344 
345  if( m_item->GetShape() == S_POLYGON )
346  {
347  if( thickness < 0 )
348  error_msgs.Add( _( "The polygon outline thickness must be >= 0." ) );
349  }
350  else if( thickness <= 0 )
351  error_msgs.Add( _( "The item thickness must be greater than zero." ) );
352 
353  // And the default thickness.
354  thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() );
355 
356  if( thickness <= 0 )
357  error_msgs.Add( _( "The default thickness must be greater than zero." ) );
358 
359  if( error_msgs.GetCount() )
360  {
361  HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );
362  dlg.ListSet( error_msgs );
363  dlg.ShowModal();
364  }
365 
366  return error_msgs.GetCount() == 0;
367 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
#define DIM(x)
of elements in an array
Definition: macros.h:98
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
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.
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:351
void SetNotAllowedLayerSet(LSET aMask)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetStartY(int y)
Class BOARD to handle a board.
polygon (not yet used for tracks, but could be in microwave apps)
DIALOG_GRAPHIC_ITEM_PROPERTIES(PCB_EDIT_FRAME *aParent, DRAWSEGMENT *aItem, wxDC *aDC)
void InstallGraphicItemPropertiesDialog(DRAWSEGMENT *aItem, wxDC *aDC)
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
usual segment : line with rounded ends
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
wxFloatingPointValidator< double > m_AngleValidator
This file contains miscellaneous commonly used macros and functions.
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)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:832
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
Arcs (with rounded ends)
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit)
Definition: base_units.cpp:485
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
int m_DrawSegmentWidth
current graphic line width (not EDGE layer)
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:370
void SetEndY(int y)
int SetLayerSelection(LAYER_NUM layer)
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
Class HTML_MESSAGE_BOX.
bool SetLayersHotkeys(bool value)
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:57
Definition: gr_basic.h:38
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:267
double GetAngle() const
Class to handle a graphic segment.
virtual void SetDesignSettings(const BOARD_DESIGN_SETTINGS &aSettings)
LAYER_NUM GetLayerSelection() const
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 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.
int m_EdgeSegmentWidth
current graphic line width (EDGE layer only)
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
void OnInitDlg(wxInitDialogEvent &event) override
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
void SetWidth(int aWidth)