KiCad PCB EDA Suite
block_libedit.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 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 2004-2017 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 
30 #include <fctsys.h>
31 #include <gr_basic.h>
32 #include <class_drawpanel.h>
33 #include <confirm.h>
34 
35 #include <general.h>
36 #include <class_library.h>
37 #include <libeditframe.h>
38 
39 
40 static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
41  bool aErase );
42 
43 
45 {
46  int cmd = BLOCK_IDLE;
47 
48  switch( key )
49  {
50  default:
51  cmd = key & 0xFF;
52  break;
53 
54  case EDA_KEY_C( 0xffffffff ): // -1
55  // Historically, -1 has been used as a key, which can cause bit flag
56  // clashes with unaware code. On debug builds, catch any old code that
57  // might still be doing this. TODO: remove if sure all this old code is gone.
58  wxFAIL_MSG( "negative EDA_KEY value should be converted to GR_KEY_INVALID" );
59  // fall through on release builds
60 
61  case GR_KEY_INVALID:
63  break;
64 
65  case GR_KEY_NONE:
66  cmd = BLOCK_MOVE;
67  break;
68 
69  case GR_KB_SHIFT:
70  cmd = BLOCK_DUPLICATE;
71  break;
72 
73  case GR_KB_ALT:
74  cmd = BLOCK_ROTATE;
75  break;
76 
77  case GR_KB_SHIFTCTRL:
78  cmd = BLOCK_DELETE;
79  break;
80 
81  case GR_KB_CTRL:
82  cmd = BLOCK_MIRROR_Y;
83  break;
84 
85  case MOUSE_MIDDLE:
86  cmd = BLOCK_ZOOM;
87  break;
88  }
89 
90  return cmd;
91 }
92 
93 
95 {
96  int ItemCount = 0;
97  bool nextCmd = false;
98  wxPoint pt;
99 
100  if( GetScreen()->m_BlockLocate.GetCount() )
101  {
105  GetScreen()->m_BlockLocate.SetState( state );
106  GetScreen()->m_BlockLocate.SetCommand( command );
108  SetCrossHairPosition( wxPoint( GetScreen()->m_BlockLocate.GetRight(),
111  }
112 
113  switch( GetScreen()->m_BlockLocate.GetCommand() )
114  {
115  case BLOCK_IDLE:
116  DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
117  break;
118 
119  case BLOCK_DRAG: // Drag
120  case BLOCK_DRAG_ITEM:
121  case BLOCK_MOVE: // Move
122  case BLOCK_DUPLICATE: // Duplicate
123  if( GetCurPart() )
124  ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
125  m_unit, m_convert,
127  if( ItemCount )
128  {
129  nextCmd = true;
130 
131  if( m_canvas->IsMouseCaptured() )
132  {
133  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
135  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
136  }
137 
139  m_canvas->Refresh( true );
140  }
141  break;
142 
143  case BLOCK_PRESELECT_MOVE: // Move with preselection list
144  nextCmd = true;
147  break;
148 
149  case BLOCK_DELETE: // Delete
150  if( GetCurPart() )
151  ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
152  m_unit, m_convert,
154  if( ItemCount )
156 
157  if( GetCurPart() )
158  {
160  OnModify();
161  }
162  break;
163 
164  case BLOCK_COPY: // Save
165  case BLOCK_PASTE:
166  case BLOCK_FLIP:
167  break;
168 
169  case BLOCK_ROTATE:
170  case BLOCK_MIRROR_X:
171  case BLOCK_MIRROR_Y:
172  if( GetCurPart() )
173  ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
174  m_unit, m_convert,
176  if( ItemCount )
178 
179  pt = GetScreen()->m_BlockLocate.Centre();
180  pt = GetNearestGridPosition( pt );
181  pt.y = -pt.y;
182 
183  if( GetCurPart() )
184  {
185  OnModify();
186  int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
187 
188  if( block_cmd == BLOCK_MIRROR_Y)
190  else if( block_cmd == BLOCK_MIRROR_X)
192  else if( block_cmd == BLOCK_ROTATE )
194  }
195 
196  break;
197 
198  case BLOCK_ZOOM: // Window Zoom
199  Window_Zoom( GetScreen()->m_BlockLocate );
200  break;
201 
202  case BLOCK_ABORT:
203  break;
204 
206  break;
207 
208  case BLOCK_DUPLICATE_AND_INCREMENT: // not used in Eeschema
209  case BLOCK_MOVE_EXACT: // not used in Eeschema
210  case BLOCK_CUT: // not used in libedit
211  break;
212  }
213 
214  if( !nextCmd )
215  {
216  if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() )
218 
221  GetScreen()->SetCurItem( NULL );
223  false );
224  m_canvas->Refresh( true );
225  }
226 
227  return nextCmd;
228 }
229 
230 
232 {
233  wxPoint pt;
234 
235  if( !m_canvas->IsMouseCaptured() )
236  {
237  DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
238  }
239 
241 
242  switch( GetScreen()->m_BlockLocate.GetCommand() )
243  {
244  case BLOCK_IDLE:
245  break;
246 
247  case BLOCK_DRAG: // Drag
248  case BLOCK_DRAG_ITEM:
249  case BLOCK_MOVE: // Move
250  case BLOCK_PRESELECT_MOVE: // Move with preselection list
252 
253  if( GetCurPart() )
255 
257  pt.y *= -1;
258 
259  if( GetCurPart() )
260  GetCurPart()->MoveSelectedItems( pt );
261 
262  m_canvas->Refresh( true );
263  break;
264 
265  case BLOCK_DUPLICATE: // Duplicate
267 
268  if( GetCurPart() )
270 
272  pt.y = -pt.y;
273 
274  if( GetCurPart() )
275  GetCurPart()->CopySelectedItems( pt );
276 
277  break;
278 
279  case BLOCK_PASTE: // Paste (recopy the last block saved)
281  break;
282 
283  case BLOCK_ROTATE: // Invert by popup menu, from block move
284  case BLOCK_MIRROR_X: // Invert by popup menu, from block move
285  case BLOCK_MIRROR_Y: // Invert by popup menu, from block move
286  if( GetCurPart() )
288 
289  pt = GetScreen()->m_BlockLocate.Centre();
290  pt = GetNearestGridPosition( pt );
291  pt.y = -pt.y;
292 
293  if( GetCurPart() )
294  {
295  int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
296 
297  if( block_cmd == BLOCK_MIRROR_Y)
299  else if( block_cmd == BLOCK_MIRROR_X)
301  else if( block_cmd == BLOCK_ROTATE )
303  }
304 
305  break;
306 
307  case BLOCK_ZOOM: // Handled by HandleBlockEnd
308  case BLOCK_DELETE:
309  case BLOCK_COPY:
310  case BLOCK_ABORT:
311  default:
312  break;
313  }
314 
315  OnModify();
316 
319  GetScreen()->SetCurItem( NULL );
320  m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
321  m_canvas->Refresh( true );
322 }
323 
324 
325 /*
326  * Traces the outline of the search block structures
327  * The entire block follows the cursor
328  */
329 void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
330  bool aErase )
331 {
333  BASE_SCREEN* screen = aPanel->GetScreen();
334  block = &screen->m_BlockLocate;
335 
336  LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
337  wxASSERT( parent != NULL );
338 
339  LIB_PART* component = parent->GetCurPart();
340 
341  if( component == NULL )
342  return;
343 
344  int unit = parent->GetUnit();
345  int convert = parent->GetConvert();
346 
347  auto opts = PART_DRAW_OPTIONS::Default();
348  opts.draw_mode = g_XorMode;
349  opts.only_selected = true;
350 
351  if( aErase )
352  {
353  block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
354  component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
355  }
356 
357  // Repaint new view
358  block->SetMoveVector( parent->GetCrossHairPosition() - block->GetLastCursorPosition() );
359 
360  GRSetDrawMode( aDC, g_XorMode );
361  block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
362 
363  component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
364 }
GR_DRAWMODE g_XorMode
Definition: gr_basic.cpp:51
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDc, const wxPoint &aOffset, int aMulti, int aConvert, const PART_DRAW_OPTIONS &aOpts)
Draw part.
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
virtual int BlockCommand(EDA_KEY aKey) override
Function BlockCommand returns the block command (BLOCK_MOVE, BLOCK_DUPLICATE...) corresponding to the...
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
static int m_convert
Definition: libeditframe.h:99
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:325
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, GR_DRAWMODE aDrawMode, COLOR4D aColor)
This file is part of the common library.
int GetCurrentCursor() const
Function GetCurrentCursor.
void SetMoveVector(const wxPoint &aMoveVector)
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
void EndMouseCapture(int aId=-1, int aCursorId=-1, const wxString &aTitle=wxEmptyString, bool aCallEndFunc=true)
Function EndMouseCapture ends mouse a capture.
BLOCK_COMMAND_T
void OnModify()
Function OnModify Must be called after a schematic change in order to set the "modify" flag of the cu...
Definition: libeditframe.h:369
BLOCK_STATE_T
void ClearSelectedItems()
Clears all the draw items marked by a block select.
void DrawAndSizingBlockOutlines(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function DrawAndSizingBlockOutlines redraws the outlines of the block which shows the search area for...
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:347
#define GR_KB_ALT
Definition: common.h:65
void CallEndMouseCapture(wxDC *aDC)
Function CallEndMouseCapture calls the end mouse capture callback.
virtual bool HandleBlockEnd(wxDC *DC) override
Function HandleBlockEnd performs a block end command.
#define GR_KEY_INVALID
Definition: common.h:69
void MirrorSelectedItemsH(const wxPoint &aCenter)
Horizontally (X axis) mirror selected draw items about a point.
void ClearItemsList()
Function ClearItemsList clear only the list of EDA_ITEM pointers, it does NOT delete the EDA_ITEM obj...
void MirrorSelectedItemsV(const wxPoint &aCenter)
Vertically (Y axis) mirror selected draw items about a point.
void SetState(BLOCK_STATE_T aState)
COLOR4D GetColor() const
#define GR_KB_SHIFT
Definition: common.h:66
bool IsMouseCaptured() const
void CopySelectedItems(const wxPoint &aOffset)
Make a copy of the selected draw items marked by a block select.
void RotateSelectedItems(const wxPoint &aCenter)
Rotate CCW selected draw items about a point.
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
Class LIB_PART defines a library part object.
uint32_t EDA_KEY
Definition: common.h:52
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:174
int GetBottom() const
wxPoint Centre() const
static PART_DRAW_OPTIONS Default()
#define GR_KB_SHIFTCTRL
Definition: common.h:67
void SetMouseCaptureCallback(MOUSE_CAPTURE_CALLBACK aMouseCaptureCallback)
Definition: solve.cpp:178
void AbortBlockCurrentCommand(EDA_DRAW_PANEL *aPanel, wxDC *aDC)
Function AbortBlockCurrentCommand cancels the current block operation.
#define GR_KEY_NONE
Definition: common.h:70
wxPoint GetLastCursorPosition() const
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
wxPoint GetNearestGridPosition(const wxPoint &aPosition, wxRealPoint *aGridSize=NULL) const
Function GetNearestGridPosition returns the nearest aGridSize location to aPosition.
The component library editor main window.
Definition: libeditframe.h:51
int SelectItems(EDA_RECT &aRect, int aUnit, int aConvert, bool aEditPinByPin)
Checks all draw objects of part to see if they are with block.
static int m_unit
Definition: libeditframe.h:95
BLOCK_STATE_T GetState() const
virtual void HandleBlockPlace(wxDC *DC) override
Function HandleBlockPlace handles the block place command.
int GetToolId() const
Definition: draw_frame.h:438
#define MOUSE_MIDDLE
Definition: common.h:68
void SetCurItem(SCH_ITEM *aItem)
Function SetCurItem sets the currently selected object, m_CurrentItem.
LIB_PART * GetCurPart()
Function GetCurPart returns the current part being edited, or NULL if none selected.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:187
void MoveSelectedItems(const wxPoint &aOffset)
Move the selected draw items marked by a block select.
void Window_Zoom(EDA_RECT &Rect)
Compute the zoom factor and the new draw offset to draw the selected area (Rect) in full window scree...
Definition: zoom.cpp:103
static void DrawMovingBlockOutlines(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
BLOCK_COMMAND_T GetCommand() const
#define EDA_KEY_C
Definition: common.h:60
Definition for part library class.
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...
void DeleteSelectedItems()
Deletes the select draw items marked by a block select.
#define GR_KB_CTRL
Definition: common.h:64
bool m_editPinsPerPartOrConvert
Set to true to not synchronize pins at the same position when editing components with multiple parts ...
Definition: libeditframe.h:77
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:71
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
Definition of class LIB_EDIT_FRAME.
void SetCommand(BLOCK_COMMAND_T aCommand)
wxPoint GetMoveVector() const
void SaveCopyInUndoList(EDA_ITEM *ItemToCopy)
Function SaveCopyInUndoList.