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  if( TextePcb->GetEditFlags() == 0 ) // i.e. not edited, or moved
252  SaveCopyInUndoList( TextePcb, UR_ROTATED, TextePcb->GetTextPos() );
253  else // set flag edit, to show it was a complex command
254  TextePcb->SetFlags( IN_EDIT );
255 
256  OnModify();
257 #ifdef USE_WX_OVERLAY
258  m_canvas->Refresh();
259 #endif
260 }
261 
262 
263 void PCB_EDIT_FRAME::FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC )
264 {
265  if( aTextePcb == NULL )
266  return;
267 
268  aTextePcb->Draw( m_canvas, aDC, GR_XOR );
269 
270  aTextePcb->Flip( aTextePcb->GetTextPos() );
271 
272  aTextePcb->Draw( m_canvas, aDC, GR_XOR );
273  SetMsgPanel( aTextePcb );
274 
275  if( aTextePcb->GetEditFlags() == 0 ) // i.e. not edited, or moved
276  SaveCopyInUndoList( aTextePcb, UR_FLIPPED, aTextePcb->GetTextPos() );
277  else // set edit flag, for the current command
278  aTextePcb->SetFlags( IN_EDIT );
279 
280  OnModify();
281 #ifdef USE_WX_OVERLAY
282  m_canvas->Refresh();
283 #endif
284 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:195
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.
void SetTextAngle(double aAngle)
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:112
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
TEXTE_PCB class definition.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
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.
bool IsMoving() const
Definition: base_struct.h:224
void SetItalic(bool isItalic)
Definition: eda_text.h:186
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:240
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.
double GetTextAngle() const
Definition: eda_text.h:181
EDA_ITEM * GetCurItem() const
Definition: base_screen.h:233
void Delete_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
virtual const wxString GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:147
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:231
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.
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:115
bool IsNew() const
Definition: base_struct.h:222
#define IS_NEW
New item, just created.
Definition: base_struct.h:114
void Place_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
virtual PCB_LAYER_ID GetActiveLayer() const
Function GetActiveLayer returns the active layer.
virtual EDA_DRAW_FRAME * GetParent() const =0
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:259
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.
STATUS_FLAGS GetEditFlags() const
Definition: base_struct.h:263
void Rotate_Texte_Pcb(TEXTE_PCB *TextePcb, wxDC *DC)
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.
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:198
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:128
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:260
const wxPoint & GetTextPos() const
Definition: eda_text.h:241
BOARD * GetBoard() const
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.
static void Abort_Edit_Pcb_Text(EDA_DRAW_PANEL *Panel, wxDC *DC)
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:165
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
#define IS_MOVED
Item being moved.
Definition: base_struct.h:113