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