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