KiCad PCB EDA Suite
target_edit.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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
6  *
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 <class_drawpanel.h>
33 #include <pcb_edit_frame.h>
34 #include <dialog_helpers.h>
35 #include <base_units.h>
36 #include <gr_basic.h>
37 #include <board_commit.h>
38 
39 #include <class_board.h>
40 #include <class_pcb_target.h>
41 
42 #include <pcbnew.h>
44 #include <widgets/unit_binder.h>
45 
46 // Routines Locales
47 static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC );
49  wxDC* aDC,
50  const wxPoint& aPosition,
51  bool aErase );
52 
53 // Local variables :
54 static int MireDefaultSize = Millimeter2iu( 5 );
55 
56 static PCB_TARGET s_TargetCopy( NULL ); // Used to store "old" values of the current item
57  // parameters before editing for undo/redo/cancel
58 
59 /**********************************/
60 /* class DIALOG_TARGET_PROPERTIES */
61 /**********************************/
62 
64 {
65 private:
67  wxDC* m_DC;
69 
72 
73 public:
74  DIALOG_TARGET_PROPERTIES( PCB_EDIT_FRAME* aParent, PCB_TARGET* aTarget, wxDC* aDC );
76 
77 private:
78  bool TransferDataToWindow() override;
79  bool TransferDataFromWindow() override;
80 };
81 
82 
84 {
85  DIALOG_TARGET_PROPERTIES dialog( this, aTarget, DC );
86 
87  dialog.ShowModal();
88 }
89 
90 
92  wxDC* aDC ) :
94  m_Parent( aParent ),
95  m_DC( aDC ),
96  m_Target( aTarget ),
97  m_Size( aParent, m_sizeLabel, m_sizeCtrl, m_sizeUnits, true ),
99 {
100  m_sdbSizerButtsOK->SetDefault();
101 
103 
104  // Now all widgets have the size fixed, call FinishDialogSettings
106 }
107 
108 
110 {
113 
114  m_TargetShape->SetSelection( m_Target->GetShape() ? 1 : 0 );
115 
116  return true;
117 }
118 
119 
121 {
122  // Zero-size targets are hard to see/select.
123  if( !m_Size.Validate( Mils2iu( 1 ), INT_MAX ) )
124  return false;
125 
126  BOARD_COMMIT commit( m_Parent );
127  commit.Modify( m_Target );
128 
129  if( m_DC )
131 
132  // Save old item in undo list, if is is not currently edited (will be later if so)
133  bool pushCommit = ( m_Target->GetFlags() == 0 );
134 
135  if( m_Target->GetFlags() != 0 ) // other edit in progress (MOVE, NEW ..)
136  m_Target->SetFlags( IN_EDIT ); // set flag in edit to force
137  // undo/redo/abort proper operation
138 
141  m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 );
142 
143  if( m_DC )
145 
146  if( pushCommit )
147  commit.Push( _( "Modified alignment target" ) );
148 
149  return true;
150 }
151 
152 
153 void PCB_EDIT_FRAME::DeleteTarget( PCB_TARGET* aTarget, wxDC* DC )
154 {
155  if( aTarget == NULL )
156  return;
157 
158  aTarget->Draw( m_canvas, DC, GR_XOR );
159  SaveCopyInUndoList( aTarget, UR_DELETED );
160  aTarget->UnLink();
161 }
162 
163 
164 static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC )
165 {
166  BASE_SCREEN* screen = Panel->GetScreen();
167  PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
168 
169  ( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
170 
171  Panel->SetMouseCapture( NULL, NULL );
172 
173  if( target == NULL )
174  return;
175 
176  target->Draw( Panel, DC, GR_XOR );
177 
178  if( target->IsNew() ) // If it is new, delete it
179  {
180  target->Draw( Panel, DC, GR_XOR );
181  target->DeleteStructure();
182  target = NULL;
183  }
184  else // it is an existing item: retrieve initial values of parameters
185  {
186  if( ( target->GetFlags() & (IN_EDIT | IS_MOVED) ) )
187  {
188  target->SetPosition( s_TargetCopy.GetPosition() );
189  target->SetWidth( s_TargetCopy.GetWidth() );
190  target->SetSize( s_TargetCopy.GetSize() );
191  target->SetShape( s_TargetCopy.GetShape() );
192  }
193 
194  target->ClearFlags();
195  target->Draw( Panel, DC, GR_OR );
196  }
197 }
198 
199 
201 {
202  PCB_TARGET* target = new PCB_TARGET( GetBoard() );
203 
204  target->SetFlags( IS_NEW );
205 
206  GetBoard()->Add( target );
207 
208  target->SetLayer( Edge_Cuts );
209  target->SetWidth( GetDesignSettings().GetLineThickness( Edge_Cuts ) );
210  target->SetSize( MireDefaultSize );
211  target->SetPosition( GetCrossHairPosition() );
212 
213  PlaceTarget( target, DC );
214 
215  return target;
216 }
217 
218 
219 void PCB_EDIT_FRAME::BeginMoveTarget( PCB_TARGET* aTarget, wxDC* DC )
220 {
221  if( aTarget == NULL )
222  return;
223 
224  s_TargetCopy = *aTarget;
225  aTarget->SetFlags( IS_MOVED );
226  m_canvas->SetMouseCapture( ShowTargetShapeWhileMovingMouse, AbortMoveAndEditTarget );
227  SetCurItem( aTarget );
228 }
229 
230 
231 void PCB_EDIT_FRAME::PlaceTarget( PCB_TARGET* aTarget, wxDC* DC )
232 {
233  if( aTarget == NULL )
234  return;
235 
236  aTarget->Draw( m_canvas, DC, GR_OR );
237  m_canvas->SetMouseCapture( NULL, NULL );
238  SetCurItem( NULL );
239  OnModify();
240 
241  if( aTarget->IsNew() )
242  {
243  SaveCopyInUndoList( aTarget, UR_NEW );
244  aTarget->ClearFlags();
245  return;
246  }
247 
248  if( aTarget->GetFlags() == IS_MOVED )
249  {
250  SaveCopyInUndoList( aTarget, UR_MOVED,
251  aTarget->GetPosition() - s_TargetCopy.GetPosition() );
252  aTarget->ClearFlags();
253  return;
254  }
255 
256  if( (aTarget->GetFlags() & IN_EDIT) )
257  {
258  aTarget->SwapData( &s_TargetCopy );
259  SaveCopyInUndoList( aTarget, UR_CHANGED );
260  aTarget->SwapData( &s_TargetCopy );
261  }
262 
263  aTarget->ClearFlags();
264 }
265 
266 
267 // Redraw the contour of the track while moving the mouse
268 static void ShowTargetShapeWhileMovingMouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
269  const wxPoint& aPosition, bool aErase )
270 {
271  BASE_SCREEN* screen = aPanel->GetScreen();
272  PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
273 
274  if( target == NULL )
275  return;
276 
277  if( aErase )
278  target->Draw( aPanel, aDC, GR_XOR );
279 
280  target->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
281 
282  target->Draw( aPanel, aDC, GR_XOR );
283 }
virtual BASE_SCREEN * GetScreen()=0
void BeginMoveTarget(PCB_TARGET *aTarget, wxDC *DC)
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
bool IsMoving() const
Definition: base_struct.h:221
void DeleteTarget(PCB_TARGET *aTarget, wxDC *DC)
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:112
Class DIALOG_TARGET_PROPERTIES_BASE.
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:385
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.
Implementation of conversion functions that require both schematic and board internal units...
int GetWidth() const
bool IsNew() const
Definition: base_struct.h:219
void SetSize(int aSize)
Class BOARD to handle a board.
virtual bool Validate(int aMin, int aMax, bool setFocusOnError=true)
Function Validate Validates the control against the given range, informing the user of any errors fou...
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void DeleteStructure()
Function DeleteStructure deletes this object after UnLink()ing it from its owner if it has one...
DIALOG_TARGET_PROPERTIES(PCB_EDIT_FRAME *aParent, PCB_TARGET *aTarget, wxDC *aDC)
Definition: target_edit.cpp:91
virtual void UnLink()
Function UnLink detaches this object from its owner.
bool TransferDataToWindow() override
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
void PlaceTarget(PCB_TARGET *aTarget, wxDC *DC)
bool TransferDataFromWindow() override
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
#define IS_NEW
New item, just created.
Definition: base_struct.h:114
PCB_TARGET * CreateTarget(wxDC *DC)
virtual EDA_DRAW_FRAME * GetParent() const =0
static PCB_TARGET s_TargetCopy(NULL)
static void AbortMoveAndEditTarget(EDA_DRAW_PANEL *Panel, wxDC *DC)
int GetShape() const
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:256
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
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 SetPosition(const wxPoint &aPos) override
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
Helper dialog and control classes.
void SetShape(int aShape)
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.
BOARD * GetBoard()
Definition: gr_basic.h:38
void ShowTargetOptionsDialog(PCB_TARGET *aTarget, wxDC *DC)
Definition: target_edit.cpp:83
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
void SetWidth(int aWidth)
int GetSize() const
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:257
static void ShowTargetShapeWhileMovingMouse(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
PCB_TARGET class definition.
PCB_EDIT_FRAME * m_Parent
Definition: target_edit.cpp:66
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
const wxPoint GetPosition() const override
static int MireDefaultSize
Definition: target_edit.cpp:54
#define IS_MOVED
Item being moved.
Definition: base_struct.h:113