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-2018 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 /****************************************************************************/
double myRotation
the current rotation
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:131
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:125
GUICompleteSchemeStorage gSchemeStorage
virtual double getXPos() const
Returns the x-offset of the field to show stored in this changer.
virtual double getZoom() const
Returns the zoom factor computed stored in this changer.
bool myMoveOnClick
Information whether the user has moved the cursor while pressing a mouse button.
virtual void recenterView()
recenters the view
void onRightBtnPress(void *data)
called when user press right button
bool onLeftBtnRelease(void *data)
called when user releases left button
long onKeyPress(void *data)
called when user press a key
bool gaming
whether the application is in gaming mode or not
double y() const
Returns the y-position.
Definition: Position.h:62
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:369
void zoom(double factor)
Performs the zooming of the view.
Position myZoomBase
the network location on which to zoom using right click+drag
double x() const
Returns the x-position.
Definition: Position.h:57
void setViewport(double zoom, double xPos, double yPos)
Sets the viewport.
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:155
void rotate(int diff)
Performs the rotation of the view.
void setViewportFrom(double xPos, double yPos, double zPos)
Alternative method for setting the viewport.
virtual double getYPos() const
Returns the y-offset of the field to show stored in this changer.
void onLeftBtnPress(void *data)
mouse functions
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
double p2m(double pixel) const
pixels-to-meters conversion method
void onMouseWheel(void *data)
called when user changes mouse wheel
bool onRightBtnRelease(void *data)
called when user releases right button
GUIDanielPerspectiveChanger(GUISUMOAbstractView &callBack, const Boundary &viewPort)
double myOrigWidth
the original viewport dimensions in m which serve as the reference point for 100% zoom ...
void setRotation(double rotation)
Sets the rotation.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
int myMouseButtonState
the current mouse state
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
void onMouseMove(void *data)
called when user moves mouse
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.
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
#define DEG2RAD(x)
Definition: GeomHelper.h:38
GUISUMOAbstractView & myCallback
The parent window (canvas to scale)
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:317
Position rotateAround2D(double rad, const Position &origin)
rotate this position by rad around origin and return the result
Definition: Position.cpp:42
GUIVisualizationSettings & getDefault()
Returns the default scheme.
virtual double getZPos() const
Returns the camera height corresponding to the current zoom factor.
Boundary myViewPort
the intended viewport
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:161
void setWindowCursorPosition(FXint x, FXint y)
Returns the information whether rotation is allowd.
void growWidth(double by)
Increases the width of the boundary (x-axis)
Definition: Boundary.cpp:310
virtual double zoom2ZPos(double zoom) const
Returns the camera height at which the given zoom level is reached.
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:113
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
void updateToolTip()
A method that updates the tooltip.
FXint myMouseXPosition
the current mouse position
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
virtual double getRotation() const
Returns the rotation of the canvas stored in this changer.
virtual double zPos2Zoom(double zPos) const
Returns the zoom level that is achieved at a given camera height.
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:137