Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-2025 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>
34
35#include "GUISUMOAbstractView.h"
37
38
39// ===========================================================================
40// FOX callback mapping
41// ===========================================================================
49
50// Object implementation
51FXIMPLEMENT(GUIDialog_EditViewport, FXDialogBox, GUIDialog_EditViewportMap, ARRAYNUMBER(GUIDialog_EditViewportMap))
52
53// ===========================================================================
54// method definitions
55// ===========================================================================
56
57#ifdef _MSC_VER
58#pragma warning(push)
59#pragma warning(disable: 4355) // mask warning about "this" in initializers
60#endif
62 FXDialogBox(parent, name, GUIDesignDialogBox, 0, 0, 0, 0, 0, 0, 0, 0),
63 GUIPersistentWindowPos(this, "VIEWPORT_DIALOG_SETTINGS", false, 20, 40, 150, 150, 100, 20),
64 myParent(parent) {
65 // create contents frame
66 FXVerticalFrame* contentsFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);
67 // create frame for file icons
68 FXHorizontalFrame* frameFiles = new FXHorizontalFrame(contentsFrame, GUIDesignHorizontalFrameIcons);
69 myLoadButton = GUIDesigns::buildFXButton(frameFiles, TL("Load"), "", TL("Load viewport from file"),
71 mySaveButton = GUIDesigns::buildFXButton(frameFiles, TL("Save"), "", TL("Save viewport to file"),
73 // create horizontalframe for zoom elements and OSG
74 FXHorizontalFrame* editElementsFrame = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
75
76 // create vertical frame for XYZ values
77 FXVerticalFrame* lookFromFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
78
79 // create zoom elements
80 FXHorizontalFrame* zoomFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
81 new FXLabel(zoomFrame, "Zoom:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
82 myZoom = new FXRealSpinner(zoomFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPortZoom);
83 myZoom->setRange(0.0001, 100000);
84 //myZoom->setNumberFormat(4);
85
86 // create lookFromX elements
87 FXHorizontalFrame* lookFromXFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
88 new FXLabel(lookFromXFrame, "X:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
89 myXOff = new FXRealSpinner(lookFromXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
90
91 // create lookFromY elements
92 FXHorizontalFrame* lookFromYFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
93 new FXLabel(lookFromYFrame, "Y:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
94 myYOff = new FXRealSpinner(lookFromYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
95
96 // create lookFromZ elements
97 FXHorizontalFrame* lookFromZFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
98 new FXLabel(lookFromZFrame, "Z:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
99 myZOff = new FXRealSpinner(lookFromZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
100 myZOff->setRange(0.12, 100000000);
101
102 // create rotation elements
103 FXHorizontalFrame* rotationFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
104 new FXLabel(rotationFrame, "A:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
105 myRotation = new FXRealSpinner(rotationFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
106
107 // create vertical frame for OSG
108 FXVerticalFrame* lookAtFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
109 new FXLabel(lookAtFrame, "OSG", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
110
111 // create lookAtX elements
112 FXHorizontalFrame* lookAtXFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
113 new FXLabel(lookAtXFrame, "LookAtX:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
114 myLookAtX = new FXRealSpinner(lookAtXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
115
116 // create lookAtY elements
117 FXHorizontalFrame* lookAtYFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
118 new FXLabel(lookAtYFrame, "LookAtY:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
119 myLookAtY = new FXRealSpinner(lookAtYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
120
121 // create lookAtZ elements
122 FXHorizontalFrame* lookAtZFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
123 new FXLabel(lookAtZFrame, "LookAtZ:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
124 myLookAtZ = new FXRealSpinner(lookAtZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
125
126 // only show LookAt elements for OSG views
127 if (parent->is3DView()) {
128 lookAtFrame->show();
129 } else {
130 lookAtFrame->hide();
131 }
132
133 // create buttons ok/cancel
134 new FXHorizontalSeparator(contentsFrame, GUIDesignHorizontalSeparator);
135 FXHorizontalFrame* frameButtons = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
136 new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
139 new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
140 // set dialog icon
143}
144#ifdef _MSC_VER
145#pragma warning(pop)
146#endif
147
148
150
151
152void
154 // If testing mode is enabled, we need to place focus in the Z dial
155 if (OptionsCont::getOptions().getBool("gui-testing")) {
156 myLoadButton->setFocus();
157 } else {
158 myOKButton->setFocus();
159 }
160 FXDialogBox::show();
161}
162
163
164long
165GUIDialog_EditViewport::onCmdOk(FXObject*, FXSelector, void*) {
166 myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
167#ifdef HAVE_OSG
168 Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
169#else
171#endif
172 , myRotation->getValue()
173 );
174 hide();
175 return 1;
176}
177
178
179long
180GUIDialog_EditViewport::onCmdCancel(FXObject*, FXSelector, void*) {
182 hide();
183 return 1;
184}
185
186
187long
188GUIDialog_EditViewport::onCmdChanged(FXObject* o, FXSelector, void*) {
189 if (o == myZOff) {
190 myZoom->setValue(myParent->getChanger().zPos2Zoom(myZOff->getValue()));
191 } else if (o == myZoom) {
192 if (myParent->is3DView()) {
193 Position camera(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()), lookAt(myLookAtX->getValue(), myLookAtY->getValue(),
194 myLookAtZ->getValue());
195 myParent->zoom2Pos(camera, lookAt, myZoom->getValue());
196 } else {
197 myZOff->setValue(myParent->getChanger().zoom2ZPos(myZoom->getValue()));
198 }
199 }
200 myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
201#ifdef HAVE_OSG
202 Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
203#else
205#endif
206 , myRotation->getValue()
207 );
208 return 1;
209}
210
211
212long
213GUIDialog_EditViewport::onCmdLoad(FXObject*, FXSelector, void*) {
214 FXFileDialog opendialog(this, TL("Load Viewport"));
215 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
216 opendialog.setSelectMode(SELECTFILE_ANY);
217 opendialog.setPatternList(SUMOXMLDefinitions::ViewSettingsFileExtensions.getMultilineString().c_str());
218 if (gCurrentFolder.length() != 0) {
219 opendialog.setDirectory(gCurrentFolder);
220 }
221 if (opendialog.execute()) {
222 gCurrentFolder = opendialog.getDirectory();
223 GUISettingsHandler handler(opendialog.getFilename().text());
224 handler.applyViewport(myParent);
226 }
227 return 1;
228}
229
230
231long
232GUIDialog_EditViewport::onCmdSave(FXObject*, FXSelector, void*) {
233 FXString file = MFXUtils::getFilename2Write(this, TL("Save Viewport"),
234 SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str(),
236 if (file == "") {
237 return 1;
238 }
239 try {
240 OutputDevice& dev = OutputDevice::getDevice(file.text(), false);
242 writeXML(dev);
243 dev.closeTag();
244 dev.close();
245 } catch (IOError& e) {
246 FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
247 }
248 return 1;
249}
250
251
252void
255 dev.writeAttr(SUMO_ATTR_ZOOM, myZoom->getValue());
256 dev.writeAttr(SUMO_ATTR_X, myXOff->getValue());
257 dev.writeAttr(SUMO_ATTR_Y, myYOff->getValue());
258 if (myParent->is3DView()) {
259 dev.writeAttr(SUMO_ATTR_Z, myZOff->getValue());
260 }
261 dev.writeAttr(SUMO_ATTR_ANGLE, myRotation->getValue());
262 if (myParent->is3DView()) {
263 if (myLookAtX->getValue() != Position::INVALID.x()) {
264 dev.writeAttr(SUMO_ATTR_CENTER_X, myLookAtX->getValue());
265 }
266 if (myLookAtY->getValue() != Position::INVALID.y()) {
267 dev.writeAttr(SUMO_ATTR_CENTER_Y, myLookAtY->getValue());
268 }
269 if (myLookAtZ->getValue() != Position::INVALID.z()) {
270 dev.writeAttr(SUMO_ATTR_CENTER_Z, myLookAtZ->getValue());
271 }
272 }
273 dev.closeTag();
274}
275
276
277void
278GUIDialog_EditViewport::setValues(double zoom, double xoff, double yoff, double rotation) {
279 myZoom->setValue(zoom);
280 myXOff->setValue(xoff);
281 myYOff->setValue(yoff);
282 myZOff->setValue(myParent->getChanger().zoom2ZPos(zoom));
283 myRotation->setValue(rotation);
284}
285
286
287void
288GUIDialog_EditViewport::setValues(const Position& lookFrom, const Position& lookAt, double rotation) {
289 myXOff->setValue(lookFrom.x());
290 myYOff->setValue(lookFrom.y());
291 myZOff->setValue(lookFrom.z());
292 if (!myParent->is3DView()) {
293 myZoom->setValue(myParent->getChanger().zPos2Zoom(lookFrom.z()));
294 }
295#ifdef HAVE_OSG
296 myLookAtX->setValue(lookAt.x());
297 myLookAtY->setValue(lookAt.y());
298 myLookAtZ->setValue(lookAt.z());
299#else
300 UNUSED_PARAMETER(lookAt);
301#endif
302 myRotation->setValue(rotation);
303}
304
305
306void
307GUIDialog_EditViewport::setOldValues(const Position& lookFrom, const Position& lookAt, double rotation) {
308 setValues(lookFrom, lookAt, rotation);
309 myOldLookFrom = lookFrom;
310 myOldLookAt = lookAt;
311 myOldRotation = rotation;
312}
313
314
315bool
317 return false;
318 //return myZoom->getDial().grabbed() || myXOff->getDial().grabbed() || myYOff->getDial().grabbed();
319}
320
321
322double
324 return myZoom->getValue();
325}
326
327void
329 myZoom->setValue(zoom);
330}
331
332
333void
335 getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "x", getX());
336 getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "y", getY());
337}
338
339
340/****************************************************************************/
#define GUIDesignButtonToolbarWithText
little button with text and icon
Definition GUIDesigns.h:126
#define GUIDesignButtonCancel
Cancel Button.
Definition GUIDesigns.h:162
#define GUIDesignContentsFrame
design for the main content frame of every frame/dialog with padding and spacing
Definition GUIDesigns.h:387
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:399
#define GUIDesignDialogBox
Definition GUIDesigns.h:599
#define GUIDesignSpinDialViewPort
design for standard spin dial
Definition GUIDesigns.h:491
#define GUIDesignButtonOK
Definition GUIDesigns.h:153
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:408
#define GUIDesignHorizontalFrameIcons
Horizontal frame used for pack icons.
Definition GUIDesigns.h:337
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:249
#define GUIDesignSpinDialViewPortZoom
design for standard spin dial
Definition GUIDesigns.h:488
#define GUIDesignHorizontalSeparator
Definition GUIDesigns.h:463
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:305
@ 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.
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 FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:116
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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:319
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)