KiCad PCB EDA Suite
dialog_pcb_text_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) 2004-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 2010-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 /* Dialog editor for text on copper and technical layers (TEXTE_PCB class) */
27 /***************************************************************************/
28 
29 #include <fctsys.h>
30 #include <gr_basic.h>
31 #include <class_drawpanel.h>
32 #include <pcbnew.h>
33 #include <pcb_edit_frame.h>
34 #include <draw_graphic_text.h>
35 #include <confirm.h>
36 #include <base_units.h>
37 #include <wx/valnum.h>
38 #include <widgets/text_ctrl_eval.h>
39 
40 #include <class_board.h>
41 #include <class_pcb_text.h>
42 
43 #include <vector>
44 #include <wx/wx.h>
46 #include <pcb_layer_box_selector.h>
47 #include <board_commit.h>
48 
49 
50 class PCB_EDIT_FRAME;
51 class TEXTE_PCB;
52 
53 
55 {
56 public:
57  DIALOG_PCB_TEXT_PROPERTIES( PCB_EDIT_FRAME* parent, TEXTE_PCB* passedTextPCB, wxDC* DC = nullptr );
59 
60 private:
62  wxDC* m_DC;
64 
65  wxFloatingPointValidator<double> m_OrientValidator;
66  double m_OrientValue;
67 
68  bool TransferDataToWindow() override;
69  bool TransferDataFromWindow() override;
70 
71  // Virtual event handler
72  virtual void OnInitDlg( wxInitDialogEvent& event ) override
73  {
74  // Call the default wxDialog handler of a wxInitDialogEvent
76 
77  // Now all widgets have the size fixed, call FinishDialogSettings
79  }
80 
81  void OnCharHook( wxKeyEvent& aEvent );
82 };
83 
84 
93  TEXTE_PCB* passedTextPCB, wxDC* DC ) :
96 {
97  m_Parent = parent;
98  m_DC = DC;
99  m_SelectedPCBText = passedTextPCB;
100 
101  m_OrientValue = 0.0;
102  m_OrientValidator.SetRange( -360.0, 360.0 );
103  m_OrientCtrl->SetValidator( m_OrientValidator );
104  m_OrientValidator.SetWindow( m_OrientCtrl );
105 
106  m_StandardSizerOK->SetDefault();
107 
108  // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
109  // so we have to listen to wxEVT_CHAR_HOOK events instead.
110  m_TextContentCtrl->Connect( wxEVT_CHAR_HOOK,
111  wxKeyEventHandler( DIALOG_PCB_TEXT_PROPERTIES::OnCharHook ),
112  NULL, this );
113 }
114 
115 
117 {
118  m_TextContentCtrl->Disconnect( wxEVT_CHAR_HOOK,
119  wxKeyEventHandler( DIALOG_PCB_TEXT_PROPERTIES::OnCharHook ),
120  NULL, this );
121 }
122 
123 
128 {
129  m_canvas->SetIgnoreMouseEvents( true );
130 #ifndef __WXMAC__
131  DIALOG_PCB_TEXT_PROPERTIES dlg( this, TextPCB, DC );
132 #else
133  // Avoid "writes" in the dialog, creates errors with WxOverlay and NSView
134  // Raising an Exception - Fixes #891347
135  DIALOG_PCB_TEXT_PROPERTIES dlg( this, TextPCB, NULL );
136 #endif
137  dlg.ShowModal();
138  m_canvas->MoveCursorToCrossHair();
139  m_canvas->SetIgnoreMouseEvents( false );
140 }
141 
142 
143 void DIALOG_PCB_TEXT_PROPERTIES::OnCharHook( wxKeyEvent& aEvent )
144 {
145  if( aEvent.GetKeyCode() == WXK_TAB )
146  {
147  int flags = 0;
148  if( !aEvent.ShiftDown() )
149  flags |= wxNavigationKeyEvent::IsForward;
150  if( aEvent.ControlDown() )
151  flags |= wxNavigationKeyEvent::WinChange;
152  NavigateIn( flags );
153  }
154  else if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
155  {
157  EndModal( 1 );
158  }
159  else
160  {
161  aEvent.Skip();
162  }
163 }
164 
165 
167 {
168  // Put units symbols to text labels where appropriate
174 
175  // Fill fields with current values
177 
183 
184  // Configure the layers list selector
186 
187  // A text has no sense on edge cut layer
192 
194 
196  m_DisplayCtrl->SetSelection( 1 );
197  else
198  m_DisplayCtrl->SetSelection( 0 );
199 
200  if( m_SelectedPCBText->IsItalic() )
201  m_StyleCtrl->SetSelection( 1 );
202  else
203  m_StyleCtrl->SetSelection( 0 );
204 
205  // Set justification
207  m_justifyChoice->SetSelection( (int) hJustify + 1 );
208 
209  // Manually set tab order
210  m_SizeXCtrl->MoveAfterInTabOrder( m_TextContentCtrl );
211  m_SizeYCtrl->MoveAfterInTabOrder( m_SizeXCtrl );
212  m_ThicknessCtrl->MoveAfterInTabOrder( m_SizeYCtrl );
213  m_PositionXCtrl->MoveAfterInTabOrder( m_ThicknessCtrl );
214  m_PositionYCtrl->MoveAfterInTabOrder( m_PositionXCtrl );
215  m_OrientCtrl->MoveAfterInTabOrder( m_PositionYCtrl );
216  m_LayerSelectionCtrl->MoveAfterInTabOrder( m_OrientCtrl );
217  m_StyleCtrl->MoveAfterInTabOrder( m_LayerSelectionCtrl );
218  m_DisplayCtrl->MoveAfterInTabOrder( m_StyleCtrl );
219  m_justifyChoice->MoveAfterInTabOrder( m_DisplayCtrl );
220 
221  // Set focus on most important control
222  m_TextContentCtrl->SetFocus();
223  m_TextContentCtrl->SetSelection( -1, -1 );
224 
225  return DIALOG_PCB_TEXT_PROPERTIES_BASE::TransferDataToWindow();
226 }
227 
228 
230 {
231  if( !DIALOG_PCB_TEXT_PROPERTIES_BASE::TransferDataFromWindow() )
232  return false;
233 
234  BOARD_COMMIT commit( m_Parent );
235  commit.Modify( m_SelectedPCBText );
236 
237  // Test for acceptable layer.
238  // Incorrect layer can happen for old boards,
239  // having texts on edge cut layer for instance
241  {
242  wxMessageBox( _( "No layer selected, Please select the text layer" ) );
243  return false;
244  }
245 
246  wxPoint newPosition;
247  wxSize newSize;
248 
249  // If no other command in progress, prepare undo command
250  // (for a command in progress, will be made later, at the completion of command)
251  bool pushCommit = ( m_SelectedPCBText->GetFlags() == 0 );
252 
253  /* set flag in edit to force undo/redo/abort proper operation,
254  * and avoid new calls to SaveCopyInUndoList for the same text
255  * this can occurs when a text is moved, and then rotated, edited ..
256  */
257  if( m_SelectedPCBText->GetFlags() != 0 )
259 
260 #ifndef USE_WX_OVERLAY
261  // Erase old text on screen if context is available
262  if( m_DC )
263  {
265  }
266 #endif
267 
268  // Set the new text content
269  if( !m_TextContentCtrl->GetValue().IsEmpty() )
270  {
272  }
273 
274  // Set PCB Text position
275  newPosition.x = ValueFromString( g_UserUnit, m_PositionXCtrl->GetValue() );
276  newPosition.y = ValueFromString( g_UserUnit, m_PositionYCtrl->GetValue() );
277  m_SelectedPCBText->SetTextPos( newPosition );
278 
279  // Check constraints and set PCB Text size
280  newSize.x = ValueFromString( g_UserUnit, m_SizeXCtrl->GetValue() );
281  newSize.y = ValueFromString( g_UserUnit, m_SizeYCtrl->GetValue() );
282 
283  if( newSize.x < TEXTS_MIN_SIZE )
284  newSize.x = TEXTS_MIN_SIZE;
285 
286  if( newSize.y < TEXTS_MIN_SIZE )
287  newSize.y = TEXTS_MIN_SIZE;
288 
289  if( newSize.x > TEXTS_MAX_WIDTH )
290  newSize.x = TEXTS_MAX_WIDTH;
291 
292  if( newSize.y > TEXTS_MAX_WIDTH )
293  newSize.y = TEXTS_MAX_WIDTH;
294 
295  m_SelectedPCBText->SetTextSize( newSize );
296 
297  // Set the new thickness
299  m_ThicknessCtrl->GetValue() ) );
300 
301  // Test for acceptable values for thickness and size and clamp if fails
302  int maxthickness = Clamp_Text_PenSize( m_SelectedPCBText->GetThickness(),
304 
305  if( m_SelectedPCBText->GetThickness() > maxthickness )
306  {
307  DisplayError( NULL,
308  _( "The text thickness is too large for the text size. It will be clamped" ) );
309  m_SelectedPCBText->SetThickness( maxthickness );
310  }
311 
312  // Set the layer on which the PCB text is laying
314 
315  // Set whether the PCB text is mirrored (faced down from layer face perspective)
316  m_SelectedPCBText->SetMirrored( m_DisplayCtrl->GetSelection() == 1 );
317 
318  // Set the text angle
320 
321  // Set whether the PCB text is slanted (it is not italics, as italics has additional curves in style)
322  m_SelectedPCBText->SetItalic( m_StyleCtrl->GetSelection() );
323 
324  // Set justification
325  switch( m_justifyChoice->GetSelection() )
326  {
327  case 0:
329  break;
330  case 1:
332  break;
333  case 2:
335  break;
336  default:
337  break;
338  }
339 
340 #ifndef USE_WX_OVERLAY
341  // Finally, display new text if there is a context to do so
342  if( m_DC )
343  {
345  }
346 #else
347  m_Parent->Refresh();
348 #endif
349 
350  if( pushCommit )
351  commit.Push( _( "Change text properties" ) );
352 
353  return true;
354 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:176
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:266
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
void SetTextAngle(double aAngle)
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...
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:107
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:47
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:222
DIALOG_PCB_TEXT_PROPERTIES(PCB_EDIT_FRAME *parent, TEXTE_PCB *passedTextPCB, wxDC *DC=nullptr)
DIALOG_PCB_TEXT_PROPERTIES, derived from DIALOG_PCB_TEXT_PROPERTIES_BASE.
void InstallTextPCBOptionsFrame(TEXTE_PCB *TextPCB, wxDC *DC)
Routine for main window class to launch text properties dialog.
bool IsItalic() const
Definition: eda_text.h:168
#define TEXTS_MAX_WIDTH
Maximum text width in Pcbnew units value (0.5 inches)
Definition: pcbnew.h:68
wxFloatingPointValidator< double > m_OrientValidator
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.
Class BOARD to handle a board.
void SetItalic(bool isItalic)
Definition: eda_text.h:167
int GetTextWidth() const
Definition: eda_text.h:216
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:221
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:212
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
double GetTextAngleDegrees() const
Definition: eda_text.h:164
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:188
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:264
Class DIALOG_PCB_TEXT_PROPERTIES_BASE.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
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
int SetLayerSelection(LAYER_NUM layer)
bool SetLayersHotkeys(bool value)
#define TEXTS_MIN_SIZE
Minimum text size in Pcbnew units value (5 mils)
Definition: pcbnew.h:66
virtual void OnInitDlg(wxInitDialogEvent &event) override
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
void AddUnitSymbol(wxStaticText &Stext, EDA_UNITS_T aUnit)
Definition: base_units.cpp:515
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:191
bool IsMirrored() const
Definition: eda_text.h:177
LAYER_NUM GetLayerSelection() const
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
int GetTextHeight() const
Definition: eda_text.h:219
const wxSize & GetTextSize() const
Definition: eda_text.h:213
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:146
virtual void SetText(const wxString &aText)
Definition: eda_text.h:139