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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // A class that allows to steer the visual output in dependence to
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <fxkeys.h>
33 #include <utils/geom/Boundary.h>
34 #include <utils/geom/Position.h>
36 #include "GUIPerspectiveChanger.h"
38 
39 
40 // ===========================================================================
41 // method definitions
42 // ===========================================================================
44  GUISUMOAbstractView& callBack, const Boundary& viewPort) :
45  GUIPerspectiveChanger(callBack, viewPort),
46  myOrigWidth(viewPort.getWidth()),
47  myOrigHeight(viewPort.getHeight()),
48  myRotation(0),
49  myMouseButtonState(MOUSEBTN_NONE),
50  myMoveOnClick(false),
51  myZoomBase(viewPort.getCenter()),
52  myDragDelay(0) {
53 }
54 
55 
57 
58 
59 void
60 GUIDanielPerspectiveChanger::move(int xdiff, int ydiff) {
61  myViewPort.moveby(myCallback.p2m(xdiff), -myCallback.p2m(ydiff));
62  myCallback.update();
63 }
64 
65 
66 void
68  if (myCallback.getApp()->reg().readIntEntry("gui", "zoomAtCenter", 1)) {
70  }
71  if (factor > 0) {
73  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmin()) / factor,
74  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymin()) / factor,
75  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmax()) / factor,
76  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymax()) / factor);
77  myCallback.update();
78  }
79 }
80 
81 
82 void
84  /*
85  if (myCallback.allowRotation()) {
86  myRotation += (double) diff / (double) 10.0;
87  myCallback.update();
88  }
89  */
90 }
91 
92 
93 double
95  return myRotation;
96 }
97 
98 
99 double
101  return myViewPort.getCenter().x();
102 }
103 
104 
105 double
107  return myViewPort.getCenter().y();
108 }
109 
110 
111 double
113  return myOrigWidth / myViewPort.getWidth() * 100;
114 }
115 
116 
117 double
119  return myViewPort.getWidth();
120 }
121 
122 
123 double
125  return myOrigWidth / (zoom / 100);
126 }
127 
128 
129 double
131  return (myOrigWidth / zPos) * 100;
132 }
133 
134 
135 void
137  bool applyZoom) {
138  if (applyZoom) {
139  myViewPort = Boundary();
140  myViewPort.add(pos);
141  myViewPort.grow(radius);
142  } else {
143  myViewPort.moveby(pos.x() - getXPos(), pos.y() - getYPos());
144  }
145 }
146 
147 
148 void
151  FXEvent* e = (FXEvent*) data;
152  myMouseXPosition = e->win_x;
153  myMouseYPosition = e->win_y;
154  myMoveOnClick = false;
155  myMouseDownTime = FXThread::time();
156 }
157 
158 
159 bool
162  FXEvent* e = (FXEvent*) data;
163  myMouseXPosition = e->win_x;
164  myMouseYPosition = e->win_y;
165  return myMoveOnClick;
166 }
167 
168 
169 void
172  FXEvent* e = (FXEvent*) data;
173  myMouseXPosition = e->win_x;
174  myMouseYPosition = e->win_y;
175  myMoveOnClick = false;
176  myMouseDownTime = FXThread::time();
178 }
179 
180 
181 bool
184  if (data != 0) {
185  FXEvent* e = (FXEvent*) data;
186  myMouseXPosition = e->win_x;
187  myMouseYPosition = e->win_y;
188  }
189  return myMoveOnClick;
190 }
191 
192 
193 void
195  FXEvent* e = (FXEvent*) data;
196  // catch empty ghost events after scroll (seem to occur only on Ubuntu)
197  if (e->code == 0) {
198  return;
199  }
200  // zoom scale relative delta and its inverse; is optimized (all literals)
201  const double zScale_rDelta_norm = 0.1;
202  const double zScale_rDelta_inv = -zScale_rDelta_norm / (1. + zScale_rDelta_norm);
203  double zScale_rDelta = zScale_rDelta_norm ;
204  if (e->code < 0) {
205  // for inverse zooming direction
206  zScale_rDelta = zScale_rDelta_inv;
207  }
208  // keyboard modifier: slow, fast mouse-zoom
209  if ((e->state & CONTROLMASK) != 0) {
210  zScale_rDelta /= 4;
211  } else if ((e->state & SHIFTMASK) != 0) {
212  zScale_rDelta *= 4;
213  }
215  zoom(1.0 + zScale_rDelta);
217 }
218 
219 
220 void
222  FXEvent* e = (FXEvent*) data;
223  myCallback.setWindowCursorPosition(e->win_x, e->win_y);
224  const int xdiff = myMouseXPosition - e->win_x;
225  const int ydiff = myMouseYPosition - e->win_y;
226  const bool moved = xdiff != 0 || ydiff != 0;
227  const bool pastDelay = !gSchemeStorage.getDefault().gaming && FXThread::time() > (myMouseDownTime + myDragDelay);
228  switch (myMouseButtonState) {
229  case MOUSEBTN_LEFT:
230  if (pastDelay) {
231  move(xdiff, ydiff);
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
278  myViewPort.xmin() - myCallback.p2m(change),
279  myViewPort.ymin(),
280  myViewPort.xmax(),
281  myViewPort.ymax());
282 }
283 
284 
285 long
287  // ignore key events in gaming mode
289  return 0;
290  }
291  FXEvent* e = (FXEvent*) data;
292  double zoomDiff = 0.1;
293  double moveX = 0;
294  double moveY = 0;
295  double moveFactor = 1;
296  bool pageVertical = true;
297  bool ctrl = false;
298  if (e->state & CONTROLMASK) {
299  ctrl = true;
300  zoomDiff /= 2;
301  moveFactor /= 10;
302  } else if (e->state & SHIFTMASK) {
303  pageVertical = false;
304  zoomDiff *= 2;
305  }
306  switch (e->code) {
307  case FX::KEY_Left:
308  moveX = -1;
309  moveFactor /= 10;
310  break;
311  case FX::KEY_Right:
312  moveX = 1;
313  moveFactor /= 10;
314  break;
315  case FX::KEY_Up:
316  moveY = -1;
317  moveFactor /= 10;
318  break;
319  case FX::KEY_Down:
320  moveY = 1;
321  moveFactor /= 10;
322  break;
323  case FX::KEY_Page_Up:
324  if (pageVertical) {
325  moveY = -1;
326  } else {
327  moveX = -1;
328  }
329  break;
330  case FX::KEY_Page_Down:
331  if (pageVertical) {
332  moveY = 1;
333  } else {
334  moveX = 1;
335  }
336  break;
337  case FX::KEY_plus:
338  case FX::KEY_KP_Add:
340  zoom(1.0 + zoomDiff);
342  return 1;
343  case FX::KEY_minus:
344  case FX::KEY_KP_Subtract:
345  zoomDiff = -zoomDiff;
347  zoom(1.0 + zoomDiff);
349  return 1;
350  case FX::KEY_Home:
351  case FX::KEY_KP_Home:
353  myCallback.update();
354  return 1;
355  case FX::KEY_v:
356  // from an architecture standpoint this isn't the best place to put
357  // this. But its simple
358  if (ctrl) {
360  return 1;
361  }
362  default:
363  return 0;
364  }
365  myViewPort.moveby(moveX * moveFactor * myViewPort.getWidth(),
366  -moveY * moveFactor * myViewPort.getHeight());
367  myCallback.update();
368  return 1;
369 }
370 
371 
372 /****************************************************************************/
double myRotation
the current rotation
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:137
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:131
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:67
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:350
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:62
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:161
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:47
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 ...
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
int myMouseButtonState
the current mouse state
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:125
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
GUISUMOAbstractView & myCallback
The parent window (canvas to scale)
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:317
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:167
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:119
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 showViewschemeEditor()
show viewsscheme editor
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:85
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:143