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 
42 #include <class_board.h>
43 #include <class_pcb_text.h>
44 #include <class_dimension.h>
45 
46 #include <pcbnew.h>
49 
50 /* Local functions */
51 static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
52  const wxPoint& aPosition, bool aErase );
53 
54 static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
55  const wxPoint& aPosition, bool aErase );
56 static void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
57 
58 
59 /* Local variables : */
60 static int status_dimension; /* Used in dimension creation:
61  * = 0 : initial value: no dimension in progress
62  * = 1 : First point created
63  * = 2 : Second point created, the text must be placed */
64 
65 /*
66  * A dimension has this shape:
67  * It has 2 reference points, and a text
68  * | |
69  * | dist |
70  * |<---------->|
71  * | |
72  *
73  */
74 
75 
76 /*********************************/
77 /* class DIALOG_DIMENSION_EDITOR */
78 /*********************************/
79 
81 {
82 private:
83 
85  wxDC* m_DC;
87 
88 public:
89 
90  // Constructor and destructor
91  DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent, DIMENSION* aDimension, wxDC* aDC );
93  {
94  }
95 
96 
97 private:
98  virtual void OnOKClick( wxCommandEvent& event ) override;
99 };
100 
101 
103  DIMENSION* aDimension, wxDC* aDC ) :
105 {
106  SetFocus();
107 
108  m_parent = aParent;
109  m_DC = aDC;
110 
111  m_currentDimension = aDimension;
112 
113  if( aDimension->Text().IsMirrored() )
114  m_rbMirror->SetSelection( 1 );
115  else
116  m_rbMirror->SetSelection( 0 );
117 
118  m_Name->SetValue( aDimension->Text().GetText() );
119 
120  // Enter size value in dialog
125 
126  // Enter lines thickness value in dialog
127  PutValueInLocalUnits( *m_TxtWidthCtrl, aDimension->GetWidth() );
129 
130  // Enter position value in dialog
131  PutValueInLocalUnits( *m_textCtrlPosX, aDimension->Text().GetTextPos().x );
133  PutValueInLocalUnits( *m_textCtrlPosY, aDimension->Text().GetTextPos().y );
135 
136  // Configure the layers list selector
137  if( !m_parent->GetBoard()->IsLayerEnabled( aDimension->GetLayer() ) )
138  // Should not happens, because one cannot select a board item on a
139  // not activated layer, but ...
141 
146 
147  if( m_SelLayerBox->SetLayerSelection( aDimension->GetLayer() ) < 0 )
148  {
149  wxMessageBox( _( "This item has an illegal layer id.\n"
150  "Now, forced on the drawings layer. Please, fix it" ) );
152  }
153 
154  m_sdbSizerBtsOK->SetDefault();
155 
156  // Now all widgets have the size fixed, call FinishDialogSettings
158 }
159 
160 
161 void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
162 {
163  BOARD_COMMIT commit( m_parent );
164 
166 
167  if( !m_parent->GetBoard()->IsLayerEnabled( newlayer ) )
168  {
169  wxMessageBox( _( "The layer currently selected is not enabled for this board\n"
170  "You cannot use it" ) );
171  return;
172  }
173 
174 #ifndef USE_WX_OVERLAY
175  if( m_DC ) // Delete old text.
176  {
178  }
179 #endif
180 
181  commit.Modify( m_currentDimension );
182 
183  if( m_Name->GetValue() != wxEmptyString )
184  {
185  m_currentDimension->SetText( m_Name->GetValue() );
186  }
187 
188  wxString msg;
189 
190  // Get new size value:
191  msg = m_TxtSizeXCtrl->GetValue();
193  msg = m_TxtSizeYCtrl->GetValue();
195 
196  // Get new position value:
197  // It will be copied later in dimension, because
198  msg = m_textCtrlPosX->GetValue();
199  wxPoint pos;
200  pos.x = ValueFromString( g_UserUnit, msg );
201  msg = m_textCtrlPosY->GetValue();
202  pos.y = ValueFromString( g_UserUnit, msg );
204 
205  // Get new line thickness value:
206  msg = m_TxtWidthCtrl->GetValue();
207  int width = ValueFromString( g_UserUnit, msg );
208  int maxthickness = Clamp_Text_PenSize( width, m_currentDimension->Text().GetTextSize() );
209 
210  if( width > maxthickness )
211  {
212  DisplayError( NULL,
213  _( "The text thickness is too large for the text size. "
214  "It will be clamped" ) );
215  width = maxthickness;
216  }
217 
218  m_currentDimension->SetWidth( width );
220  m_currentDimension->Text().SetMirrored( ( m_rbMirror->GetSelection() == 1 ) ? true : false );
221  m_currentDimension->SetLayer( newlayer );
222 
223 #ifndef USE_WX_OVERLAY
224  if( m_DC ) // Display new text
225  {
227  }
228 #else
229  m_parent->Refresh();
230 #endif
231 
232  commit.Push( _( "Modifed dimensions properties" ) );
233  event.Skip(); // ends returning wxID_OK (default behavior)
234 }
235 
236 
237 static void AbortBuildDimension( EDA_DRAW_PANEL* Panel, wxDC* aDC )
238 {
239  DIMENSION* dimension = (DIMENSION*) Panel->GetScreen()->GetCurItem();
240 
241  if( dimension )
242  {
243  if( dimension->IsNew() )
244  {
245  dimension->Draw( Panel, aDC, GR_XOR );
246  dimension->DeleteStructure();
247  }
248  else
249  {
250  dimension->Draw( Panel, aDC, GR_OR );
251  }
252  }
253 
254  status_dimension = 0;
255  ((PCB_EDIT_FRAME*)Panel->GetParent())->SetCurItem( NULL );
256 }
257 
258 
260 {
261  wxPoint pos;
262 
263  if( aDimension == NULL )
264  {
265  status_dimension = 1;
266  pos = GetCrossHairPosition();
267 
268  aDimension = new DIMENSION( GetBoard() );
269  aDimension->SetFlags( IS_NEW );
270  aDimension->SetLayer( GetActiveLayer() );
271  aDimension->SetOrigin( pos );
272  aDimension->SetEnd( pos );
273 
274  aDimension->Text().SetTextSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
275  int width = GetBoard()->GetDesignSettings().m_PcbTextWidth;
276  int maxthickness = Clamp_Text_PenSize(width, aDimension->Text().GetTextSize() );
277 
278  if( width > maxthickness )
279  {
280  width = maxthickness;
281  }
282 
283  aDimension->Text().SetThickness( width );
284  aDimension->SetWidth( width );
285  aDimension->AdjustDimensionDetails();
286  aDimension->Draw( m_canvas, aDC, GR_XOR );
287 
289  return aDimension;
290  }
291 
292  // Dimension != NULL
293  if( status_dimension == 1 )
294  {
295  status_dimension = 2;
296  return aDimension;
297  }
298 
299  aDimension->Draw( m_canvas, aDC, GR_OR );
300  aDimension->ClearFlags();
301 
302  /* ADD this new item in list */
303  GetBoard()->Add( aDimension );
304 
305  // Add store it in undo/redo list
306  SaveCopyInUndoList( aDimension, UR_NEW );
307 
308  OnModify();
309  m_canvas->SetMouseCapture( NULL, NULL );
310 
311  return NULL;
312 }
313 
314 
315 static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
316  const wxPoint& aPosition, bool aErase )
317 {
318  PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
319  DIMENSION* Dimension = (DIMENSION*) screen->GetCurItem();
320  wxPoint pos = aPanel->GetParent()->GetCrossHairPosition();
321 
322  if( Dimension == NULL )
323  return;
324 
325  // Erase previous dimension.
326  if( aErase )
327  {
328  Dimension->Draw( aPanel, aDC, GR_XOR );
329  }
330 
331  Dimension->SetLayer( screen->m_Active_Layer );
332 
333  if( status_dimension == 1 )
334  {
335  Dimension->m_featureLineDO = pos;
336  Dimension->m_crossBarF = Dimension->m_featureLineDO;
337  Dimension->AdjustDimensionDetails( );
338  }
339  else
340  {
341  /* Calculating the direction of travel perpendicular to the selected axis. */
342  double angle = Dimension->GetAngle() + (M_PI / 2);
343 
344  wxPoint delta = pos - Dimension->m_featureLineDO;
345  double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
346  Dimension->SetHeight( depl );
347  }
348 
349  Dimension->Draw( aPanel, aDC, GR_XOR );
350 }
351 
352 
354 {
355  if( aDimension == NULL )
356  return;
357 
358  DIALOG_DIMENSION_EDITOR dlg( this, aDimension, aDC );
359  dlg.ShowModal();
360 }
361 
362 
363 void PCB_EDIT_FRAME::DeleteDimension( DIMENSION* aDimension, wxDC* aDC )
364 {
365  if( aDimension == NULL )
366  return;
367 
368  if( aDC )
369  aDimension->Draw( m_canvas, aDC, GR_XOR );
370 
371  SaveCopyInUndoList( aDimension, UR_DELETED );
372  aDimension->UnLink();
373  OnModify();
374 }
375 
376 
377 /* Initialize parameters to move a pcb text
378  */
380 
382 {
383  if( aItem == NULL )
384  return;
385 
386  // Store the initial position for undo/abort command
387  initialTextPosition = aItem->Text().GetTextPos();
388 
389  aItem->Draw( m_canvas, DC, GR_XOR );
390  aItem->SetFlags( IS_MOVED );
391  SetMsgPanel( aItem );
392 
393  SetCrossHairPosition( aItem->Text().GetTextPos() );
395 
397  SetCurItem( aItem );
398  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
399 }
400 
401 
402 /* Move dimension text following the cursor. */
403 static void MoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
404  bool aErase )
405 {
406  DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
407 
408  if( dimension == NULL )
409  return;
410 
411  if( aErase )
412  dimension->Draw( aPanel, aDC, GR_XOR );
413 
414  dimension->Text().SetTextPos( aPanel->GetParent()->GetCrossHairPosition() );
415 
416  dimension->Draw( aPanel, aDC, GR_XOR );
417 }
418 
419 
420 /*
421  * Abort current text edit progress.
422  *
423  * If a text is selected, its initial coord are regenerated
424  */
425 void AbortMoveDimensionText( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
426 {
427  DIMENSION* dimension = (DIMENSION*) aPanel->GetScreen()->GetCurItem();
428  ( (PCB_EDIT_FRAME*) aPanel->GetParent() )->SetCurItem( NULL );
429 
430  aPanel->SetMouseCapture( NULL, NULL );
431 
432  if( dimension == NULL ) // Should not occur
433  return;
434 
435  dimension->Draw( aPanel, aDC, GR_XOR );
436  dimension->Text().SetTextPos( initialTextPosition );
437  dimension->ClearFlags();
438  dimension->Draw( aPanel, aDC, GR_OR );
439 }
440 
441 
442 /*
443  * Place the current dimension text being moving
444  */
446 {
447  m_canvas->SetMouseCapture( NULL, NULL );
448  SetCurItem( NULL );
449 
450  if( aItem == NULL )
451  return;
452 
453  aItem->Draw( m_canvas, DC, GR_OR );
454  OnModify();
455 
456  wxPoint tmp = aItem->Text().GetTextPos();
457  aItem->Text().SetTextPos( initialTextPosition );
458  SaveCopyInUndoList( aItem, UR_CHANGED );
459  aItem->Text().SetTextPos( tmp );
460  aItem->ClearFlags();
461 }
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:1001
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:363
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:230
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:337
void PlaceDimensionText(DIMENSION *aItem, wxDC *DC)
Definition: dimension.cpp:445
virtual void OnOKClick(wxCommandEvent &event) override
Definition: dimension.cpp:161
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:381
void ShowDimensionPropertyDialog(DIMENSION *aDimension, wxDC *aDC)
Definition: dimension.cpp:353
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:259
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:237
#define IS_NEW
New item, just created.
Definition: base_struct.h:127
PCB_EDIT_FRAME * m_parent
Definition: dimension.cpp:84
DIMENSION class definition.
static void MoveDimensionText(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: dimension.cpp:403
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:267
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:60
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:368
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:315
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:172
bool SetLayersHotkeys(bool value)
DIMENSION * m_currentDimension
Definition: dimension.cpp:86
void AdjustDimensionDetails(bool aDoNotChangeText=false)
Function AdjustDimensionDetails Calculate coordinates of segments used to draw the dimension...
static wxPoint initialTextPosition
Definition: dimension.cpp:379
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:265
void AddUnitSymbol(wxStaticText &Stext, EDA_UNITS_T aUnit)
Definition: base_units.cpp:509
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:102
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:268
This file is part of the common libary.
static void AbortMoveDimensionText(EDA_DRAW_PANEL *aPanel, wxDC *aDC)
Definition: dimension.cpp:425
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:71
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