SUMO - Simulation of Urban MObility
GUIDanielPerspectiveChanger.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A class that allows to steer the visual output in dependence to
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <fxkeys.h>
34 #include <utils/geom/Boundary.h>
35 #include <utils/geom/Position.h>
37 #include "GUIPerspectiveChanger.h"
39 
40 
41 // ===========================================================================
42 // method definitions
43 // ===========================================================================
45  GUISUMOAbstractView& callBack, const Boundary& viewPort) :
46  GUIPerspectiveChanger(callBack, viewPort),
47  myOrigWidth(viewPort.getWidth()),
48  myOrigHeight(viewPort.getHeight()),
49  myRotation(0),
50  myMouseButtonState(MOUSEBTN_NONE),
51  myMoveOnClick(false),
52  myZoomBase(viewPort.getCenter()),
53  myDragDelay(0) {
54 }
55 
56 
58 
59 
60 void
61 GUIDanielPerspectiveChanger::move(int xdiff, int ydiff) {
62  myViewPort.moveby(myCallback.p2m(xdiff), -myCallback.p2m(ydiff));
63  myCallback.update();
64 }
65 
66 
67 void
69  if (myCallback.getApp()->reg().readIntEntry("gui", "zoomAtCenter", 1)) {
71  }
72  if (factor > 0) {
74  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmin()) / factor,
75  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymin()) / factor,
76  myZoomBase.x() - (myZoomBase.x() - myViewPort.xmax()) / factor,
77  myZoomBase.y() - (myZoomBase.y() - myViewPort.ymax()) / factor);
78  myCallback.update();
79  }
80 }
81 
82 
83 void
85  /*
86  if (myCallback.allowRotation()) {
87  myRotation += (double) diff / (double) 10.0;
88  myCallback.update();
89  }
90  */
91 }
92 
93 
94 double
96  return myRotation;
97 }
98 
99 
100 double
102  return myViewPort.getCenter().x();
103 }
104 
105 
106 double
108  return myViewPort.getCenter().y();
109 }
110 
111 
112 double
114  return myOrigWidth / myViewPort.getWidth() * 100;
115 }
116 
117 
118 double
120  return myViewPort.getWidth();
121 }
122 
123 
124 double
126  return myOrigWidth / (zoom / 100);
127 }
128 
129 
130 double
132  return (myOrigWidth / zPos) * 100;
133 }
134 
135 
136 void
138  bool applyZoom) {
139  if (applyZoom) {
140  myViewPort = Boundary();
141  myViewPort.add(pos);
142  myViewPort.grow(radius);
143  } else {
144  myViewPort.moveby(pos.x() - getXPos(), pos.y() - getYPos());
145  }
146 }
147 
148 
149 void
152  FXEvent* e = (FXEvent*) data;
153  myMouseXPosition = e->win_x;
154  myMouseYPosition = e->win_y;
155  myMoveOnClick = false;
156  myMouseDownTime = FXThread::time();
157 }
158 
159 
160 bool
163  FXEvent* e = (FXEvent*) data;
164  myMouseXPosition = e->win_x;
165  myMouseYPosition = e->win_y;
166  return myMoveOnClick;
167 }
168 
169 
170 void
173  FXEvent* e = (FXEvent*) data;
174  myMouseXPosition = e->win_x;
175  myMouseYPosition = e->win_y;
176  myMoveOnClick = false;
177  myMouseDownTime = FXThread::time();
179 }
180 
181 
182 bool
185  if (data != 0) {
186  FXEvent* e = (FXEvent*) data;
187  myMouseXPosition = e->win_x;
188  myMouseYPosition = e->win_y;
189  }
190  return myMoveOnClick;
191 }
192 
193 
194 void
196  FXEvent* e = (FXEvent*) data;
197  // catch empty ghost events after scroll (seem to occur only on Ubuntu)
198  if (e->code == 0) {
199  return;
200  }
201  // zoom scale relative delta and its inverse; is optimized (all literals)
202  const double zScale_rDelta_norm = 0.1;
203  const double zScale_rDelta_inv = -zScale_rDelta_norm / (1. + zScale_rDelta_norm);
204  double zScale_rDelta = zScale_rDelta_norm ;
205  if (e->code < 0) {
206  // for inverse zooming direction
207  zScale_rDelta = zScale_rDelta_inv;
208  }
209  // keyboard modifier: slow, fast mouse-zoom
210  if ((e->state & CONTROLMASK) != 0) {
211  zScale_rDelta /= 4;
212  } else if ((e->state & SHIFTMASK) != 0) {
213  zScale_rDelta *= 4;
214  }
216  zoom(1.0 + zScale_rDelta);
218 }
219 
220 
221 void
223  FXEvent* e = (FXEvent*) data;
224  myCallback.setWindowCursorPosition(e->win_x, e->win_y);
225  const int xdiff = myMouseXPosition - e->win_x;
226  const int ydiff = myMouseYPosition - e->win_y;
227  const bool moved = xdiff != 0 || ydiff != 0;
228  const bool pastDelay = !gSchemeStorage.getDefault().gaming && FXThread::time() > (myMouseDownTime + myDragDelay);
229  switch (myMouseButtonState) {
230  case MOUSEBTN_LEFT:
231  if (pastDelay) {
232  move(xdiff, ydiff);
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
279  myViewPort.xmin() - myCallback.p2m(change),
280  myViewPort.ymin(),
281  myViewPort.xmax(),
282  myViewPort.ymax());
283 }
284 
285 
286 long
288  // ignore key events in gaming mode
290  return 0;
291  }
292  FXEvent* e = (FXEvent*) data;
293  double zoomDiff = 0.1;
294  double moveX = 0;
295  double moveY = 0;
296  double moveFactor = 1;
297  bool pageVertical = true;
298  bool ctrl = false;
299  if (e->state & CONTROLMASK) {
300  ctrl = true;
301  zoomDiff /= 2;
302  moveFactor /= 10;
303  } else if (e->state & SHIFTMASK) {
304  pageVertical = false;
305  zoomDiff *= 2;
306  }
307  switch (e->code) {
308  case FX::KEY_Left:
309  moveX = -1;
310  moveFactor /= 10;
311  break;
312  case FX::KEY_Right:
313  moveX = 1;
314  moveFactor /= 10;
315  break;
316  case FX::KEY_Up:
317  moveY = -1;
318  moveFactor /= 10;
319  break;
320  case FX::KEY_Down:
321  moveY = 1;
322  moveFactor /= 10;
323  break;
324  case FX::KEY_Page_Up:
325  if (pageVertical) {
326  moveY = -1;
327  } else {
328  moveX = -1;
329  }
330  break;
331  case FX::KEY_Page_Down:
332  if (pageVertical) {
333  moveY = 1;
334  } else {
335  moveX = 1;
336  }
337  break;
338  case FX::KEY_plus:
339  case FX::KEY_KP_Add:
341  zoom(1.0 + zoomDiff);
343  return 1;
344  case FX::KEY_minus:
345  case FX::KEY_KP_Subtract:
346  zoomDiff = -zoomDiff;
348  zoom(1.0 + zoomDiff);
350  return 1;
351  case FX::KEY_Home:
352  case FX::KEY_KP_Home:
354  myCallback.update();
355  return 1;
356  case FX::KEY_v:
357  // from an architecture standpoint this isn't the best place to put
358  // this. But its simple
359  if (ctrl) {
361  return 1;
362  }
363  default:
364  return 0;
365  }
366  myViewPort.moveby(moveX * moveFactor * myViewPort.getWidth(),
367  -moveY * moveFactor * myViewPort.getHeight());
368  myCallback.update();
369  return 1;
370 }
371 
372 
373 /****************************************************************************/
double myRotation
the current rotation
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:138
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:132
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:68
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:283
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:63
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:162
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:48
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:46
int myMouseButtonState
the current mouse state
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
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:234
GUISUMOAbstractView & myCallback
The parent window (canvas to scale)
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:250
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:168
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:243
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:120
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:86
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:144