KiCad PCB EDA Suite
edtxtmod.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2012 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 
30 #include <fctsys.h>
31 #include <gr_basic.h>
32 #include <common.h>
33 #include <class_drawpanel.h>
34 #include <drawtxt.h>
35 #include <trigo.h>
36 #include <wxBasePcbFrame.h>
37 #include <macros.h>
38 
39 #include <pcbnew.h>
40 #include <wxPcbStruct.h>
41 #include <module_editor_frame.h>
42 
43 #include <class_board.h>
44 #include <class_module.h>
45 #include <class_text_mod.h>
46 #include <class_pcb_text.h>
47 
48 
49 static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
50  bool aErase );
51 static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
52 
53 
54 wxPoint MoveVector; // Move vector for move edge, exported
55  // to dialog_edit mod_text.cpp
56 static wxPoint TextInitialPosition; // Mouse cursor initial position for
57  // undo/abort move command
58 static double TextInitialOrientation; // module text initial orientation for
59  // undo/abort move+rot command+rot
60 
61 
62 /* Add a new graphical text to the active module (footprint)
63  * Note there always are 2 mandatory texts: reference and value.
64  * New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS
65  */
67 {
68  TEXTE_MODULE* text = new TEXTE_MODULE( aModule );
69 
70  text->SetFlags( IS_NEW );
71 
73  std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true );
74  text->SetTextSize( GetDesignSettings().m_ModuleTextSize );
75  text->SetThickness( GetDesignSettings().m_ModuleTextWidth );
77 
78  if( LSET::AllTechMask().test( GetActiveLayer() ) ) // i.e. a possible layer for a text
79  text->SetLayer( GetActiveLayer() );
80 
81  InstallTextModOptionsFrame( text, NULL );
82 
84 
85  if( text->GetText().IsEmpty() )
86  {
87  delete text;
88  return NULL;
89  }
90 
91  // Add the new text object to the beginning of the footprint draw list.
92  if( aModule )
93  aModule->GraphicalItems().PushFront( text );
94 
95  text->ClearFlags();
96 
97  if( aDC )
98  text->Draw( m_canvas, aDC, GR_OR );
99 
100  SetMsgPanel( text );
101 
102  return text;
103 }
104 
105 
106 /* Rotate text 90 degrees.
107  */
109 {
110  if( Text == NULL )
111  return;
112 
113  MODULE* module = (MODULE*) Text->GetParent();
114 
115  if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
116  {
117  if( IsType( FRAME_PCB ) )
118  SaveCopyInUndoList( module, UR_CHANGED );
119  }
120 
121  // we expect MoveVector to be (0,0) if there is no move in progress
122  Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
123 
124  Text->SetTextAngle( Text->GetTextAngle() + 900 );
125 
126  Text->Draw( m_canvas, DC, GR_XOR, MoveVector );
127  SetMsgPanel( Text );
128 
129  if( module )
130  module->SetLastEditTime();
131 
132  OnModify();
133 }
134 
135 
136 /*
137  * Deletes text in module (if not the reference or value)
138  */
140 {
141  MODULE* Module;
142 
143  if( Text == NULL )
144  return;
145 
146  Module = static_cast<MODULE*>( Text->GetParent() );
147 
148  if( Text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
149  {
151  Text->DeleteStructure();
152  OnModify();
153  Module->SetLastEditTime();
154  }
155 }
156 
157 
158 /*
159  * Abort text move in progress.
160  *
161  * If a text is selected, its initial coordinates are regenerated.
162  */
163 static void AbortMoveTextModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
164 {
165  BASE_SCREEN* screen = Panel->GetScreen();
166  TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
167  MODULE* Module;
168 
169  Panel->SetMouseCapture( NULL, NULL );
170 
171  if( Text == NULL )
172  return;
173 
174  Module = static_cast<MODULE*>( Text->GetParent() );
175 
176  Text->DrawUmbilical( Panel, DC, GR_XOR, -MoveVector );
177  Text->Draw( Panel, DC, GR_XOR, MoveVector );
178 
179  // If the text was moved (the move does not change internal data)
180  // it could be rotated while moving. So set old value for orientation
181  if( Text->IsMoving() )
183 
184  // Redraw the text
185  Panel->RefreshDrawingRect( Text->GetBoundingBox() );
186 
187  // leave it at (0,0) so we can use it Rotate when not moving.
188  MoveVector.x = MoveVector.y = 0;
189 
190  Text->ClearFlags();
191  Module->ClearFlags();
192 
193  screen->SetCurItem( NULL );
194 }
195 
196 
197 /* Start a text move.
198  */
200 {
201  if( Text == NULL )
202  return;
203 
204  MODULE *Module = static_cast<MODULE*>( Text->GetParent() );
205 
206  Text->SetFlags( IS_MOVED );
207  Module->SetFlags( IN_EDIT );
208 
209  MoveVector.x = MoveVector.y = 0;
210 
211  TextInitialPosition = Text->GetTextPos();
213 
214  // Center cursor on initial position of text
215  SetCrossHairPosition( TextInitialPosition );
217 
218  SetMsgPanel( Text );
219  SetCurItem( Text );
221  m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
222 }
223 
224 
225 /* Place the text a the cursor position when the left mouse button is clicked.
226  */
228 {
229  if( Text != NULL )
230  {
232  Text->DrawUmbilical( m_canvas, DC, GR_XOR, -MoveVector );
233 
234  // Update the coordinates for anchor.
235  MODULE* Module = static_cast<MODULE*>( Text->GetParent() );
236 
237  if( Module )
238  {
239  // Prepare undo command (a rotation can be made while moving)
240  double tmp = Text->GetTextAngle();
242 
243  if( IsType( FRAME_PCB ) )
244  SaveCopyInUndoList( Module, UR_CHANGED );
245  else
246  SaveCopyInUndoList( Module, UR_CHANGED );
247 
248  Text->SetTextAngle( tmp );
249 
250  // Set the new position for text.
251  Text->SetTextPos( GetCrossHairPosition() );
252  wxPoint textRelPos = Text->GetTextPos() - Module->GetPosition();
253  RotatePoint( &textRelPos, -Module->GetOrientation() );
254  Text->SetPos0( textRelPos );
255  Text->ClearFlags();
256  Module->ClearFlags();
257  Module->SetLastEditTime();
258  OnModify();
259 
260  // Redraw text.
262  }
263  else
264  {
265  Text->SetTextPos( GetCrossHairPosition() );
266  }
267  }
268 
269  // leave it at (0,0) so we can use it Rotate when not moving.
270  MoveVector.x = MoveVector.y = 0;
271 
272  m_canvas->SetMouseCapture( NULL, NULL );
273 }
274 
275 
276 static void Show_MoveTexte_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
277  bool aErase )
278 {
279  BASE_SCREEN* screen = aPanel->GetScreen();
280  TEXTE_MODULE* Text = static_cast<TEXTE_MODULE*>( screen->GetCurItem() );
281 
282  if( Text == NULL )
283  return;
284 
285  // Erase umbilical and text if necessary
286  if( aErase )
287  {
288  Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
289  Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
290  }
291 
292  MoveVector = TextInitialPosition - aPanel->GetParent()->GetCrossHairPosition();
293 
294  // Draw umbilical if text moved
295  if( MoveVector.x || MoveVector.y )
296  Text->DrawUmbilical( aPanel, aDC, GR_XOR, -MoveVector );
297 
298  // Redraw text
299  Text->Draw( aPanel, aDC, GR_XOR, MoveVector );
300 }
301 
302 void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC )
303 {
304  wxSize newSize;
305  int newThickness;
306 
307  if( aItem->Type() == PCB_TEXT_T )
308  {
309  newSize = GetDesignSettings().m_PcbTextSize;
310  newThickness = GetDesignSettings().m_PcbTextWidth;
311  TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem );
312 
313  // Exit if there's nothing to do
314  if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
315  return;
316 
318  text->SetTextSize( newSize );
319  text->SetThickness( newThickness );
320  }
321 
322  else if( aItem->Type() == PCB_MODULE_TEXT_T )
323  {
325  newThickness = GetDesignSettings().m_ModuleTextWidth;
326  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
327 
328  // Exit if there's nothing to do
329  if( text->GetTextSize() == newSize && text->GetThickness() == newThickness )
330  return;
331 
333  text->SetTextSize( newSize );
334  text->SetThickness( newThickness );
335  }
336  else
337  return;
338 
339  if( aDC )
340  m_canvas->Refresh();
341 
342  OnModify();
343 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
BOARD_ITEM_CONTAINER * GetParent() const
void SetCurItem(EDA_ITEM *aItem)
Function SetCurItem sets the currently selected object, m_CurrentItem.
Definition of class FOOTPRINT_EDIT_FRAME.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:255
bool IsMoving() const
Definition: base_struct.h:218
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:111
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
BOARD_DESIGN_SETTINGS & GetDesignSettings() const override
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
EDA_ITEM * GetCurItem() const
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Definition: draw_panel.cpp:326
void PushFront(T *aNewElement)
Function PushFront puts aNewElement at front of list sequence.
Definition: dlist.h:240
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
int m_ModuleTextWidth
Default footprint texts thickness.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
TEXT_TYPE GetType() const
int m_PcbTextWidth
current Pcb (not module) Text width
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:143
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 DeleteStructure()
Function DeleteStructure deletes this object after UnLink()ing it from its owner if it has one...
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
Definition: draw_panel.cpp:306
wxPoint MoveVector
Definition: edtxtmod.cpp:54
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:214
TEXTE_MODULE * CreateTextModule(MODULE *aModule, wxDC *aDC)
Creates a new text for the footprint.
Definition: edtxtmod.cpp:66
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void RotateTextModule(TEXTE_MODULE *Text, wxDC *DC)
Definition: edtxtmod.cpp:108
wxSize m_ModuleTextSize
Default footprint texts size.
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:348
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side...
Definition: lset.cpp:709
void SetLastEditTime(time_t aTime)
Definition: class_module.h:269
DLIST< BOARD_ITEM > & GraphicalItems()
Definition: class_module.h:136
double GetTextAngle() const
Definition: eda_text.h:164
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:154
This file contains miscellaneous commonly used macros and functions.
#define IS_NEW
New item, just created.
Definition: base_struct.h:113
static void AbortMoveTextModule(EDA_DRAW_PANEL *Panel, wxDC *DC)
Definition: edtxtmod.cpp:163
void ResetTextSize(BOARD_ITEM *aItem, wxDC *aDC)
Function ResetTextSize resets given field text size and width to current settings in Preferences->Dim...
Definition: edtxtmod.cpp:302
static wxPoint TextInitialPosition
Definition: edtxtmod.cpp:56
Footprint text class description.
Classes used in Pcbnew, CvPcb and GerbView.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:253
void InstallTextModOptionsFrame(TEXTE_MODULE *TextMod, wxDC *DC)
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:754
double GetOrientation() const
Definition: class_module.h:147
wxSize m_PcbTextSize
current Pcb (not module) Text size
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
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
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:175
virtual void SetPosition(const wxPoint &aPos) override
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw Draw the text according to the footprint pos and orient.
void SetPos0(const wxPoint &aPos)
void PlaceTexteModule(TEXTE_MODULE *Text, wxDC *DC)
Definition: edtxtmod.cpp:227
Definition: gr_basic.h:42
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
void DeleteTextModule(TEXTE_MODULE *Text)
Definition: edtxtmod.cpp:139
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
virtual void OnModify()
Function OnModify Virtual Must be called after a change in order to set the "modify" flag of the curr...
static void Show_MoveTexte_Module(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: edtxtmod.cpp:276
virtual void SaveCopyInUndoList(BOARD_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, const wxPoint &aTransformPoint=wxPoint(0, 0))=0
Function SaveCopyInUndoList (virtual pure) Creates a new entry in undo list of commands.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:188
void DrawUmbilical(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset)
Function DrawUmbilical draws a line from the TEXTE_MODULE origin to parent MODULE origin...
The common library.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:254
This file is part of the common libary.
bool IsType(FRAME_T aType) const
Definition: wxstruct.h:216
void StartMoveTexteModule(TEXTE_MODULE *Text, wxDC *DC)
Definition: edtxtmod.cpp:199
void SetTextAngle(double aAngle)
Module description (excepted pads)
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...
static double TextInitialOrientation
Definition: edtxtmod.cpp:58
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.
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:148
#define min(a, b)
Definition: auxiliary.h:85
#define IS_MOVED
Item being moved.
Definition: base_struct.h:112