Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GUIDialog_EditViewport.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2005-2026 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 dialog to change the viewport
21/****************************************************************************/
22#include <config.h>
23
25#include <utils/geom/Position.h>
35
36#include "GUISUMOAbstractView.h"
38
39
40// ===========================================================================
41// FOX callback mapping
42// ===========================================================================
50
51// Object implementation
52FXIMPLEMENT(GUIDialog_EditViewport, FXDialogBox, GUIDialog_EditViewportMap, ARRAYNUMBER(GUIDialog_EditViewportMap))
53
54// ===========================================================================
55// method definitions
56// ===========================================================================
57
58#ifdef _MSC_VER
59#pragma warning(push)
60#pragma warning(disable: 4355) // mask warning about "this" in initializers
61#endif
63 FXDialogBox(parent, name, GUIDesignDialogBox, 0, 0, 0, 0, 0, 0, 0, 0),
64 GUIPersistentWindowPos(this, "VIEWPORT_DIALOG_SETTINGS", false, 20, 40, 150, 150, 100, 20),
65 myParent(parent) {
66 // create contents frame
67 FXVerticalFrame* contentsFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);
68 // create frame for file icons
69 FXHorizontalFrame* frameFiles = new FXHorizontalFrame(contentsFrame, GUIDesignHorizontalFrameIcons);
70 myLoadButton = GUIDesigns::buildFXButton(frameFiles, TL("Load"), "", TL("Load viewport from file"),
72 mySaveButton = GUIDesigns::buildFXButton(frameFiles, TL("Save"), "", TL("Save viewport to file"),
74 // create horizontalframe for zoom elements and OSG
75 FXHorizontalFrame* editElementsFrame = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
76
77 // create vertical frame for XYZ values
78 FXVerticalFrame* lookFromFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
79
80 // create zoom elements
81 FXHorizontalFrame* zoomFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
82 new FXLabel(zoomFrame, "Zoom:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
83 myZoom = new FXRealSpinner(zoomFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPortZoom);
84 myZoom->setRange(0.0001, 100000);
85 //myZoom->setNumberFormat(4);
86
87 // create lookFromX elements
88 FXHorizontalFrame* lookFromXFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
89 new FXLabel(lookFromXFrame, "X:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
90 myXOff = new FXRealSpinner(lookFromXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
91
92 // create lookFromY elements
93 FXHorizontalFrame* lookFromYFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
94 new FXLabel(lookFromYFrame, "Y:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
95 myYOff = new FXRealSpinner(lookFromYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
96
97 // create lookFromZ elements
98 FXHorizontalFrame* lookFromZFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
99 new FXLabel(lookFromZFrame, "Z:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
100 myZOff = new FXRealSpinner(lookFromZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
101 myZOff->setRange(0.12, 100000000);
102
103 // create rotation elements
104 FXHorizontalFrame* rotationFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
105 new FXLabel(rotationFrame, "A:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
106 myRotation = new FXRealSpinner(rotationFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
107
108 // create Latitude elements
109 FXHorizontalFrame* latFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
110 new FXLabel(latFrame, "Lat:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
111 myLatitude = new FXRealSpinner(latFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
112 myLatitude->setRange(-90.0, 90.0);
113 myLatitude->setIncrement(0.001);
114 myLatitude->setGranularity(1e-6);
115
116 // create Longitude elements
117 FXHorizontalFrame* lonFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
118 new FXLabel(lonFrame, "Lon:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
119 myLongitude = new FXRealSpinner(lonFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
120 myLongitude->setRange(-180.0, 180.0);
121 myLongitude->setIncrement(0.001);
122 myLongitude->setGranularity(1e-6);
123
124 // create vertical frame for OSG
125 FXVerticalFrame* lookAtFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
126 new FXLabel(lookAtFrame, "OSG", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
127
128 // create lookAtX elements
129 FXHorizontalFrame* lookAtXFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
130 new FXLabel(lookAtXFrame, "LookAtX:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
131 myLookAtX = new FXRealSpinner(lookAtXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
132
133 // create lookAtY elements
134 FXHorizontalFrame* lookAtYFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
135 new FXLabel(lookAtYFrame, "LookAtY:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
136 myLookAtY = new FXRealSpinner(lookAtYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
137
138 // create lookAtZ elements
139 FXHorizontalFrame* lookAtZFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
140 new FXLabel(lookAtZFrame, "LookAtZ:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
141 myLookAtZ = new FXRealSpinner(lookAtZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
142
143 // only show LookAt elements for OSG views
144 if (parent->is3DView()) {
145 lookAtFrame->show();
146 } else {
147 lookAtFrame->hide();
148 }
149
150 // create buttons ok/cancel
151 new FXHorizontalSeparator(contentsFrame, GUIDesignHorizontalSeparator);
152 FXHorizontalFrame* frameButtons = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
153 new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
156 new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
157 // set dialog icon
160}
161#ifdef _MSC_VER
162#pragma warning(pop)
163#endif
164
165
167
168
169void
171 // If testing mode is enabled, we need to place focus in the Z dial
172 if (OptionsCont::getOptions().getBool("gui-testing")) {
173 myLoadButton->setFocus();
174 } else {
175 myOKButton->setFocus();
176 }
177 FXDialogBox::show();
178}
179
180
181long
182GUIDialog_EditViewport::onCmdOk(FXObject*, FXSelector, void*) {
183 myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
184#ifdef HAVE_OSG
185 Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
186#else
188#endif
189 , myRotation->getValue()
190 );
191 hide();
192 return 1;
193}
194
195
196long
197GUIDialog_EditViewport::onCmdCancel(FXObject*, FXSelector, void*) {
199 hide();
200 return 1;
201}
202
203
204long
205GUIDialog_EditViewport::onCmdChanged(FXObject* o, FXSelector, void*) {
206 if (o == myZOff) {
207 myZoom->setValue(myParent->getChanger().zPos2Zoom(myZOff->getValue()));
208 } else if (o == myZoom) {
209 if (myParent->is3DView()) {
210 Position camera(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()), lookAt(myLookAtX->getValue(), myLookAtY->getValue(),
211 myLookAtZ->getValue());
212 myParent->zoom2Pos(camera, lookAt, myZoom->getValue());
213 } else {
214 myZOff->setValue(myParent->getChanger().zoom2ZPos(myZoom->getValue()));
215 }
216 } else if (o == myLatitude || o == myLongitude) {
217 if (GeoConvHelper::getFinal().usingGeoProjection()) {
218 Position geo(myLongitude->getValue(), myLatitude->getValue());
219 if (GeoConvHelper::getFinal().x2cartesian_const(geo)) {
220 myXOff->setValue(geo.x());
221 myYOff->setValue(geo.y());
222 }
223 }
224 } else if (o == myXOff || o == myYOff) {
225 if (GeoConvHelper::getFinal().usingGeoProjection()) {
226 Position pos(myXOff->getValue(), myYOff->getValue());
228 myLatitude->setValue(pos.y());
229 myLongitude->setValue(pos.x());
230 }
231 }
232 myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
233#ifdef HAVE_OSG
234 Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
235#else
237#endif
238 , myRotation->getValue()
239 );
240 return 1;
241}
242
243
244long
245GUIDialog_EditViewport::onCmdLoad(FXObject*, FXSelector, void*) {
246 FXFileDialog opendialog(this, TL("Load Viewport"));
247 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
248 opendialog.setSelectMode(SELECTFILE_ANY);
249 opendialog.setPatternList(SUMOXMLDefinitions::ViewSettingsFileExtensions.getMultilineString().c_str());
250 if (gCurrentFolder.length() != 0) {
251 opendialog.setDirectory(gCurrentFolder);
252 }
253 if (opendialog.execute()) {
254 gCurrentFolder = opendialog.getDirectory();
255 GUISettingsHandler handler(getApp(), opendialog.getFilename().text());
256 handler.applyViewport(myParent);
258 }
259 return 1;
260}
261
262
263long
264GUIDialog_EditViewport::onCmdSave(FXObject*, FXSelector, void*) {
265 FXString file = MFXUtils::getFilename2Write(this, TL("Save Viewport"),
266 SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str(),
268 if (file == "") {
269 return 1;
270 }
271 try {
272 OutputDevice& dev = OutputDevice::getDevice(file.text(), false);
274 writeXML(dev);
275 dev.closeTag();
276 dev.close();
277 } catch (IOError& e) {
278 FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
279 }
280 return 1;
281}
282
283
284void
287 dev.writeAttr(SUMO_ATTR_ZOOM, myZoom->getValue());
288 dev.writeAttr(SUMO_ATTR_X, myXOff->getValue());
289 dev.writeAttr(SUMO_ATTR_Y, myYOff->getValue());
290 if (myParent->is3DView()) {
291 dev.writeAttr(SUMO_ATTR_Z, myZOff->getValue());
292 }
293 dev.writeAttr(SUMO_ATTR_ANGLE, myRotation->getValue());
294 if (myParent->is3DView()) {
295 if (myLookAtX->getValue() != Position::INVALID.x()) {
296 dev.writeAttr(SUMO_ATTR_CENTER_X, myLookAtX->getValue());
297 }
298 if (myLookAtY->getValue() != Position::INVALID.y()) {
299 dev.writeAttr(SUMO_ATTR_CENTER_Y, myLookAtY->getValue());
300 }
301 if (myLookAtZ->getValue() != Position::INVALID.z()) {
302 dev.writeAttr(SUMO_ATTR_CENTER_Z, myLookAtZ->getValue());
303 }
304 }
305 dev.closeTag();
306}
307
308
309void
310GUIDialog_EditViewport::setValues(double zoom, double xoff, double yoff, double rotation) {
311 myZoom->setValue(zoom);
312 myXOff->setValue(xoff);
313 myYOff->setValue(yoff);
314 myZOff->setValue(myParent->getChanger().zoom2ZPos(zoom));
315 myRotation->setValue(rotation);
316 if (GeoConvHelper::getFinal().usingGeoProjection()) {
317 Position pos(xoff, yoff);
319 myLatitude->setValue(pos.y());
320 myLongitude->setValue(pos.x());
321 myLatitude->enable();
322 myLongitude->enable();
323 } else {
324 myLatitude->setValue(0);
325 myLongitude->setValue(0);
326 myLatitude->disable();
327 myLongitude->disable();
328 }
329}
330
331
332void
333GUIDialog_EditViewport::setValues(const Position& lookFrom, const Position& lookAt, double rotation) {
334 myXOff->setValue(lookFrom.x());
335 myYOff->setValue(lookFrom.y());
336 myZOff->setValue(lookFrom.z());
337 if (!myParent->is3DView()) {
338 myZoom->setValue(myParent->getChanger().zPos2Zoom(lookFrom.z()));
339 }
340#ifdef HAVE_OSG
341 myLookAtX->setValue(lookAt.x());
342 myLookAtY->setValue(lookAt.y());
343 myLookAtZ->setValue(lookAt.z());
344#else
345 UNUSED_PARAMETER(lookAt);
346#endif
347 myRotation->setValue(rotation);
348 if (GeoConvHelper::getFinal().usingGeoProjection()) {
349 Position pos(lookFrom.x(), lookFrom.y());
351 myLatitude->setValue(pos.y());
352 myLongitude->setValue(pos.x());
353 myLatitude->enable();
354 myLongitude->enable();
355 } else {
356 myLatitude->setValue(0);
357 myLongitude->setValue(0);
358 myLatitude->disable();
359 myLongitude->disable();
360 }
361}
362
363
364void
365GUIDialog_EditViewport::setOldValues(const Position& lookFrom, const Position& lookAt, double rotation) {
366 setValues(lookFrom, lookAt, rotation);
367 myOldLookFrom = lookFrom;
368 myOldLookAt = lookAt;
369 myOldRotation = rotation;
370}
371
372
373bool
375 return false;
376 //return myZoom->getDial().grabbed() || myXOff->getDial().grabbed() || myYOff->getDial().grabbed();
377}
378
379
380double
382 return myZoom->getValue();
383}
384
385void
387 myZoom->setValue(zoom);
388}
389
390
391void
393 getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "x", getX());
394 getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "y", getY());
395}
396
397
398/****************************************************************************/
#define GUIDesignButtonToolbarWithText
little button with text and icon
Definition GUIDesigns.h:147
#define GUIDesignContentsFrame
design for the main content frame of every frame/dialog with padding and spacing
Definition GUIDesigns.h:406
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:430
#define GUIDesignDialogBox
Definition GUIDesigns.h:630
#define GUIDesignSpinDialViewPort
design for standard spin dial
Definition GUIDesigns.h:522
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:439
#define GUIDesignHorizontalFrameIcons
Horizontal frame used for pack icons.
Definition GUIDesigns.h:356
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:251
#define GUIDesignSpinDialViewPortZoom
design for standard spin dial
Definition GUIDesigns.h:519
#define GUIDesignHorizontalSeparator
Definition GUIDesigns.h:494
#define GUIDesignButtonDialog
Definition GUIDesigns.h:174
FXDEFMAP(GUIDialog_EditViewport) GUIDialog_EditViewportMap[]
FXString gCurrentFolder
The folder used as last.
@ EDITVIEWPORT
@ OPEN
open icons
@ SAVE
save icons
#define TL(string)
Definition MsgHandler.h:304
@ SUMO_TAG_VIEWSETTINGS
@ SUMO_TAG_VIEWPORT
@ SUMO_ATTR_Y
@ SUMO_ATTR_Z
@ SUMO_ATTR_X
@ SUMO_ATTR_CENTER_Y
@ SUMO_ATTR_ZOOM
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_CENTER_Z
@ SUMO_ATTR_CENTER_X
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
A dialog to change the viewport.
void setOldValues(const Position &lookFrom, const Position &lookAt, double rotation)
Resets old values.
void writeXML(OutputDevice &dev)
write the settings to the given device
FXButton * mySaveButton
save button
FXButton * myCancelButton
Cancel button.
bool haveGrabbed() const
Returns the information whether one of the spin dialers is grabbed.
long onCmdSave(FXObject *, FXSelector, void *)
Called when the user wants to save a viewport.
Position myOldLookFrom
The old viewport.
void setZoomValue(double zoom)
Resets the zoom spin dialer.
FXRealSpinner * myLatitude
The spin dialers used to change geo coordinates.
GUIDialog_EditViewport(GUISUMOAbstractView *parent, const char *name)
Constructor.
void setValues(double zoom, double xoff, double yoff, double rotation)
Sets the given values into the dialog.
void saveWindowPos()
save window position to the registry
FXButton * myLoadButton
load button
long onCmdLoad(FXObject *, FXSelector, void *)
Called when the user wants to load a viewport.
GUISUMOAbstractView * myParent
The calling view.
FXButton * myOKButton
OK button.
long onCmdCancel(FXObject *, FXSelector, void *)
Called when the user wants to restore the viewport.
long onCmdChanged(FXObject *, FXSelector, void *)
Called when the user changes the viewport.
FXRealSpinner * myLookAtX
The spin dialers used to change the view at (osg only)
long onCmdOk(FXObject *, FXSelector, void *)
Called when the user wants to keep the viewport.
FXRealSpinner * myZoom
The spin dialers used to change the view.
double getZoomValue() const
Returns the current zoom value stored in the corresponding spin dialer.
void show()
overload show function to focus always in OK Button
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
Persists window position in the registry.
virtual double zoom2ZPos(double zoom) const =0
Returns the camera height at which the given zoom level is reached.
virtual double zPos2Zoom(double zPos) const =0
Returns the zoom level that is achieved at a given camera height.
virtual double getRotation() const =0
Returns the rotation of the canvas stored in this changer.
virtual double getZoom() const =0
Returns the zoom factor computed stored in this changer.
virtual double getXPos() const =0
Returns the x-offset of the field to show stored in this changer.
virtual double getYPos() const =0
Returns the y-offset of the field to show stored in this changer.
GUIPerspectiveChanger & getChanger() const
get changer
virtual void zoom2Pos(Position &camera, Position &lookAt, double zoom)
zoom interface for 3D view
virtual void setViewportFromToRot(const Position &lookFrom, const Position &lookAt, double rotation)
applies the given viewport settings
virtual bool is3DView() const
return whether this is a 3D view
An XML-handler for visualisation schemes.
void applyViewport(GUISUMOAbstractView *view) const
Sets the viewport which has been parsed.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:117
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false, const bool escape=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:323
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double y() const
Returns the y-position.
Definition Position.h:57
static StringBijection< XMLFileExtension > XMLFileExtensions
XML file Extensions.
static StringBijection< ViewSettingsFileExtension > ViewSettingsFileExtensions
view settings file extensions
#define UNUSED_PARAMETER(x)