KiCad PCB EDA Suite
common_tools.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) 2014-2016 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
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 
25 #include <bitmaps.h>
26 #include <tool/actions.h>
27 #include <tool/tool_manager.h>
28 #include <draw_frame.h>
29 #include <class_draw_panel_gal.h>
30 #include <view/view.h>
31 #include <view/view_controls.h>
33 #include <base_screen.h>
34 #include <hotkeys.h>
35 #include <tool/common_tools.h>
36 
37 
39 {
40  m_frame = getEditFrame<EDA_DRAW_FRAME>();
41 }
42 
43 
44 // Cursor control
46 {
47  long type = aEvent.Parameter<intptr_t>();
48  bool fastMove = type & ACTIONS::CURSOR_FAST_MOVE;
49  type &= ~ACTIONS::CURSOR_FAST_MOVE;
50  bool mirroredX = getView()->IsMirroredX();
51 
52  VECTOR2D cursor = getViewControls()->GetRawCursorPosition( false );
53  VECTOR2I gridSize = VECTOR2D( m_frame->GetScreen()->GetGridSize() );
54 
55  if( fastMove )
56  gridSize = gridSize * 10;
57 
58  switch( type )
59  {
60  case ACTIONS::CURSOR_UP:
61  cursor -= VECTOR2D( 0, gridSize.y );
62  break;
63 
65  cursor += VECTOR2D( 0, gridSize.y );
66  break;
67 
69  cursor -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
70  break;
71 
73  cursor += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
74  break;
75 
76  case ACTIONS::CURSOR_CLICK: // fall through
78  {
79  TOOL_ACTIONS action = TA_NONE;
80  int modifiers = 0;
81 
82  modifiers |= wxGetKeyState( WXK_SHIFT ) ? MD_SHIFT : 0;
83  modifiers |= wxGetKeyState( WXK_CONTROL ) ? MD_CTRL : 0;
84  modifiers |= wxGetKeyState( WXK_ALT ) ? MD_ALT : 0;
85 
86  if( type == ACTIONS::CURSOR_CLICK )
87  action = TA_MOUSE_CLICK;
88  else if( type == ACTIONS::CURSOR_DBL_CLICK )
89  action = TA_MOUSE_DBLCLICK;
90  else
91  wxFAIL;
92 
93  TOOL_EVENT evt( TC_MOUSE, action, BUT_LEFT | modifiers );
94  evt.SetMousePosition( getViewControls()->GetCursorPosition() );
95  m_toolMgr->ProcessEvent( evt );
96 
97  return 0;
98  }
99  break;
100  }
101 
102  getViewControls()->SetCursorPosition( cursor, true, true );
103 
104  return 0;
105 }
106 
107 
109 {
110  long type = aEvent.Parameter<intptr_t>();
111  KIGFX::VIEW* view = getView();
112  VECTOR2D center = view->GetCenter();
113  VECTOR2I gridSize = VECTOR2D( m_frame->GetScreen()->GetGridSize() ) * 10;
114  bool mirroredX = view->IsMirroredX();
115 
116  switch( type )
117  {
118  case ACTIONS::CURSOR_UP:
119  center -= VECTOR2D( 0, gridSize.y );
120  break;
121 
123  center += VECTOR2D( 0, gridSize.y );
124  break;
125 
127  center -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
128  break;
129 
131  center += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
132  break;
133 
134  default:
135  wxFAIL;
136  break;
137  }
138 
139  view->SetCenter( center );
140 
141  return 0;
142 }
143 
144 
146 {
147  m_frame->HardRedraw();
148  return 0;
149 }
150 
151 
153 {
154  bool direction = aEvent.IsAction( &ACTIONS::zoomIn );
155  return doZoomInOut( direction, true );
156 }
157 
158 
160 {
161  bool direction = aEvent.IsAction( &ACTIONS::zoomInCenter );
162  return doZoomInOut( direction, false );
163 }
164 
165 
166 int COMMON_TOOLS::doZoomInOut( bool aDirection, bool aCenterOnCursor )
167 {
168  double zoom = m_frame->GetGalCanvas()->GetLegacyZoom();
169 
170  // Step must be AT LEAST 1.3
171  if( aDirection )
172  zoom /= 1.3;
173  else
174  zoom *= 1.3;
175 
176  // Now look for the next closest menu step
177  std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
178  int idx;
179 
180  if( aDirection )
181  {
182  for( idx = zoomList.size() - 1; idx >= 0; --idx )
183  {
184  if( zoomList[idx] <= zoom )
185  break;
186  }
187 
188  if( idx < 0 )
189  idx = 0; // if we ran off the end then peg to the end
190  }
191  else
192  {
193  for( idx = 0; idx < (int)zoomList.size(); ++idx )
194  {
195  if( zoomList[idx] >= zoom )
196  break;
197  }
198 
199  if( idx >= (int)zoomList.size() )
200  idx = zoomList.size() - 1; // if we ran off the end then peg to the end
201  }
202 
203  return doZoomToPreset( idx + 1, aCenterOnCursor );
204 }
205 
206 
208 {
210 
211  ctls->CenterOnCursor();
212 
213  return 0;
214 }
215 
216 
218 {
219  KIGFX::VIEW* view = getView();
220  EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
221  EDA_DRAW_FRAME* frame = getEditFrame<EDA_DRAW_FRAME>();
222 
223  BOX2I bBox = frame->GetDocumentExtents();
224  VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
225  VECTOR2D screenSize = view->ToWorld( galCanvas->GetClientSize(), false );
226 
227  if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
228  {
229  bBox = galCanvas->GetDefaultViewBBox();
230  }
231 
232  VECTOR2D vsize = bBox.GetSize();
233  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
234  fabs( vsize.y / screenSize.y ) );
235 
236  // Reserve a 10% margin around component bounding box.
237  double margin_scale_factor = 1.1;
238 
239  // Leave 20% for library editors & viewers
241  || frame->IsType( FRAME_SCH_VIEWER ) || frame->IsType( FRAME_SCH_VIEWER_MODAL )
242  || frame->IsType( FRAME_SCH_LIB_EDITOR ) || frame->IsType( FRAME_PCB_MODULE_EDITOR ) )
243  {
244  margin_scale_factor = 1.2;
245  }
246 
247  view->SetScale( scale / margin_scale_factor );
248  view->SetCenter( bBox.Centre() );
249 
250  // Take scrollbars into account
251  VECTOR2D worldScrollbarSize = view->ToWorld( scrollbarSize, false );
252  view->SetCenter( view->GetCenter() + worldScrollbarSize / 2.0 );
253 
254  return 0;
255 }
256 
257 
259 {
260  EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
261  BOX2I bBox = getModel<EDA_ITEM>()->ViewBBox();
262 
263  if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
264  bBox = galCanvas->GetDefaultViewBBox();
265 
266  getView()->SetCenter( bBox.Centre() );
267 
268  // Take scrollbars into account
269  VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
270  VECTOR2D worldScrollbarSize = getView()->ToWorld( scrollbarSize, false );
271  getView()->SetCenter( getView()->GetCenter() + worldScrollbarSize / 2.0 );
272 
273  return 0;
274 }
275 
276 
278 {
279  unsigned int idx = aEvent.Parameter<intptr_t>();
280  return doZoomToPreset( idx, false );
281 }
282 
283 
284 // Note: idx == 0 is Auto; idx == 1 is first entry in zoomList
285 int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
286 {
287  std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
288  KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
289 
290  if( idx == 0 ) // Zoom Auto
291  {
293  return ZoomFitScreen( dummy );
294  }
295  else
296  {
297  idx--;
298  }
299 
300  double scale = m_frame->GetZoomLevelCoeff() / zoomList[idx];
301 
302  if( aCenterOnCursor )
303  {
304  view->SetScale( scale, getViewControls()->GetCursorPosition() );
305 
306  if( getViewControls()->IsCursorWarpingEnabled() )
308  }
309  else
310  {
311  view->SetScale( scale );
312  }
313 
314  return 0;
315 }
316 
317 
318 // Grid control
319 int COMMON_TOOLS::GridNext( const TOOL_EVENT& aEvent )
320 {
321  BASE_SCREEN * screen = m_frame->GetScreen();
322 
323  int new_grid_cmd = screen->GetGridCmdId();
324 
325  // if the grid id is the not the last, increment it
326  if( screen->GridExists( new_grid_cmd + 1 ) )
327  new_grid_cmd += 1;
328 
329  return doGridPreset( new_grid_cmd - ID_POPUP_GRID_LEVEL_1000 );
330 }
331 
332 
333 int COMMON_TOOLS::GridPrev( const TOOL_EVENT& aEvent )
334 {
335  BASE_SCREEN * screen = m_frame->GetScreen();
336 
337  int new_grid_cmd = screen->GetGridCmdId();
338 
339  // if the grid id is the not the first, increment it
340  if( screen->GridExists( new_grid_cmd - 1 ) )
341  new_grid_cmd -= 1;
342 
343  return doGridPreset( new_grid_cmd - ID_POPUP_GRID_LEVEL_1000 );
344 }
345 
346 
348 {
349  return doGridPreset( aEvent.Parameter<intptr_t>() );
350 }
351 
352 
354 {
355  BASE_SCREEN* screen = m_frame->GetScreen();
356 
357  if( !screen->GridExists( idx + ID_POPUP_GRID_LEVEL_1000 ) )
358  idx = 0;
359 
360  screen->SetGrid( idx + ID_POPUP_GRID_LEVEL_1000 );
361 
362  // Be sure m_LastGridSizeId is up to date.
363  m_frame->SetLastGridSizeId( idx );
364 
365  // Update the combobox (if any)
366  wxUpdateUIEvent dummy;
368 
369  // Update GAL canvas from screen
370  getView()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGridSize() ) );
372 
373  // Put cursor on new grid
375 
376  return 0;
377 }
378 
379 
381 {
383 
387 
388  return 0;
389 }
390 
391 
393 {
394  wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
395 
396  cmd.SetId( ID_GRID_SETTINGS );
397  m_frame->ProcessEvent( cmd );
398 
399  return 0;
400 }
401 
402 
404 {
406  return 0;
407 }
408 
409 
411 {
413  return 0;
414 }
415 
416 
418 {
420  return 0;
421 }
422 
423 
425 {
426  auto& galOpts = m_frame->GetGalDisplayOptions();
427 
428  galOpts.m_forceDisplayCursor = !galOpts.m_forceDisplayCursor;
429  galOpts.NotifyChanged();
430 
431  return 0;
432 }
433 
434 
436 {
438 
439  galOpts.m_fullscreenCursor = !galOpts.m_fullscreenCursor;
440  galOpts.NotifyChanged();
441 
442  return 0;
443 }
444 
445 
447 {
448  // Cursor control
457 
460 
461  // Pan control
462  Go( &COMMON_TOOLS::PanControl, ACTIONS::panUp.MakeEvent() );
466 
467  // Zoom control
469  Go( &COMMON_TOOLS::ZoomInOut, ACTIONS::zoomIn.MakeEvent() );
476 
478 
484 
488 
491 }
492 
493 
int MetricUnits(const TOOL_EVENT &aEvent)
EDA_DRAW_FRAME * m_frame
Pointer to the currently used edit frame.
Definition: common_tools.h:85
const wxRealPoint & GetGridSize() const
Return the grid size of the currently selected grid.
Definition: base_screen.h:410
int ZoomFitScreen(const TOOL_EVENT &aEvent)
static TOOL_ACTION zoomPreset
Definition: actions.h:64
int doGridPreset(int idx)
static TOOL_ACTION zoomInCenter
Definition: actions.h:60
KIGFX::GAL_DISPLAY_OPTIONS & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
Definition: draw_frame.h:949
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:475
const VECTOR2D & GetCenter() const
Function GetCenter() Returns the center point of this VIEW (in world space coordinates)
Definition: view.h:339
VIEW_CONTROLS class definition.
int ToggleCursorStyle(const TOOL_EVENT &aEvent)
TOOL_ACTIONS
Definition: tool_event.h:60
virtual bool IsGridVisible() const
Definition: draw_frame.h:533
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:931
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:216
static TOOL_ACTION cursorRight
Definition: actions.h:74
static TOOL_ACTION zoomFitScreen
Definition: actions.h:63
static TOOL_ACTION cursorRightFast
Definition: actions.h:79
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
int GridPreset(const TOOL_EVENT &aEvent)
static TOOL_ACTION panLeft
Definition: actions.h:87
bool m_forceDisplayCursor
Force cursor display
The base class for create windows for drawing purpose.
Definition: draw_frame.h:82
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:250
void SetMousePosition(const VECTOR2D &aP)
Definition: tool_event.h:405
int doZoomToPreset(int idx, bool aCenterOnCursor)
Note: idx == 0 is Auto; idx == 1 is first entry in zoomList
static TOOL_ACTION imperialUnits
Definition: actions.h:102
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
int ImperialUnits(const TOOL_EVENT &aEvent)
static TOOL_ACTION zoomOutCenter
Definition: actions.h:61
Pcbnew hotkeys.
Auxiliary rendering target (noncached)
Definition: definitions.h:49
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:54
int GridNext(const TOOL_EVENT &aEvent)
int ToggleUnits(const TOOL_EVENT &aEvent)
int ZoomInOutCenter(const TOOL_EVENT &aEvent)
virtual void CenterOnCursor() const =0
Function CenterOnCursor() Sets the viewport center to the current cursor position and warps the curso...
void ChangeUserUnits(EDA_UNITS_T aUnits)
Definition: draw_frame.h:292
static TOOL_ACTION centerContents
Definition: actions.h:66
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:601
static TOOL_ACTION toggleCursor
Definition: actions.h:67
static TOOL_ACTION gridPreset
Definition: actions.h:97
double GetZoomLevelCoeff() const
Return the coefficient to convert internal display scale factor to zoom level.
Definition: draw_frame.h:475
static TOOL_ACTION gridPrev
Definition: actions.h:94
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
static TOOL_ACTION panDown
Definition: actions.h:86
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:596
int GridPrev(const TOOL_EVENT &aEvent)
static TOOL_ACTION toggleGrid
Definition: actions.h:98
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
int doZoomInOut(bool aDirection, bool aCenterOnCursor)
void OnUpdateSelectGrid(wxUpdateUIEvent &aEvent)
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:289
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:378
coord_type GetWidth() const
Definition: box2.h:195
Definition: common.h:158
double GetLegacyZoom() const
Function GetLegacyZoom() Returns current view scale converted to zoom value used by the legacy canvas...
Class TOOL_EVENT.
Definition: tool_event.h:167
static TOOL_ACTION cursorUpFast
Definition: actions.h:76
static TOOL_ACTION cursorDownFast
Definition: actions.h:77
static TOOL_ACTION cursorLeft
Definition: actions.h:73
static TOOL_ACTION panRight
Definition: actions.h:88
int ZoomCenter(const TOOL_EVENT &aEvent)
int ToggleGrid(const TOOL_EVENT &aEvent)
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
int ZoomInOut(const TOOL_EVENT &aEvent)
KIGFX::GAL * GetGAL() const
Function GetGAL() Returns a pointer to the GAL instance used in the panel.
static TOOL_ACTION cursorLeftFast
Definition: actions.h:78
int CursorControl(const TOOL_EVENT &aEvent)
int ToggleCursor(const TOOL_EVENT &aEvent)
void SetGridSize(const VECTOR2D &aGridSize)
Set the grid size.
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:35
virtual void HardRedraw()
Rebuild the GAL and redraws the screen.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
void setTransitions() override
Sets up handlers for various events.
bool IsMirroredX() const
Function IsMirroredX() Returns true if view is flipped across the X axis.
Definition: view.h:230
int CenterContents(const TOOL_EVENT &aEvent)
static TOOL_ACTION metricUnits
Definition: actions.h:103
const int scale
bool GridExists(int aCommandId)
Function GridExists tests for grid command ID (not an index in grid list, but a wxID) exists in grid ...
virtual VECTOR2D GetRawCursorPosition(bool aSnappingEnabled=true) const =0
Returns the current cursor position in world coordinates - ingoring the cursorUp position force mode.
bool IsType(FRAME_T aType) const
Vec Centre() const
Definition: box2.h:77
static TOOL_ACTION zoomCenter
Definition: actions.h:62
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
#define max(a, b)
Definition: auxiliary.h:86
static TOOL_ACTION cursorUp
Cursor control with keyboard.
Definition: actions.h:71
static TOOL_ACTION zoomRedraw
Definition: actions.h:57
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
static TOOL_ACTION cursorDblClick
Definition: actions.h:82
int ZoomPreset(const TOOL_EVENT &aEvent)
void SetLastGridSizeId(int aId)
Definition: draw_frame.h:313
coord_type GetHeight() const
Definition: box2.h:196
wxPoint RefPos(bool useMouse) const
Return the reference position, coming from either the mouse position or the cursor position.
static TOOL_ACTION gridNext
Definition: actions.h:93
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void SetGridVisibility(bool aVisibility)
Sets the visibility setting of the grid.
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
static TOOL_ACTION gridProperties
Definition: actions.h:99
Class ACTIONS.
Definition: actions.h:41
static TOOL_ACTION panUp
Definition: actions.h:85
static TOOL_ACTION zoomIn
Definition: actions.h:58
static TOOL_ACTION zoomOut
Definition: actions.h:59
virtual void SetGridVisibility(bool aVisible)
It may be overloaded by derived classes.
Definition: draw_frame.h:542
const Vec & GetSize() const
Definition: box2.h:187
static TOOL_ACTION toggleCursorStyle
Definition: actions.h:68
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
Class VIEW.
Definition: view.h:61
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Set the screen cross hair position to aPosition in logical (drawing) units.
int SetGrid(const wxRealPoint &size)
set the current grid size m_Grid.
double GetScale() const
Function GetScale()
Definition: view.h:268
BASE_SCREEN class implementation.
static TOOL_ACTION cursorDown
Definition: actions.h:72
int PanControl(const TOOL_EVENT &aEvent)
int GetGridCmdId() const
Return the command ID of the currently selected grid.
Definition: base_screen.h:403
int ZoomRedraw(const TOOL_EVENT &aEvent)
virtual BOX2I GetDefaultViewBBox() const
Returns the bounding box of the view that should be used if model is not valid For example,...
static TOOL_ACTION toggleUnits
Definition: actions.h:104
virtual BASE_SCREEN * GetScreen() const
Return a pointer to a BASE_SCREEN or one of its derivatives.
Definition: draw_frame.h:408
bool m_fullscreenCursor
Fullscreen crosshair or small cross
bool ProcessEvent(wxEvent &aEvent) override
Override the default process event handler to implement the auto save feature.
int GridProperties(const TOOL_EVENT &aEvent)
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false)=0
Moves cursor to the requested position expressed in world coordinates.
static TOOL_ACTION cursorClick
Definition: actions.h:81
std::vector< double > m_ZoomList
standard zoom (i.e. scale) coefficients.
Definition: base_screen.h:219
virtual const BOX2I GetDocumentExtents() const