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