KiCad PCB EDA Suite
edit_pcb_text.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) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
31 #include <fctsys.h>
32 #include <gr_basic.h>
33 #include <class_drawpanel.h>
34 #include <pcbnew.h>
35 #include <pcb_edit_frame.h>
36 #include <macros.h>
37 
38 #include <class_board.h>
39 #include <class_pcb_text.h>
40 #include <class_board_item.h>
41 
42 
43 static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
44  bool aErase );
45 static void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC );
46 
47 
48 static TEXTE_PCB s_TextCopy( (BOARD_ITEM*) NULL ); // copy of the edited text used to
49  // undo/redo/abort a complex edit command
50 
51 
52 /*
53  * Abort current text edit progress.
54  * If a text is selected, its initial coord are regenerated
55  */
56 void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC )
57 {
58  TEXTE_PCB* TextePcb = (TEXTE_PCB*) Panel->GetScreen()->GetCurItem();
59  ( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
60 
61  Panel->SetMouseCapture( NULL, NULL );
62 
63  if( TextePcb == NULL ) // Should not occur
64  return;
65 
66 #ifndef USE_WX_OVERLAY
67  TextePcb->Draw( Panel, DC, GR_XOR );
68 #endif
69 
70  if( TextePcb->IsNew() ) // If new: remove it
71  {
72  TextePcb->DeleteStructure();
73  return;
74  }
75 
76 
77  TextePcb->SwapData( &s_TextCopy );
78  TextePcb->ClearFlags();
79 #ifndef USE_WX_OVERLAY
80  TextePcb->Draw( Panel, DC, GR_OR );
81 #else
82  Panel->Refresh();
83 #endif
84 }
85 
86 
87 /*
88  * Place the current text being moving
89  */
90 void PCB_EDIT_FRAME::Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
91 {
92  m_canvas->SetMouseCapture( NULL, NULL );
93  SetCurItem( NULL );
94 
95  if( TextePcb == NULL )
96  return;
97 
98  TextePcb->Draw( m_canvas, DC, GR_OR );
99  OnModify();
100 
101  if( TextePcb->IsNew() ) // If new: prepare undo command
102  {
103  SaveCopyInUndoList( TextePcb, UR_NEW );
104  TextePcb->ClearFlags();
105  return;
106  }
107 
108  if( TextePcb->IsMoving() ) // If moved only
109  {
110  SaveCopyInUndoList( TextePcb, UR_MOVED,
111  TextePcb->GetTextPos() - s_TextCopy.GetTextPos() );
112  }
113  else
114  {
115  // Restore initial params
116  TextePcb->SwapData( &s_TextCopy );
117  // Prepare undo command
118  SaveCopyInUndoList( TextePcb, UR_CHANGED );
119  // Restore current params
120  TextePcb->SwapData( &s_TextCopy );
121  }
122 
123  TextePcb->ClearFlags();
124 #ifdef USE_WX_OVERLAY
125  m_canvas->Refresh();
126 #endif
127 }
128 
129 
130 void PCB_EDIT_FRAME::StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aErase )
131 {
132  if( aTextePcb == NULL )
133  return;
134 
135  // if it is an existing item: prepare a copy to undo/abort command
136  if( !aTextePcb->IsNew() )
137  s_TextCopy = *aTextePcb;
138 
139  aTextePcb->SetFlags( IS_MOVED );
140  SetMsgPanel( aTextePcb );
141 
142 #ifdef USE_WX_OVERLAY
143  m_canvas->Refresh();
144 #endif
145 
146  SetCrossHairPosition( aTextePcb->GetTextPos() );
148 
150  SetCurItem( aTextePcb );
151  m_canvas->CallMouseCapture( aDC, wxDefaultPosition, aErase );
152 }
153 
154 
155 // Move PCB text following the cursor.
156 static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
157  bool aErase )
158 {
159  TEXTE_PCB* TextePcb = (TEXTE_PCB*) aPanel->GetScreen()->GetCurItem();
160 
161  if( TextePcb == NULL )
162  return;
163 
164  if( aErase )
165  TextePcb->Draw( aPanel, aDC, GR_XOR );
166 
167  TextePcb->SetTextPos( aPanel->GetParent()->GetCrossHairPosition() );
168 
169  TextePcb->Draw( aPanel, aDC, GR_XOR );
170 }
171 
172 
173 void PCB_EDIT_FRAME::Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
174 {
175  if( TextePcb == NULL )
176  return;
177 
178  TextePcb->Draw( m_canvas, DC, GR_XOR );
179 
180  SaveCopyInUndoList( TextePcb, UR_DELETED );
181  TextePcb->UnLink();
182  m_canvas->SetMouseCapture( NULL, NULL );
183  SetCurItem( NULL );
184 }
185 
186 
188 {
189  TEXTE_PCB* textePcb = new TEXTE_PCB( GetBoard() );
190 
191  if( aText )
192  {
193  *textePcb = *aText;
194  GetBoard()->Add( textePcb );
195  textePcb->SetFlags( IS_NEW );
196  if( aDC )
197  StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
198  }
199  else
200  {
201  GetBoard()->Add( textePcb );
202  textePcb->SetFlags( IS_NEW );
203 
204  PCB_LAYER_ID layer = GetActiveLayer();
205 
206  textePcb->SetLayer( layer );
207 
208  // Set the mirrored option for layers on the BACK side of the board
209  if( layer == B_Cu || layer == B_SilkS ||
210  layer == B_Paste || layer == B_Mask ||
211  layer == B_Adhes
212  )
213  textePcb->SetMirrored( true );
214 
215  textePcb->SetTextSize( GetBoard()->GetDesignSettings().GetTextSize( layer ) );
216  textePcb->SetTextPos( GetCrossHairPosition() );
217  textePcb->SetThickness( GetBoard()->GetDesignSettings().GetTextThickness( layer ) );
218  textePcb->SetItalic( GetBoard()->GetDesignSettings().GetTextItalic( layer ) );
219 
220  InstallTextOptionsFrame( textePcb, aDC );
221 
222  if( textePcb->GetText().IsEmpty() )
223  {
224  textePcb->DeleteStructure();
225  textePcb = NULL;
226  }
227  else if( aDC )
228  {
229  StartMoveTextePcb( textePcb, aDC );
230  }
231  }
232 
233  return textePcb;
234 }
235 
236 
237 void PCB_EDIT_FRAME::Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
238 {
239  if( TextePcb == NULL )
240  return;
241 
242  // Erase previous text:
243  TextePcb->Draw( m_canvas, DC, GR_XOR );
244 
245  TextePcb->SetTextAngle( TextePcb->GetTextAngle() + 900 );
246 
247  // Redraw text in new position:
248  TextePcb->Draw( m_canvas, DC, GR_XOR );
249  SetMsgPanel( TextePcb );
250 
251  int mask = EDA_ITEM_ALL_FLAGS - ( SELECTED | HIGHLIGHTED | BRIGHTENED );
252  if( ( TextePcb->GetFlags() & mask ) == 0 ) // i.e. not edited, or moved
253  SaveCopyInUndoList( TextePcb, UR_ROTATED, TextePcb->GetTextPos() );
254  else // set flag edit, to show it was a complex command
255  TextePcb->SetFlags( IN_EDIT );
256 
257  OnModify();
258 #ifdef USE_WX_OVERLAY
259  m_canvas->Refresh();
260 #endif
261 }
262 
263 
264 void PCB_EDIT_FRAME::FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC )
265 {
266  if( aTextePcb == NULL )
267  return;
268 
269  aTextePcb->Draw( m_canvas, aDC, GR_XOR );
270 
271  aTextePcb->Flip( aTextePcb->GetTextPos() );
272 
273  aTextePcb->Draw( m_canvas, aDC, GR_XOR );
274  SetMsgPanel( aTextePcb );
275 
276  int mask = EDA_ITEM_ALL_FLAGS - ( SELECTED | HIGHLIGHTED | BRIGHTENED );
277  if( ( aTextePcb->GetFlags() & mask ) == 0 ) // i.e. not edited, or moved
278  SaveCopyInUndoList( aTextePcb, UR_FLIPPED, aTextePcb->GetTextPos() );
279  else // set edit flag, for the current command
280  aTextePcb->SetFlags( IN_EDIT );
281 
282  OnModify();
283 #ifdef USE_WX_OVERLAY
284  m_canvas->Refresh();
285 #endif
286 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:191
virtual BASE_SCREEN * GetScreen()=0
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
virtual void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
void SetTextAngle(double aAngle)
bool IsMoving() const
Definition: base_struct.h:221
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:112
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:237
EDA_ITEM * GetCurItem() const
Definition: base_screen.h:233
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
bool IsNew() const
Definition: base_struct.h:219
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
void FlipTextePcb(TEXTE_PCB *aTextePcb, wxDC *aDC)
Class BOARD to handle a board.
void SetItalic(bool isItalic)
Definition: eda_text.h:182
void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
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:236
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...
BOARD * GetBoard() const
void Delete_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:227
virtual void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
virtual void UnLink()
Function UnLink detaches this object from its owner.
void InstallTextOptionsFrame(BOARD_ITEM *aText, wxDC *aDC)
Routine for main window class to launch text properties dialog.
#define EDA_ITEM_ALL_FLAGS
Definition: base_struct.h:145
double GetTextAngle() const
Definition: eda_text.h:177
This file contains miscellaneous commonly used macros and functions.
wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
Definition: common.cpp:111
#define IS_NEW
New item, just created.
Definition: base_struct.h:114
void Place_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
virtual EDA_DRAW_FRAME * GetParent() const =0
#define SELECTED
Definition: base_struct.h:121
PCB_LAYER_ID
A quick note on layer IDs:
void StartMoveTextePcb(TEXTE_PCB *aTextePcb, wxDC *aDC, bool aErase=true)
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:256
TEXTE_PCB * CreateTextePcb(wxDC *aDC, TEXTE_PCB *aText=NULL)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
void Rotate_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
virtual 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 Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
virtual void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:138
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame...
static void Move_Texte_Pcb(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
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:202
static TEXTE_PCB s_TextCopy((BOARD_ITEM *) NULL)
Definition: gr_basic.h:38
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:123
#define HIGHLIGHTED
item is drawn in normal colors, when the rest is darkened
Definition: base_struct.h:137
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL)
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Set the screen cross hair position to aPosition in logical (drawing) units.
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
static void Abort_Edit_Pcb_Text(EDA_DRAW_PANEL *Panel, wxDC *DC)
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:161
#define IS_MOVED
Item being moved.
Definition: base_struct.h:113