Eclipse SUMO - Simulation of Urban MObility
GUIDanielPerspectiveChanger.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // A class that allows to steer the visual output in dependence to
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <fxkeys.h>
27 #include <utils/geom/Boundary.h>
28 #include <utils/geom/Position.h>
29 #include <utils/geom/GeomHelper.h>
31 #include "GUIPerspectiveChanger.h"
33 
34 
35 // ===========================================================================
36 // method definitions
37 // ===========================================================================
39  GUISUMOAbstractView& callBack, const Boundary& viewPort) :
40  GUIPerspectiveChanger(callBack, viewPort),
41  myOrigWidth(viewPort.getWidth()),
42  myOrigHeight(viewPort.getHeight()),
43  myRotation(0),
44  myMouseButtonState(MOUSEBTN_NONE),
45  myMoveOnClick(false),
46  myZoomBase(viewPort.getCenter()),
47  myDragDelay(0) {
48 }
49 
50 
52 
53 
54 void
55 GUIDanielPerspectiveChanger::move(int xdiff, int ydiff) {
56  myViewPort.moveby(myCallback.p2m(xdiff), -myCallback.p2m(ydiff));
57  myCallback.update();
58 }
59 
60 
61 void
63  if (myCallback.getApp()->reg().readIntEntry("gui", "zoomAtCenter", 1)) {
65  }
66  if (factor > 0) {
68  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmin()) / factor,
69  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymin()) / factor,
70  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmax()) / factor,
71  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymax()) / factor);
72  myCallback.update();
73  }
74 }
75 
76 
77 void
79  /*
80  if (myCallback.allowRotation()) {
81  myRotation += (double) diff / (double) 10.0;
82  myCallback.update();
83  }
84  */
85 }
86 
87 
88 double
90  return myRotation;
91 }
92 
93 
94 double
96  return myViewPort.getCenter().x();
97 }
98 
99 
100 double
102  return myViewPort.getCenter().y();
103 }
104 
105 
106 double
108  return myOrigWidth / myViewPort.getWidth() * 100;
109 }
110 
111 
112 double
114  return myViewPort.getWidth();
115 }
116 
117 
118 double
120  return myOrigWidth / (zoom / 100);
121 }
122 
123 
124 double
126  return (myOrigWidth / zPos) * 100;
127 }
128 
129 
130 void
132  bool applyZoom) {
133  if (applyZoom) {
134  myViewPort = Boundary();
135  myViewPort.add(pos);
136  myViewPort.grow(radius);
137  } else {
138  myViewPort.moveby(pos.x() - getXPos(), pos.y() - getYPos());
139  }
140 }
141 
142 
143 void
146  FXEvent* e = (FXEvent*) data;
147  myMouseXPosition = e->win_x;
148  myMouseYPosition = e->win_y;
149  myMoveOnClick = false;
150  myMouseDownTime = FXThread::time();
151 }
152 
153 
154 bool
157  FXEvent* e = (FXEvent*) data;
158  myMouseXPosition = e->win_x;
159  myMouseYPosition = e->win_y;
160  return myMoveOnClick;
161 }
162 
163 
164 void
167  FXEvent* e = (FXEvent*) data;
168  myMouseXPosition = e->win_x;
169  myMouseYPosition = e->win_y;
170  myMoveOnClick = false;
171  myMouseDownTime = FXThread::time();
173 }
174 
175 
176 bool
179  if (data != nullptr) {
180  FXEvent* e = (FXEvent*) data;
181  myMouseXPosition = e->win_x;
182  myMouseYPosition = e->win_y;
183  }
184  return myMoveOnClick;
185 }
186 
187 
188 void
190  FXEvent* e = (FXEvent*) data;
191  // catch empty ghost events after scroll (seem to occur only on Ubuntu)
192  if (e->code == 0) {
193  return;
194  }
195  // zoom scale relative delta and its inverse; is optimized (all literals)
196  const double zScale_rDelta_norm = 0.1;
197  const double zScale_rDelta_inv = -zScale_rDelta_norm / (1. + zScale_rDelta_norm);
198  double zScale_rDelta = zScale_rDelta_norm ;
199  if (e->code < 0) {
200  // for inverse zooming direction
201  zScale_rDelta = zScale_rDelta_inv;
202  }
203  // keyboard modifier: slow, fast mouse-zoom
204  if ((e->state & CONTROLMASK) != 0) {
205  zScale_rDelta /= 4;
206  } else if ((e->state & SHIFTMASK) != 0) {
207  zScale_rDelta *= 4;
208  }
210  zoom(1.0 + zScale_rDelta);
212 }
213 
214 
215 void
217  FXEvent* e = (FXEvent*) data;
218  myCallback.setWindowCursorPosition(e->win_x, e->win_y);
219  const int xdiff = myMouseXPosition - e->win_x;
220  const int ydiff = myMouseYPosition - e->win_y;
221  const bool moved = xdiff != 0 || ydiff != 0;
222  const bool pastDelay = !gSchemeStorage.getDefault().gaming && FXThread::time() > (myMouseDownTime + myDragDelay);
223  switch (myMouseButtonState) {
224  case MOUSEBTN_LEFT:
225  if (pastDelay) {
226  if (myRotation != 0) {
227  Position diffRot = Position(xdiff, ydiff).rotateAround2D(
228  DEG2RAD(myRotation), Position(0, 0));
229  move((int)diffRot.x(), (int)diffRot.y());
230  } else {
231  move(xdiff, ydiff);
232  }
233  if (moved) {
234  myMoveOnClick = true;
235  }
236  }
237  break;
238  case MOUSEBTN_RIGHT:
239  if (pastDelay) {
240  zoom(1 + 10.0 * ydiff / myCallback.getWidth());
241  rotate(xdiff);
242  if (moved) {
243  myMoveOnClick = true;
244  }
245  }
246  break;
247  default:
248  if (moved) {
250  }
251  break;
252  }
253  myMouseXPosition = e->win_x;
254  myMouseYPosition = e->win_y;
255 }
256 
257 
258 void
260  double xPos, double yPos) {
261  const double zoomFactor = zoom / 50; // /100 to normalize, *2 because growth is added on both sides
262  myViewPort = Boundary();
263  myViewPort.add(Position(xPos, yPos));
264  myViewPort.growHeight(myOrigHeight / zoomFactor);
265  myViewPort.growWidth(myOrigWidth / zoomFactor);
266  myCallback.update();
267 }
268 
269 
270 void
271 GUIDanielPerspectiveChanger::setViewportFrom(double xPos, double yPos, double zPos) {
272  setViewport(zPos2Zoom(zPos), xPos, yPos);
273 }
274 
275 
276 void
278  myRotation = rotation;
279 }
280 
281 void
284  myViewPort.xmin() - myCallback.p2m(change),
285  myViewPort.ymin(),
286  myViewPort.xmax(),
287  myViewPort.ymax());
288 }
289 
290 
291 long
293  // ignore key events in gaming mode
295  return 0;
296  }
297  FXEvent* e = (FXEvent*) data;
298  double zoomDiff = 0.1;
299  double moveX = 0;
300  double moveY = 0;
301  double moveFactor = 1;
302  bool pageVertical = true;
303  if (e->state & CONTROLMASK) {
304  zoomDiff /= 2;
305  moveFactor /= 10;
306  } else if (e->state & SHIFTMASK) {
307  pageVertical = false;
308  zoomDiff *= 2;
309  }
310  switch (e->code) {
311  case FX::KEY_Left:
312  moveX = -1;
313  moveFactor /= 10;
314  break;
315  case FX::KEY_Right:
316  moveX = 1;
317  moveFactor /= 10;
318  break;
319  case FX::KEY_Up:
320  moveY = -1;
321  moveFactor /= 10;
322  break;
323  case FX::KEY_Down:
324  moveY = 1;
325  moveFactor /= 10;
326  break;
327  case FX::KEY_Page_Up:
328  if (pageVertical) {
329  moveY = -1;
330  } else {
331  moveX = -1;
332  }
333  break;
334  case FX::KEY_Page_Down:
335  if (pageVertical) {
336  moveY = 1;
337  } else {
338  moveX = 1;
339  }
340  break;
341  case FX::KEY_plus:
342  case FX::KEY_KP_Add:
344  zoom(1.0 + zoomDiff);
346  return 1;
347  case FX::KEY_minus:
348  case FX::KEY_KP_Subtract:
349  zoomDiff = -zoomDiff;
351  zoom(1.0 + zoomDiff);
353  return 1;
354  case FX::KEY_Home:
355  case FX::KEY_KP_Home:
357  myCallback.update();
358  return 1;
359  default:
360  return 0;
361  }
362  myViewPort.moveby(moveX * moveFactor * myViewPort.getWidth(),
363  -moveY * moveFactor * myViewPort.getHeight());
364  myCallback.update();
365  return 1;
366 }
367 
368 
369 /****************************************************************************/
GUIPerspectiveChanger
Definition: GUIPerspectiveChanger.h:53
GUICompleteSchemeStorage.h
Boundary.h
GUIDanielPerspectiveChanger::onLeftBtnPress
void onLeftBtnPress(void *data)
mouse functions
Definition: GUIDanielPerspectiveChanger.cpp:144
GUIPerspectiveChanger::myViewPort
Boundary myViewPort
the intended viewport
Definition: GUIPerspectiveChanger.h:160
Boundary::moveby
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:369
GUIDanielPerspectiveChanger::~GUIDanielPerspectiveChanger
~GUIDanielPerspectiveChanger()
Destructor.
Definition: GUIDanielPerspectiveChanger.cpp:51
GUICompleteSchemeStorage::getDefault
GUIVisualizationSettings & getDefault()
Returns the default scheme.
Definition: GUICompleteSchemeStorage.cpp:69
Position::rotateAround2D
Position rotateAround2D(double rad, const Position &origin)
rotate this position by rad around origin and return the result
Definition: Position.cpp:42
GUIDanielPerspectiveChanger::zPos2Zoom
virtual double zPos2Zoom(double zPos) const
Returns the zoom level that is achieved at a given camera height.
Definition: GUIDanielPerspectiveChanger.cpp:125
GUISUMOAbstractView
Definition: GUISUMOAbstractView.h:73
Boundary::ymin
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:131
GUIDanielPerspectiveChanger::myMouseDownTime
FXlong myMouseDownTime
Definition: GUIDanielPerspectiveChanger.h:149
GUIDanielPerspectiveChanger::getRotation
virtual double getRotation() const
Returns the rotation of the canvas stored in this changer.
Definition: GUIDanielPerspectiveChanger.cpp:89
GUIDanielPerspectiveChanger.h
GUIDanielPerspectiveChanger::myDragDelay
FXTime myDragDelay
avoid flicker
Definition: GUIDanielPerspectiveChanger.h:148
GUIDanielPerspectiveChanger::onRightBtnRelease
bool onRightBtnRelease(void *data)
called when user releases right button
Definition: GUIDanielPerspectiveChanger.cpp:177
Boundary::xmax
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:125
GUIDanielPerspectiveChanger::onLeftBtnRelease
bool onLeftBtnRelease(void *data)
called when user releases left button
Definition: GUIDanielPerspectiveChanger.cpp:155
Boundary::getHeight
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
GUIDanielPerspectiveChanger::getYPos
virtual double getYPos() const
Returns the y-offset of the field to show stored in this changer.
Definition: GUIDanielPerspectiveChanger.cpp:101
GUIDanielPerspectiveChanger::myOrigHeight
double myOrigHeight
Definition: GUIDanielPerspectiveChanger.h:133
GUISUMOAbstractView::setWindowCursorPosition
void setWindowCursorPosition(FXint x, FXint y)
Returns the gl-id of the object under the given coordinates.
Definition: GUISUMOAbstractView.cpp:814
GUIDanielPerspectiveChanger::zoom
void zoom(double factor)
Performs the zooming of the view.
Definition: GUIDanielPerspectiveChanger.cpp:62
GUISUMOAbstractView::updateToolTip
void updateToolTip()
A method that updates the tooltip.
Definition: GUISUMOAbstractView.cpp:179
GUIPerspectiveChanger::MOUSEBTN_LEFT
Definition: GUIPerspectiveChanger.h:58
GUIDanielPerspectiveChanger::myZoomBase
Position myZoomBase
the network location on which to zoom using right click+drag
Definition: GUIDanielPerspectiveChanger.h:145
GUIDanielPerspectiveChanger::onRightBtnPress
void onRightBtnPress(void *data)
called when user press right button
Definition: GUIDanielPerspectiveChanger.cpp:165
GUIDanielPerspectiveChanger::setViewportFrom
void setViewportFrom(double xPos, double yPos, double zPos)
Alternative method for setting the viewport.
Definition: GUIDanielPerspectiveChanger.cpp:271
Boundary::xmin
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
GUIDanielPerspectiveChanger::myMouseButtonState
int myMouseButtonState
the current mouse state
Definition: GUIDanielPerspectiveChanger.h:139
GUIPerspectiveChanger.h
Boundary
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
Boundary::getWidth
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
gSchemeStorage
GUICompleteSchemeStorage gSchemeStorage
Definition: GUICompleteSchemeStorage.cpp:39
Position::x
double x() const
Returns the x-position.
Definition: Position.h:57
Boundary::add
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
GUIDanielPerspectiveChanger::move
void move(int xdiff, int ydiff)
Definition: GUIDanielPerspectiveChanger.cpp:55
GUIDanielPerspectiveChanger::setRotation
void setRotation(double rotation)
Sets the rotation.
Definition: GUIDanielPerspectiveChanger.cpp:277
GUIDanielPerspectiveChanger::rotate
void rotate(int diff)
Performs the rotation of the view.
Definition: GUIDanielPerspectiveChanger.cpp:78
GUISUMOAbstractView::getPositionInformation
Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Definition: GUISUMOAbstractView.cpp:188
Boundary::growWidth
void growWidth(double by)
Increases the width of the boundary (x-axis)
Definition: Boundary.cpp:310
DEG2RAD
#define DEG2RAD(x)
Definition: GeomHelper.h:38
Position.h
GUIPerspectiveChanger::myMouseYPosition
FXint myMouseYPosition
Definition: GUIPerspectiveChanger.h:157
Position::y
double y() const
Returns the y-position.
Definition: Position.h:62
Boundary::getCenter
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:113
GUISUMOAbstractView::p2m
double p2m(double pixel) const
pixels-to-meters conversion method
Definition: GUISUMOAbstractView.cpp:757
GUIDanielPerspectiveChanger::zoom2ZPos
virtual double zoom2ZPos(double zoom) const
Returns the camera height at which the given zoom level is reached.
Definition: GUIDanielPerspectiveChanger.cpp:119
GUIPerspectiveChanger::myMouseXPosition
FXint myMouseXPosition
the current mouse position
Definition: GUIPerspectiveChanger.h:157
GUIPerspectiveChanger::MOUSEBTN_RIGHT
Definition: GUIPerspectiveChanger.h:59
GUIDanielPerspectiveChanger::getZoom
virtual double getZoom() const
Returns the zoom factor computed stored in this changer.
Definition: GUIDanielPerspectiveChanger.cpp:107
GUIDanielPerspectiveChanger::changeCanvasSizeLeft
void changeCanvasSizeLeft(int change)
Definition: GUIDanielPerspectiveChanger.cpp:282
config.h
GeomHelper.h
Boundary::grow
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
GUIDanielPerspectiveChanger::getZPos
virtual double getZPos() const
Returns the camera height corresponding to the current zoom factor.
Definition: GUIDanielPerspectiveChanger.cpp:113
GUISUMOAbstractView::recenterView
virtual void recenterView()
recenters the view
Definition: GUISUMOAbstractView.cpp:763
GUIDanielPerspectiveChanger::myRotation
double myRotation
the current rotation
Definition: GUIDanielPerspectiveChanger.h:136
GUIDanielPerspectiveChanger::setViewport
void setViewport(double zoom, double xPos, double yPos)
Sets the viewport.
Definition: GUIDanielPerspectiveChanger.cpp:259
GUIPerspectiveChanger::myCallback
GUISUMOAbstractView & myCallback
The parent window (canvas to scale)
Definition: GUIPerspectiveChanger.h:154
GUIDanielPerspectiveChanger::onMouseMove
void onMouseMove(void *data)
called when user moves mouse
Definition: GUIDanielPerspectiveChanger.cpp:216
GUIVisualizationSettings::gaming
bool gaming
whether the application is in gaming mode or not
Definition: GUIVisualizationSettings.h:626
GUIDanielPerspectiveChanger::onKeyPress
long onKeyPress(void *data)
called when user press a key
Definition: GUIDanielPerspectiveChanger.cpp:292
GUIDanielPerspectiveChanger::myOrigWidth
double myOrigWidth
the original viewport dimensions in m which serve as the reference point for 100% zoom
Definition: GUIDanielPerspectiveChanger.h:133
GUIDanielPerspectiveChanger::onMouseWheel
void onMouseWheel(void *data)
called when user changes mouse wheel
Definition: GUIDanielPerspectiveChanger.cpp:189
GUIDanielPerspectiveChanger::centerTo
void centerTo(const Position &pos, double radius, bool applyZoom=true)
Centers the view to the given position, setting it to a size that covers the radius.
Definition: GUIDanielPerspectiveChanger.cpp:131
GUIDanielPerspectiveChanger::getXPos
virtual double getXPos() const
Returns the x-offset of the field to show stored in this changer.
Definition: GUIDanielPerspectiveChanger.cpp:95
GUIDanielPerspectiveChanger::myMoveOnClick
bool myMoveOnClick
Information whether the user has moved the cursor while pressing a mouse button.
Definition: GUIDanielPerspectiveChanger.h:142
Boundary::growHeight
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:317
GUIDanielPerspectiveChanger::GUIDanielPerspectiveChanger
GUIDanielPerspectiveChanger(GUISUMOAbstractView &callBack, const Boundary &viewPort)
Definition: GUIDanielPerspectiveChanger.cpp:38
Boundary::ymax
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:137