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 <tool/actions.h>
26 #include <tool/tool_manager.h>
27 #include <draw_frame.h>
28 #include <class_draw_panel_gal.h>
29 #include <view/view.h>
30 #include <view/view_controls.h>
32 #include <base_screen.h>
33 #include <hotkeys.h>
34 
35 #include <tool/common_tools.h>
36 
37 
38 static TOOL_ACTION ACT_toggleCursor( "common.Control.toggleCursor",
40  _( "Toggle Always Show Cursor" ),
41  _( "Toggle display of the cursor, even when not in an interactive tool" ) );
42 
43 
45  TOOL_INTERACTIVE( "common.Control" ), m_frame( NULL )
46 {
47 }
48 
49 
51 {
52 }
53 
54 
56 {
57  m_frame = getEditFrame<EDA_DRAW_FRAME>();
58 }
59 
60 
61 // Cursor control
63 {
64  long type = aEvent.Parameter<intptr_t>();
65  bool fastMove = type & ACTIONS::CURSOR_FAST_MOVE;
66  type &= ~ACTIONS::CURSOR_FAST_MOVE;
67  bool mirroredX = getView()->IsMirroredX();
68 
69  VECTOR2D cursor = getViewControls()->GetRawCursorPosition( false );
70  VECTOR2I gridSize = VECTOR2D( m_frame->GetScreen()->GetGridSize() );
71 
72  if( fastMove )
73  gridSize = gridSize * 10;
74 
75  switch( type )
76  {
77  case ACTIONS::CURSOR_UP:
78  cursor -= VECTOR2D( 0, gridSize.y );
79  break;
80 
82  cursor += VECTOR2D( 0, gridSize.y );
83  break;
84 
86  cursor -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
87  break;
88 
90  cursor += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
91  break;
92 
93  case ACTIONS::CURSOR_CLICK: // fall through
95  {
96  TOOL_ACTIONS action = TA_NONE;
97  int modifiers = 0;
98 
99  modifiers |= wxGetKeyState( WXK_SHIFT ) ? MD_SHIFT : 0;
100  modifiers |= wxGetKeyState( WXK_CONTROL ) ? MD_CTRL : 0;
101  modifiers |= wxGetKeyState( WXK_ALT ) ? MD_ALT : 0;
102 
103  if( type == ACTIONS::CURSOR_CLICK )
104  action = TA_MOUSE_CLICK;
105  else if( type == ACTIONS::CURSOR_DBL_CLICK )
106  action = TA_MOUSE_DBLCLICK;
107  else
108  wxFAIL;
109 
110  TOOL_EVENT evt( TC_MOUSE, action, BUT_LEFT | modifiers );
111  evt.SetMousePosition( getViewControls()->GetCursorPosition() );
112  m_toolMgr->ProcessEvent( evt );
113 
114  return 0;
115  }
116  break;
117  }
118 
119  getViewControls()->SetCursorPosition( cursor, true, true );
120 
121  return 0;
122 }
123 
124 
126 {
127  long type = aEvent.Parameter<intptr_t>();
128  KIGFX::VIEW* view = getView();
129  VECTOR2D center = view->GetCenter();
130  VECTOR2I gridSize = VECTOR2D( m_frame->GetScreen()->GetGridSize() ) * 10;
131  bool mirroredX = view->IsMirroredX();
132 
133  switch( type )
134  {
135  case ACTIONS::CURSOR_UP:
136  center -= VECTOR2D( 0, gridSize.y );
137  break;
138 
140  center += VECTOR2D( 0, gridSize.y );
141  break;
142 
144  center -= VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
145  break;
146 
148  center += VECTOR2D( mirroredX ? -gridSize.x : gridSize.x, 0 );
149  break;
150 
151  default:
152  wxFAIL;
153  break;
154  }
155 
156  view->SetCenter( center );
157 
158  return 0;
159 }
160 
161 
163 {
164  bool direction = aEvent.IsAction( &ACTIONS::zoomIn );
165  return doZoomInOut( direction, true );
166 }
167 
168 
170 {
171  bool direction = aEvent.IsAction( &ACTIONS::zoomInCenter );
172  return doZoomInOut( direction, false );
173 }
174 
175 
176 int COMMON_TOOLS::doZoomInOut( bool aDirection, bool aCenterOnCursor )
177 {
178  double zoom = m_frame->GetGalCanvas()->GetLegacyZoom();
179 
180  // Step must be AT LEAST 1.3
181  if( aDirection )
182  zoom /= 1.3;
183  else
184  zoom *= 1.3;
185 
186  // Now look for the next closest menu step
187  std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
188  int idx;
189 
190  if( aDirection )
191  {
192  for( idx = zoomList.size() - 1; idx >= 0; --idx )
193  {
194  if( zoomList[idx] <= zoom )
195  break;
196  }
197 
198  if( idx < 0 )
199  idx = 0; // if we ran off the end then peg to the end
200  }
201  else
202  {
203  for( idx = 0; idx < (int)zoomList.size(); ++idx )
204  {
205  if( zoomList[idx] >= zoom )
206  break;
207  }
208 
209  if( idx >= (int)zoomList.size() )
210  idx = zoomList.size() - 1; // if we ran off the end then peg to the end
211  }
212 
213  return doZoomToPreset( idx + 1, aCenterOnCursor );
214 }
215 
216 
218 {
220 
221  ctls->CenterOnCursor();
222 
223  return 0;
224 }
225 
226 
228 {
229  KIGFX::VIEW* view = getView();
230  EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
231  EDA_ITEM* model = getModel<EDA_ITEM>();
232  EDA_BASE_FRAME* frame = getEditFrame<EDA_BASE_FRAME>();
233 
234  BOX2I bBox = model->ViewBBox();
235  VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
236  VECTOR2D screenSize = view->ToWorld( galCanvas->GetClientSize(), false );
237 
238  if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
239  {
240  bBox = galCanvas->GetDefaultViewBBox();
241  }
242 
243  VECTOR2D vsize = bBox.GetSize();
244  double scale = view->GetScale() / std::max( fabs( vsize.x / screenSize.x ),
245  fabs( vsize.y / screenSize.y ) );
246 
247  // Reserve a 10% margin around component bounding box.
248  double margin_scale_factor = 1.1;
249 
250  // Leave 20% for library editors & viewers
252  || frame->IsType( FRAME_SCH_VIEWER ) || frame->IsType( FRAME_SCH_VIEWER_MODAL )
253  || frame->IsType( FRAME_SCH_LIB_EDITOR ) || frame->IsType( FRAME_PCB_MODULE_EDITOR ) )
254  {
255  margin_scale_factor = 1.2;
256  }
257 
258  view->SetScale( scale / margin_scale_factor );
259  view->SetCenter( bBox.Centre() );
260 
261  // Take scrollbars into account
262  VECTOR2D worldScrollbarSize = view->ToWorld( scrollbarSize, false );
263  view->SetCenter( view->GetCenter() + worldScrollbarSize / 2.0 );
264 
265  return 0;
266 }
267 
268 
270 {
271  EDA_DRAW_PANEL_GAL* galCanvas = m_frame->GetGalCanvas();
272  BOX2I bBox = getModel<EDA_ITEM>()->ViewBBox();
273 
274  if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 )
275  bBox = galCanvas->GetDefaultViewBBox();
276 
277  getView()->SetCenter( bBox.Centre() );
278 
279  // Take scrollbars into account
280  VECTOR2D scrollbarSize = VECTOR2D( galCanvas->GetSize() - galCanvas->GetClientSize() );
281  VECTOR2D worldScrollbarSize = getView()->ToWorld( scrollbarSize, false );
282  getView()->SetCenter( getView()->GetCenter() + worldScrollbarSize / 2.0 );
283 
284  return 0;
285 }
286 
287 
289 {
290  unsigned int idx = aEvent.Parameter<intptr_t>();
291  return doZoomToPreset( idx, false );
292 }
293 
294 
295 // Note: idx == 0 is Auto; idx == 1 is first entry in zoomList
296 int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
297 {
298  std::vector<double>& zoomList = m_frame->GetScreen()->m_ZoomList;
299  KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
300 
301  if( idx == 0 ) // Zoom Auto
302  {
304  return ZoomFitScreen( dummy );
305  }
306  else
307  {
308  idx--;
309  }
310 
311  double scale = m_frame->GetZoomLevelCoeff() / zoomList[idx];
312 
313  if( aCenterOnCursor )
314  {
315  view->SetScale( scale, getViewControls()->GetCursorPosition() );
316 
317  if( getViewControls()->IsCursorWarpingEnabled() )
319  }
320  else
321  {
322  view->SetScale( scale );
323  }
324 
325  return 0;
326 }
327 
328 
329 // Grid control
330 int COMMON_TOOLS::GridNext( const TOOL_EVENT& aEvent )
331 {
332  m_frame->SetNextGrid();
333  updateGrid();
334 
335  return 0;
336 }
337 
338 
339 int COMMON_TOOLS::GridPrev( const TOOL_EVENT& aEvent )
340 {
341  m_frame->SetPrevGrid();
342  updateGrid();
343 
344  return 0;
345 }
346 
347 
349 {
350  long idx = aEvent.Parameter<intptr_t>();
351 
352  m_frame->SetPresetGrid( idx );
353  updateGrid();
354 
355  return 0;
356 }
357 
358 
360 {
361  auto& galOpts = m_frame->GetGalDisplayOptions();
362 
363  galOpts.m_forceDisplayCursor = !galOpts.m_forceDisplayCursor;
364  galOpts.NotifyChanged();
365 
366  return 0;
367 }
368 
369 
371 {
372  // Cursor control
381 
384 
385  // Pan control
386  Go( &COMMON_TOOLS::PanControl, ACTIONS::panUp.MakeEvent() );
390 
391  // Zoom control
392  Go( &COMMON_TOOLS::ZoomInOut, ACTIONS::zoomIn.MakeEvent() );
399 
401 
405 
407 }
408 
409 
411 {
412  BASE_SCREEN* screen = m_frame->GetScreen();
413  getView()->GetGAL()->SetGridSize( VECTOR2D( screen->GetGridSize() ) );
415 }
EDA_DRAW_FRAME * m_frame
Pointer to the currently used edit frame.
Definition: common_tools.h:72
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:57
static TOOL_ACTION zoomInCenter
Definition: actions.h:53
KIGFX::GAL_DISPLAY_OPTIONS & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
Definition: draw_frame.h:953
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.
TOOL_ACTIONS
Definition: tool_event.h:61
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:935
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION cursorRight
Definition: actions.h:65
static TOOL_ACTION zoomFitScreen
Definition: actions.h:56
static TOOL_ACTION cursorRightFast
Definition: actions.h:70
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key.
Definition: tool_action.h:174
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)
void updateGrid()
Applies the legacy canvas grid settings for GAL.
static TOOL_ACTION panLeft
Definition: actions.h:78
bool m_forceDisplayCursor
Force cursor display
virtual void SetPrevGrid()
Change the grid size settings to the previous one available.
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:250
void SetMousePosition(const VECTOR2D &aP)
Definition: tool_event.h:414
int doZoomToPreset(int idx, bool aCenterOnCursor)
Note: idx == 0 is Auto; idx == 1 is first entry in zoomList
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
static TOOL_ACTION zoomOutCenter
Definition: actions.h:54
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 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...
static TOOL_ACTION centerContents
Definition: actions.h:59
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:601
static TOOL_ACTION gridPreset
Definition: actions.h:88
double GetZoomLevelCoeff() const
Return the coefficient to convert internal display scale factor to zoom level.
Definition: draw_frame.h:471
static TOOL_ACTION gridPrev
Definition: actions.h:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:586
static TOOL_ACTION panDown
Definition: actions.h:77
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:596
int GridPrev(const TOOL_EVENT &aEvent)
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
int doZoomInOut(bool aDirection, bool aCenterOnCursor)
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:387
coord_type GetWidth() const
Definition: box2.h:195
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:168
static TOOL_ACTION cursorUpFast
Definition: actions.h:67
static TOOL_ACTION cursorDownFast
Definition: actions.h:68
static TOOL_ACTION cursorLeft
Definition: actions.h:64
static TOOL_ACTION panRight
Definition: actions.h:79
int ZoomCenter(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)
static TOOL_ACTION cursorLeftFast
Definition: actions.h:69
void SetPresetGrid(int aIndex)
Change the grid size to one of the preset values.
All active tools
Definition: tool_event.h:144
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
void setTransitions() override
Sets up handlers for various events.
virtual void SetNextGrid()
Change the grid size settings to the next one available.
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)
const int scale
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:55
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:62
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
static TOOL_ACTION cursorDblClick
Definition: actions.h:73
int ZoomPreset(const TOOL_EVENT &aEvent)
Class EDA_BASE_FRAME is the base frame for deriving all KiCad main window classes.
Class TOOL_ACTION.
Definition: tool_action.h:46
TOOL_EVENT MakeEvent() const
Function HasHotKey() Checks if the action has a hot key assigned.
Definition: tool_action.h:104
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
coord_type GetHeight() const
Definition: box2.h:196
static TOOL_ACTION gridNext
Definition: actions.h:84
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
Class ACTIONS.
Definition: actions.h:41
static TOOL_ACTION panUp
Definition: actions.h:76
static TOOL_ACTION zoomIn
Definition: actions.h:51
static TOOL_ACTION zoomOut
Definition: actions.h:52
const Vec & GetSize() const
Definition: box2.h:187
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:41
Class VIEW.
Definition: view.h:61
double GetScale() const
Function GetScale()
Definition: view.h:268
BASE_SCREEN class implementation.
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
static TOOL_ACTION cursorDown
Definition: actions.h:63
int PanControl(const TOOL_EVENT &aEvent)
static TOOL_ACTION ACT_toggleCursor("common.Control.toggleCursor", AS_GLOBAL, TOOL_ACTION::LegacyHotKey(HK_TOGGLE_CURSOR), _("Toggle Always Show Cursor"), _("Toggle display of the cursor, even when not in an interactive tool"))
virtual BOX2I GetDefaultViewBBox() const
Returns the bounding box of the view that should be used if model is not valid For example,...
virtual BASE_SCREEN * GetScreen() const
Return a pointer to a BASE_SCREEN or one of its derivatives.
Definition: draw_frame.h:404
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:72
std::vector< double > m_ZoomList
standard zoom (i.e. scale) coefficients.
Definition: base_screen.h:219