KiCad PCB EDA Suite
dimension.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
10  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
11  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, you may find one here:
25  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
26  * or you may search the http://www.gnu.org website for the version 2 license,
27  * or you may write to the Free Software Foundation, Inc.,
28  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29  */
30 
31 #include <fctsys.h>
32 #include <confirm.h>
33 #include <gr_basic.h>
34 #include <class_drawpanel.h>
35 #include <wxPcbStruct.h>
36 #include <drawtxt.h>
37 #include <dialog_helpers.h>
38 #include <macros.h>
39 #include <base_units.h>
40 #include <board_commit.h>
41 #include <widgets/text_ctrl_eval.h>
42 
43 #include <class_board.h>
44 #include <class_pcb_text.h>
45 #include <class_dimension.h>
46 
47 #include <pcbnew.h>
50 
51 /* Local functions */
52 static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
53  const wxPoint& aPosition, bool aErase );
54 
55 static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
56  const wxPoint& aPosition, bool aErase );
57 static void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
58 
59 
60 /* Local variables : */
61 static int status_dimension; /* Used in dimension creation:
62  * = 0 : initial value: no dimension in progress
63  * = 1 : First point created
64  * = 2 : Second point created, the text must be placed */
65 
66 /*
67  * A dimension has this shape:
68  * It has 2 reference points, and a text
69  * | |
70  * | dist |
71  * |<---------->|
72  * | |
73  *
74  */
75 
76 
77 /*********************************/
78 /* class DIALOG_DIMENSION_EDITOR */
79 /*********************************/
80 
82 {
83 private:
84 
86  wxDC* m_DC;
88 
89 public:
90 
91  // Constructor and destructor
92  DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent, DIMENSION* aDimension, wxDC* aDC );
94  {
95  }
96 
97 
98 private:
99  virtual void OnOKClick( wxCommandEvent& event ) override;
100 };
101 
102 
104  DIMENSION* aDimension, wxDC* aDC ) :
106 {
107  SetFocus();
108 
109  m_parent = aParent;
110  m_DC = aDC;
111 
112  m_currentDimension = aDimension;
113 
114  if( aDimension->Text().IsMirrored() )
115  m_rbMirror->SetSelection( 1 );
116  else
117  m_rbMirror->SetSelection( 0 );
118 
119  m_Name->SetValue( aDimension->Text().GetText() );
120 
121  // Enter size value in dialog
126 
127  // Enter lines thickness value in dialog
128  PutValueInLocalUnits( *m_TxtWidthCtrl, aDimension->GetWidth() );
130 
131  // Enter position value in dialog
132  PutValueInLocalUnits( *m_textCtrlPosX, aDimension->Text().GetTextPos().x );
134  PutValueInLocalUnits( *m_textCtrlPosY, aDimension->Text().GetTextPos().y );
136 
137  // Configure the layers list selector
138  if( !m_parent->GetBoard()->IsLayerEnabled( aDimension->GetLayer() ) )
139  // Should not happens, because one cannot select a board item on a
140  // not activated layer, but ...
142 
147 
148  if( m_SelLayerBox->SetLayerSelection( aDimension->GetLayer() ) < 0 )
149  {
150  wxMessageBox( _( "This item has an illegal layer id.\n"
151  "Now, forced on the drawings layer. Please, fix it" ) );
153  }
154 
155  m_sdbSizerBtsOK->SetDefault();
156 
157  // Now all widgets have the size fixed, call FinishDialogSettings
159 }
160 
161 
162 void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
163 {
164  BOARD_COMMIT commit( m_parent );
165 
167 
168  if( !m_parent->GetBoard()->IsLayerEnabled( newlayer ) )
169  {
170  wxMessageBox( _( "The layer currently selected is not enabled for this board\n"
171  "You cannot use it" ) );
172  return;
173  }
174 
175 #ifndef USE_WX_OVERLAY
176  if( m_DC ) // Delete old text.
177  {
179  }
180 #endif
181 
182  commit.Modify( m_currentDimension );
183 
184  if( m_Name->GetValue() != wxEmptyString )
185  {
186  m_currentDimension->SetText( m_Name->GetValue() );
187  }
188 
189  wxString msg;
190 
191  // Get new size value:
192  msg = m_TxtSizeXCtrl->GetValue();
194  msg = m_TxtSizeYCtrl->GetValue();
196 
197  // Get new position value:
198  // It will be copied later in dimension, because
199  msg = m_textCtrlPosX->GetValue();
200  wxPoint pos;
201  pos.x = ValueFromString( g_UserUnit, msg );
202  msg = m_textCtrlPosY->GetValue();
203  pos.y = ValueFromString( g_UserUnit, msg );
205 
206  // Get new line thickness value:
207  msg = m_TxtWidthCtrl->GetValue();
208  int width = ValueFromString( g_UserUnit, msg );
209  int maxthickness = Clamp_Text_PenSize( width, m_currentDimension->Text().GetTextSize() );
210 
211  if( width > maxthickness )
212  {
213  DisplayError( NULL,
214  _( "The text thickness is too large for the text size. "
215  "It will be clamped" ) );
216  width = maxthickness;
217  }
218 
219  m_currentDimension->SetWidth( width );
221  m_currentDimension->Text().SetMirrored( ( m_rbMirror->GetSelection() == 1 ) ? true : false );
222  m_currentDimension->SetLayer( newlayer );
223 
224 #ifndef USE_WX_OVERLAY
225  if( m_DC ) // Display new text
226  {
228  }
229 #else
230  m_parent->Refresh();
231 #endif
232 
233  commit.Push( _( "Modifed dimensions properties" ) );
234  event.Skip(); // ends returning wxID_OK (default behavior)
235 }
236 
237 
238 static void AbortBuildDimension( EDA_DRAW_PANEL* Panel, wxDC* aDC )
239 {
240  DIMENSION* dimension = (DIMENSION*) Panel->GetScreen()->GetCurItem();
241 
242  if( dimension )
243  {
244  if( dimension->IsNew() )
245  {
246  dimension->Draw( Panel, aDC, GR_XOR );
247  dimension->DeleteStructure();
248  }
249  else
250  {
251  dimension->Draw( Panel, aDC, GR_OR );
252  }
253  }
254 
255  status_dimension = 0;
256  ((PCB_EDIT_FRAME*)Panel->GetParent())->SetCurItem( NULL );
257 }
258 
259 
261 {
262  wxPoint pos;
263 
264  if( aDimension == NULL )
265  {
266  status_dimension = 1;
267  pos = GetCrossHairPosition();
268 
269  aDimension = new DIMENSION( GetBoard() );
270  aDimension->SetFlags( IS_NEW );
271  aDimension->SetLayer( GetActiveLayer() );
272  aDimension->SetOrigin( pos );
273  aDimension->SetEnd( pos );
274 
275  aDimension->Text().SetTextSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
276  int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
277  int maxthickness = Clamp_Text_PenSize(width, aDimension->Text().GetTextSize() );
278 
279  if( width > maxthickness )
280  {
281  width = maxthickness;
282  }
283 
284  aDimension->Text().SetThickness( width );
285  aDimension->SetWidth( width );
286  aDimension->AdjustDimensionDetails();
287  aDimension->Draw( m_canvas, aDC, GR_XOR );
288 
290  return aDimension;
291  }
292 
293  // Dimension != NULL
294  if( status_dimension == 1 )
295  {
296  status_dimension = 2;
297  return aDimension;
298  }
299 
300  aDimension->Draw( m_canvas, aDC, GR_OR );
301  aDimension->ClearFlags();
302 
303  /* ADD this new item in list */
304  GetBoard()->Add( aDimension );
305 
306  // Add store it in undo/redo list
307  SaveCopyInUndoList( aDimension, UR_NEW );
308 
309  OnModify();
310  m_canvas->SetMouseCapture( NULL, NULL );
311 
312  return NULL;
313 }
314 
315 
316 static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
317  const wxPoint& aPosition, bool aErase )
318 {
319  PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
320  DIMENSION* Dimension = (DIMENSION*) screen->GetCurItem();
321  wxPoint pos = aPanel->GetParent()->GetCrossHairPosition();
322 
323  if( Dimension == NULL )
324  return;
325 
326  // Erase previous dimension.
327  if( aErase )
328  {
329  Dimension->Draw( aPanel, aDC, GR_XOR );
330  }
331 
332  Dimension->SetLayer( screen->m_Active_Layer );
333 
334  if( status_dimension == 1 )
335  {
336  Dimension->m_featureLineDO = pos;
337  Dimension->m_crossBarF = Dimension->m_featureLineDO;
338  Dimension->AdjustDimensionDetails( );
339  }
340  else
341  {
342  /* Calculating the direction of travel perpendicular to the selected axis. */
343  double angle = Dimension->GetAngle() + (M_PI / 2);
344 
345  wxPoint delta = pos - Dimension->m_featureLineDO;
346  double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
347  Dimension->SetHeight( depl );
348  }
349 
350  Dimension->Draw( aPanel, aDC, GR_XOR );
351 }
352 
353 
355 {
356  if( aDimension == NULL )
357  return;
358 
359  DIALOG_DIMENSION_EDITOR dlg( this, aDimension, aDC );
360  dlg.ShowModal();
361 }
362 
363 
364 void PCB_EDIT_FRAME::DeleteDimension( DIMENSION* aDimension, wxDC* aDC )
365 {
366  if( aDimension == NULL )
367  return;
368 
369  if( aDC )
370  aDimension->Draw( m_canvas, aDC, GR_XOR );
371 
372  SaveCopyInUndoList( aDimension, UR_DELETED );
373  aDimension->UnLink();
374  OnModify();
375 }
376 
377 
378 /* Initialize parameters to move a pcb text
379  */
381 
383 {
384  if( aItem == NULL )
385  return;
386 
387  // Store the initial position for undo/abort command
388  initialTextPosition = aItem->Text().GetTextPos();
389 
390  aItem->Draw( m_canvas, DC, GR_XOR );
391  aItem->SetFlags( IS_MOVED );
392  SetMsgPanel( aItem );
393 
394  SetCrossHairPosition( aItem->Text().GetTextPos() );
396 
398  SetCurItem( aItem );
399  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
400 }
401 
402 
403 /* Move dimension text following the cursor. */
404 static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
405  bool aErase )
406 {
407  DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
408 
409  if( dimension == NULL )
410  return;
411 
412  if( aErase )
413  dimension->Draw( aPanel, aDC, GR_XOR );
414 
415  dimension->Text().SetTextPos( aPanel->GetParent()->GetCrossHairPosition() );
416 
417  dimension->Draw( aPanel, aDC, GR_XOR );
418 }
419 
420 
421 /*
422  * Abort current text edit progress.
423  *
424  * If a text is selected, its initial coord are regenerated
425  */
426 void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
427 {
428  DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
429  ( (PCB_EDIT_FRAME*) aPanel->GetParent() )->SetCurItem( NULL );
430 
431  aPanel->SetMouseCapture( NULL, NULL );
432 
433  if( dimension == NULL ) // Should not occur
434  return;
435 
436  dimension->Draw( aPanel, aDC, GR_XOR );
437  dimension->Text().SetTextPos( initialTextPosition );
438  dimension->ClearFlags();
439  dimension->Draw( aPanel, aDC, GR_OR );
440 }
441 
442 
443 /*
444  * Place the current dimension text being moving
445  */
447 {
448  m_canvas->SetMouseCapture( NULL, NULL );
449  SetCurItem( NULL );
450 
451  if( aItem == NULL )
452  return;
453 
454  aItem->Draw( m_canvas, DC, GR_OR );
455  OnModify();
456 
457  wxPoint tmp = aItem->Text().GetTextPos();
458  aItem->Text().SetTextPos( initialTextPosition );
459  SaveCopyInUndoList( aItem, UR_CHANGED );
460  aItem->Text().SetTextPos( tmp );
461  aItem->ClearFlags();
462 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:178
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:646
Class DIALOG_DIMENSION_EDITOR_BASE.
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
Definition: pcbframe.cpp:994
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
void DeleteDimension(DIMENSION *aDimension, wxDC *aDC)
Definition: dimension.cpp:364
TEXTE_PCB class definition.
void SetText(const wxString &NewText)
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
EDA_ITEM * GetCurItem() const
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
wxPoint m_crossBarF
bool IsNew() const
Definition: base_struct.h:243
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:331
void PlaceDimensionText(DIMENSION *aItem, wxDC *DC)
Definition: dimension.cpp:446
virtual void OnOKClick(wxCommandEvent &event) override
Definition: dimension.cpp:162
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int m_PcbTextWidth
current Pcb (not module) Text width
int GetWidth() const
Class BOARD to handle a board.
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
Function IsLayerEnabled is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:439
int GetTextWidth() const
Definition: eda_text.h:218
void BeginMoveDimensionText(DIMENSION *aItem, wxDC *DC)
Definition: dimension.cpp:382
void ShowDimensionPropertyDialog(DIMENSION *aDimension, wxDC *aDC)
Definition: dimension.cpp:354
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:223
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aColorMode, const wxPoint &offset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void DeleteStructure()
Function DeleteStructure deletes this object after UnLink()ing it from its owner if it has one...
BOARD * GetBoard() const
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:214
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
DIMENSION * EditDimension(DIMENSION *aDimension, wxDC *aDC)
Definition: dimension.cpp:260
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:347
virtual void UnLink()
Function UnLink detaches this object from its owner.
double GetAngle() const
Function GetAngle Returns angle of the crossbar.
PCB_LAYER_ID m_Active_Layer
static const int delta[8][2]
Definition: solve.cpp:112
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
This file contains miscellaneous commonly used macros and functions.
static void AbortBuildDimension(EDA_DRAW_PANEL *Panel, wxDC *aDC)
Definition: dimension.cpp:238
#define IS_NEW
New item, just created.
Definition: base_struct.h:127
PCB_EDIT_FRAME * m_parent
Definition: dimension.cpp:85
DIMENSION class definition.
static void MoveDimensionText(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: dimension.cpp:404
PCB_LAYER_ID
A quick note on layer IDs:
void SetOrigin(const wxPoint &aOrigin)
Function SetOrigin Sets a new origin of the crossbar line.
BOARD_ITEM * GetCurItem() const
Function GetCurItem returns the currently selected BOARD_ITEM, overriding BASE_SCREEN::GetCurItem().
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:280
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:784
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
void SetEnd(const wxPoint &aEnd)
Function SetEnd Sets a new end of the crossbar line.
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize As a rule, pen width should not be >1/4em, otherwise the character will b...
Definition: drawtxt.cpp:67
static int status_dimension
Definition: dimension.cpp:61
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
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:369
Helper dialog and control classes.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
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...
static void BuildDimension(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: dimension.cpp:316
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:174
void SaveCopyInUndoList(BOARD_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, const wxPoint &aTransformPoint=wxPoint(0, 0)) override
Function SaveCopyInUndoList Creates a new entry in undo list of commands.
Definition: undo_redo.cpp:199
bool SetLayersHotkeys(bool value)
DIMENSION * m_currentDimension
Definition: dimension.cpp:87
void AdjustDimensionDetails(bool aDoNotChangeText=false)
Function AdjustDimensionDetails Calculate coordinates of segments used to draw the dimension...
static wxPoint initialTextPosition
Definition: dimension.cpp:380
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
Definition: gr_basic.h:42
void SetTextWidth(int aWidth)
Definition: eda_text.h:217
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
void PutValueInLocalUnits(wxTextCtrl &aTextCtr, int aValue)
Function PutValueInLocalUnits converts aValue from internal units to user units and append the units ...
Definition: base_units.cpp:266
void AddUnitSymbol(wxStaticText &Stext, EDA_UNITS_T aUnit)
Definition: base_units.cpp:514
bool IsMirrored() const
Definition: eda_text.h:179
void SetHeight(int aHeight)
Function SetHeight Sets the length of feature lines.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
TEXTE_PCB & Text()
LAYER_NUM GetLayerSelection() const
DIALOG_DIMENSION_EDITOR(PCB_EDIT_FRAME *aParent, DIMENSION *aDimension, wxDC *aDC)
Definition: dimension.cpp:103
void SetTextHeight(int aHeight)
Definition: eda_text.h:220
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:187
int GetTextHeight() const
Definition: eda_text.h:221
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:281
This file is part of the common libary.
static void AbortMoveDimensionText(EDA_DRAW_PANEL *aPanel, wxDC *aDC)
Definition: dimension.cpp:426
const wxSize & GetTextSize() const
Definition: eda_text.h:215
void SetMouseCapture(MOUSE_CAPTURE_CALLBACK aMouseCaptureCallback, END_MOUSE_CAPTURE_CALLBACK aEndMouseCaptureCallback)
Function SetMouseCapture sets the mouse capture and end mouse capture callbacks to aMouseCaptureCallb...
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Function SetCrossHairPosition sets the screen cross hair position to aPosition in logical (drawing) u...
void SetWidth(int aWidth)
wxPoint m_featureLineDO
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:73
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:774
Class DIMENSION.
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:148
#define IS_MOVED
Item being moved.
Definition: base_struct.h:126