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