Line data Source code
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 : /****************************************************************************/
14 : /// @file GUIDialog_EditViewport.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Laura Bieker
17 : /// @author Michael Behrisch
18 : /// @date Mon, 25.04.2005
19 : ///
20 : // A dialog to change the viewport
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <utils/common/MsgHandler.h>
25 : #include <utils/geom/Position.h>
26 : #include <utils/foxtools/MFXUtils.h>
27 : #include <utils/gui/windows/GUIAppEnum.h>
28 : #include <utils/gui/windows/GUIPerspectiveChanger.h>
29 : #include <utils/gui/images/GUIIconSubSys.h>
30 : #include <utils/gui/div/GUIIOGlobals.h>
31 : #include <utils/gui/div/GUIDesigns.h>
32 : #include <utils/gui/settings/GUISettingsHandler.h>
33 : #include <utils/options/OptionsCont.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[] = {
43 : FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_CHANGED, GUIDialog_EditViewport::onCmdChanged),
44 : FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_OK, GUIDialog_EditViewport::onCmdOk),
45 : FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_CANCEL, GUIDialog_EditViewport::onCmdCancel),
46 : FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_LOAD, GUIDialog_EditViewport::onCmdLoad),
47 : FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_SAVE, GUIDialog_EditViewport::onCmdSave),
48 : };
49 :
50 : // Object implementation
51 0 : FXIMPLEMENT(GUIDialog_EditViewport, FXDialogBox, GUIDialog_EditViewportMap, ARRAYNUMBER(GUIDialog_EditViewportMap))
52 :
53 : // ===========================================================================
54 : // method definitions
55 : // ===========================================================================
56 :
57 0 : GUIDialog_EditViewport::GUIDialog_EditViewport(GUISUMOAbstractView* parent, const char* name) :
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 0 : myParent(parent) {
61 : // create contents frame
62 0 : FXVerticalFrame* contentsFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);
63 : // create frame for file icons
64 0 : FXHorizontalFrame* frameFiles = new FXHorizontalFrame(contentsFrame, GUIDesignHorizontalFrameIcons);
65 0 : myLoadButton = GUIDesigns::buildFXButton(frameFiles, TL("Load"), "", TL("Load viewport from file"),
66 : GUIIconSubSys::getIcon(GUIIcon::OPEN), this, GUIDialog_EditViewport::MID_LOAD, GUIDesignButtonToolbarWithText);
67 0 : mySaveButton = GUIDesigns::buildFXButton(frameFiles, TL("Save"), "", TL("Save viewport to file"),
68 : GUIIconSubSys::getIcon(GUIIcon::SAVE), this, GUIDialog_EditViewport::MID_SAVE, GUIDesignButtonToolbarWithText);
69 : // create horizontalframe for zoom elements and OSG
70 0 : FXHorizontalFrame* editElementsFrame = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
71 :
72 : // create vertical frame for XYZ values
73 0 : FXVerticalFrame* lookFromFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
74 :
75 : // create zoom elements
76 0 : FXHorizontalFrame* zoomFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
77 0 : new FXLabel(zoomFrame, "Zoom:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
78 0 : myZoom = new FXRealSpinner(zoomFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPortZoom);
79 0 : myZoom->setRange(0.0001, 100000);
80 : //myZoom->setNumberFormat(4);
81 :
82 : // create lookFromX elements
83 0 : FXHorizontalFrame* lookFromXFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
84 0 : new FXLabel(lookFromXFrame, "X:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
85 0 : myXOff = new FXRealSpinner(lookFromXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
86 :
87 : // create lookFromY elements
88 0 : FXHorizontalFrame* lookFromYFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
89 0 : new FXLabel(lookFromYFrame, "Y:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
90 0 : myYOff = new FXRealSpinner(lookFromYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
91 :
92 : // create lookFromZ elements
93 0 : FXHorizontalFrame* lookFromZFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
94 0 : new FXLabel(lookFromZFrame, "Z:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
95 0 : myZOff = new FXRealSpinner(lookFromZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
96 0 : myZOff->setRange(0.12, 100000000);
97 :
98 : // create rotation elements
99 0 : FXHorizontalFrame* rotationFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);
100 0 : new FXLabel(rotationFrame, "A:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
101 0 : myRotation = new FXRealSpinner(rotationFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
102 :
103 : // create vertical frame for OSG
104 0 : FXVerticalFrame* lookAtFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);
105 0 : new FXLabel(lookAtFrame, "OSG", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
106 :
107 : // create lookAtX elements
108 0 : FXHorizontalFrame* lookAtXFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
109 0 : new FXLabel(lookAtXFrame, "LookAtX:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
110 0 : myLookAtX = new FXRealSpinner(lookAtXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
111 :
112 : // create lookAtY elements
113 0 : FXHorizontalFrame* lookAtYFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
114 0 : new FXLabel(lookAtYFrame, "LookAtY:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
115 0 : myLookAtY = new FXRealSpinner(lookAtYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
116 :
117 : // create lookAtZ elements
118 0 : FXHorizontalFrame* lookAtZFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);
119 0 : new FXLabel(lookAtZFrame, "LookAtZ:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
120 0 : myLookAtZ = new FXRealSpinner(lookAtZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);
121 :
122 : // only show LookAt elements for OSG views
123 0 : if (parent->is3DView()) {
124 0 : lookAtFrame->show();
125 : } else {
126 0 : lookAtFrame->hide();
127 : }
128 :
129 : // create buttons ok/cancel
130 0 : new FXHorizontalSeparator(contentsFrame, GUIDesignHorizontalSeparator);
131 0 : FXHorizontalFrame* frameButtons = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);
132 0 : new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
133 0 : myOKButton = GUIDesigns::buildFXButton(frameButtons, TL("&OK"), "", TL("accept"), GUIIconSubSys::getIcon(GUIIcon::ACCEPT), this, GUIDialog_EditViewport::MID_OK, GUIDesignButtonOK);
134 0 : myCancelButton = GUIDesigns::buildFXButton(frameButtons, TL("&Cancel"), "", TL("close"), GUIIconSubSys::getIcon(GUIIcon::CANCEL), this, GUIDialog_EditViewport::MID_CANCEL, GUIDesignButtonCancel);
135 0 : new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);
136 : // set dialog icon
137 0 : setIcon(GUIIconSubSys::getIcon(GUIIcon::EDITVIEWPORT));
138 0 : loadWindowPos();
139 0 : }
140 :
141 :
142 0 : GUIDialog_EditViewport::~GUIDialog_EditViewport() {}
143 :
144 :
145 : void
146 0 : GUIDialog_EditViewport::show() {
147 : // If testing mode is enabled, we need to place focus in the Z dial
148 0 : if (OptionsCont::getOptions().getBool("gui-testing")) {
149 0 : myLoadButton->setFocus();
150 : } else {
151 0 : myOKButton->setFocus();
152 : }
153 0 : FXDialogBox::show();
154 0 : }
155 :
156 :
157 : long
158 0 : GUIDialog_EditViewport::onCmdOk(FXObject*, FXSelector, void*) {
159 0 : myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
160 : #ifdef HAVE_OSG
161 0 : Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
162 : #else
163 : Position::INVALID
164 : #endif
165 0 : , myRotation->getValue()
166 : );
167 : // write information of current zoom status
168 0 : WRITE_DEBUG("Current Viewport values: " + toString(myXOff->getValue()) + ", " + toString(myYOff->getValue()) + ", " + toString(myZOff->getValue()) +
169 : ". Zoom = '" + toString(myZoom->getValue()) + "'");
170 0 : hide();
171 0 : return 1;
172 : }
173 :
174 :
175 : long
176 0 : GUIDialog_EditViewport::onCmdCancel(FXObject*, FXSelector, void*) {
177 0 : myParent->setViewportFromToRot(myOldLookFrom, myOldLookAt, myOldRotation);
178 0 : hide();
179 0 : return 1;
180 : }
181 :
182 :
183 : long
184 0 : GUIDialog_EditViewport::onCmdChanged(FXObject* o, FXSelector, void*) {
185 0 : if (o == myZOff) {
186 0 : myZoom->setValue(myParent->getChanger().zPos2Zoom(myZOff->getValue()));
187 0 : } else if (o == myZoom) {
188 0 : if (myParent->is3DView()) {
189 0 : Position camera(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()), lookAt(myLookAtX->getValue(), myLookAtY->getValue(),
190 0 : myLookAtZ->getValue());
191 0 : myParent->zoom2Pos(camera, lookAt, myZoom->getValue());
192 : } else {
193 0 : myZOff->setValue(myParent->getChanger().zoom2ZPos(myZoom->getValue()));
194 : }
195 : }
196 0 : myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),
197 : #ifdef HAVE_OSG
198 0 : Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())
199 : #else
200 : Position::INVALID
201 : #endif
202 0 : , myRotation->getValue()
203 : );
204 0 : return 1;
205 : }
206 :
207 :
208 : long
209 0 : GUIDialog_EditViewport::onCmdLoad(FXObject*, FXSelector, void*) {
210 0 : FXFileDialog opendialog(this, TL("Load Viewport"));
211 0 : opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
212 0 : opendialog.setSelectMode(SELECTFILE_ANY);
213 0 : opendialog.setPatternList("*.xml,*.xml.gz");
214 0 : if (gCurrentFolder.length() != 0) {
215 0 : opendialog.setDirectory(gCurrentFolder);
216 : }
217 0 : if (opendialog.execute()) {
218 0 : gCurrentFolder = opendialog.getDirectory();
219 0 : GUISettingsHandler handler(opendialog.getFilename().text());
220 0 : handler.applyViewport(myParent);
221 0 : setValues(myParent->getChanger().getZoom(), myParent->getChanger().getXPos(), myParent->getChanger().getYPos(), myParent->getChanger().getRotation());
222 0 : }
223 0 : return 1;
224 0 : }
225 :
226 :
227 : long
228 0 : GUIDialog_EditViewport::onCmdSave(FXObject*, FXSelector, void*) {
229 0 : FXString file = MFXUtils::getFilename2Write(this, TL("Save Viewport"), ".xml", GUIIconSubSys::getIcon(GUIIcon::SAVE), gCurrentFolder);
230 0 : if (file == "") {
231 : return 1;
232 : }
233 : try {
234 0 : OutputDevice& dev = OutputDevice::getDevice(file.text(), false);
235 0 : dev.openTag(SUMO_TAG_VIEWSETTINGS);
236 0 : writeXML(dev);
237 0 : dev.closeTag();
238 0 : dev.close();
239 0 : } catch (IOError& e) {
240 0 : FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
241 0 : }
242 : return 1;
243 0 : }
244 :
245 :
246 : void
247 0 : GUIDialog_EditViewport::writeXML(OutputDevice& dev) {
248 0 : dev.openTag(SUMO_TAG_VIEWPORT);
249 0 : dev.writeAttr(SUMO_ATTR_ZOOM, myZoom->getValue());
250 0 : dev.writeAttr(SUMO_ATTR_X, myXOff->getValue());
251 0 : dev.writeAttr(SUMO_ATTR_Y, myYOff->getValue());
252 0 : if (myParent->is3DView()) {
253 0 : dev.writeAttr(SUMO_ATTR_Z, myZOff->getValue());
254 : }
255 0 : dev.writeAttr(SUMO_ATTR_ANGLE, myRotation->getValue());
256 0 : if (myParent->is3DView()) {
257 0 : if (myLookAtX->getValue() != Position::INVALID.x()) {
258 0 : dev.writeAttr(SUMO_ATTR_CENTER_X, myLookAtX->getValue());
259 : }
260 0 : if (myLookAtY->getValue() != Position::INVALID.y()) {
261 0 : dev.writeAttr(SUMO_ATTR_CENTER_Y, myLookAtY->getValue());
262 : }
263 0 : if (myLookAtZ->getValue() != Position::INVALID.z()) {
264 0 : dev.writeAttr(SUMO_ATTR_CENTER_Z, myLookAtZ->getValue());
265 : }
266 : }
267 0 : dev.closeTag();
268 0 : }
269 :
270 :
271 : void
272 0 : GUIDialog_EditViewport::setValues(double zoom, double xoff, double yoff, double rotation) {
273 0 : myZoom->setValue(zoom);
274 0 : myXOff->setValue(xoff);
275 0 : myYOff->setValue(yoff);
276 0 : myZOff->setValue(myParent->getChanger().zoom2ZPos(zoom));
277 0 : myRotation->setValue(rotation);
278 0 : }
279 :
280 :
281 : void
282 0 : GUIDialog_EditViewport::setValues(const Position& lookFrom, const Position& lookAt, double rotation) {
283 0 : myXOff->setValue(lookFrom.x());
284 0 : myYOff->setValue(lookFrom.y());
285 0 : myZOff->setValue(lookFrom.z());
286 0 : if (!myParent->is3DView()) {
287 0 : myZoom->setValue(myParent->getChanger().zPos2Zoom(lookFrom.z()));
288 : }
289 : #ifdef HAVE_OSG
290 0 : myLookAtX->setValue(lookAt.x());
291 0 : myLookAtY->setValue(lookAt.y());
292 0 : myLookAtZ->setValue(lookAt.z());
293 : #else
294 : UNUSED_PARAMETER(lookAt);
295 : #endif
296 0 : myRotation->setValue(rotation);
297 0 : }
298 :
299 :
300 : void
301 0 : GUIDialog_EditViewport::setOldValues(const Position& lookFrom, const Position& lookAt, double rotation) {
302 0 : setValues(lookFrom, lookAt, rotation);
303 0 : myOldLookFrom = lookFrom;
304 0 : myOldLookAt = lookAt;
305 0 : myOldRotation = rotation;
306 0 : }
307 :
308 :
309 : bool
310 0 : GUIDialog_EditViewport::haveGrabbed() const {
311 0 : return false;
312 : //return myZoom->getDial().grabbed() || myXOff->getDial().grabbed() || myYOff->getDial().grabbed();
313 : }
314 :
315 :
316 : double
317 0 : GUIDialog_EditViewport::getZoomValue() const {
318 0 : return myZoom->getValue();
319 : }
320 :
321 : void
322 0 : GUIDialog_EditViewport::setZoomValue(double zoom) {
323 0 : myZoom->setValue(zoom);
324 0 : }
325 :
326 :
327 : void
328 0 : GUIDialog_EditViewport::saveWindowPos() {
329 0 : getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "x", getX());
330 0 : getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "y", getY());
331 0 : }
332 :
333 :
334 : /****************************************************************************/
|