Path: blob/main/src/utils/gui/windows/GUIDialog_EditViewport.cpp
169684 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2005-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GUIDialog_EditViewport.cpp14/// @author Daniel Krajzewicz15/// @author Laura Bieker16/// @author Michael Behrisch17/// @date Mon, 25.04.200518///19// A dialog to change the viewport20/****************************************************************************/21#include <config.h>2223#include <utils/common/MsgHandler.h>24#include <utils/geom/Position.h>25#include <utils/foxtools/MFXUtils.h>26#include <utils/gui/windows/GUIAppEnum.h>27#include <utils/gui/windows/GUIPerspectiveChanger.h>28#include <utils/gui/images/GUIIconSubSys.h>29#include <utils/gui/div/GUIIOGlobals.h>30#include <utils/gui/div/GUIDesigns.h>31#include <utils/gui/settings/GUISettingsHandler.h>32#include <utils/options/OptionsCont.h>3334#include "GUISUMOAbstractView.h"35#include "GUIDialog_EditViewport.h"363738// ===========================================================================39// FOX callback mapping40// ===========================================================================41FXDEFMAP(GUIDialog_EditViewport) GUIDialog_EditViewportMap[] = {42FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_CHANGED, GUIDialog_EditViewport::onCmdChanged),43FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_OK, GUIDialog_EditViewport::onCmdOk),44FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_CANCEL, GUIDialog_EditViewport::onCmdCancel),45FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_LOAD, GUIDialog_EditViewport::onCmdLoad),46FXMAPFUNC(SEL_COMMAND, GUIDialog_EditViewport::MID_SAVE, GUIDialog_EditViewport::onCmdSave),47};4849// Object implementation50FXIMPLEMENT(GUIDialog_EditViewport, FXDialogBox, GUIDialog_EditViewportMap, ARRAYNUMBER(GUIDialog_EditViewportMap))5152// ===========================================================================53// method definitions54// ===========================================================================5556#ifdef _MSC_VER57#pragma warning(push)58#pragma warning(disable: 4355) // mask warning about "this" in initializers59#endif60GUIDialog_EditViewport::GUIDialog_EditViewport(GUISUMOAbstractView* parent, const char* name) :61FXDialogBox(parent, name, GUIDesignDialogBox, 0, 0, 0, 0, 0, 0, 0, 0),62GUIPersistentWindowPos(this, "VIEWPORT_DIALOG_SETTINGS", false, 20, 40, 150, 150, 100, 20),63myParent(parent) {64// create contents frame65FXVerticalFrame* contentsFrame = new FXVerticalFrame(this, GUIDesignContentsFrame);66// create frame for file icons67FXHorizontalFrame* frameFiles = new FXHorizontalFrame(contentsFrame, GUIDesignHorizontalFrameIcons);68myLoadButton = GUIDesigns::buildFXButton(frameFiles, TL("Load"), "", TL("Load viewport from file"),69GUIIconSubSys::getIcon(GUIIcon::OPEN), this, GUIDialog_EditViewport::MID_LOAD, GUIDesignButtonToolbarWithText);70mySaveButton = GUIDesigns::buildFXButton(frameFiles, TL("Save"), "", TL("Save viewport to file"),71GUIIconSubSys::getIcon(GUIIcon::SAVE), this, GUIDialog_EditViewport::MID_SAVE, GUIDesignButtonToolbarWithText);72// create horizontalframe for zoom elements and OSG73FXHorizontalFrame* editElementsFrame = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);7475// create vertical frame for XYZ values76FXVerticalFrame* lookFromFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);7778// create zoom elements79FXHorizontalFrame* zoomFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);80new FXLabel(zoomFrame, "Zoom:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));81myZoom = new FXRealSpinner(zoomFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPortZoom);82myZoom->setRange(0.0001, 100000);83//myZoom->setNumberFormat(4);8485// create lookFromX elements86FXHorizontalFrame* lookFromXFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);87new FXLabel(lookFromXFrame, "X:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));88myXOff = new FXRealSpinner(lookFromXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);8990// create lookFromY elements91FXHorizontalFrame* lookFromYFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);92new FXLabel(lookFromYFrame, "Y:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));93myYOff = new FXRealSpinner(lookFromYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);9495// create lookFromZ elements96FXHorizontalFrame* lookFromZFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);97new FXLabel(lookFromZFrame, "Z:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));98myZOff = new FXRealSpinner(lookFromZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);99myZOff->setRange(0.12, 100000000);100101// create rotation elements102FXHorizontalFrame* rotationFrame = new FXHorizontalFrame(lookFromFrame, GUIDesignAuxiliarHorizontalFrame);103new FXLabel(rotationFrame, "A:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));104myRotation = new FXRealSpinner(rotationFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);105106// create vertical frame for OSG107FXVerticalFrame* lookAtFrame = new FXVerticalFrame(editElementsFrame, GUIDesignAuxiliarVerticalFrame);108new FXLabel(lookAtFrame, "OSG", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));109110// create lookAtX elements111FXHorizontalFrame* lookAtXFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);112new FXLabel(lookAtXFrame, "LookAtX:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));113myLookAtX = new FXRealSpinner(lookAtXFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);114115// create lookAtY elements116FXHorizontalFrame* lookAtYFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);117new FXLabel(lookAtYFrame, "LookAtY:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));118myLookAtY = new FXRealSpinner(lookAtYFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);119120// create lookAtZ elements121FXHorizontalFrame* lookAtZFrame = new FXHorizontalFrame(lookAtFrame, GUIDesignAuxiliarHorizontalFrame);122new FXLabel(lookAtZFrame, "LookAtZ:", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));123myLookAtZ = new FXRealSpinner(lookAtZFrame, 16, this, MID_CHANGED, GUIDesignSpinDialViewPort);124125// only show LookAt elements for OSG views126if (parent->is3DView()) {127lookAtFrame->show();128} else {129lookAtFrame->hide();130}131132// create buttons ok/cancel133new FXHorizontalSeparator(contentsFrame, GUIDesignHorizontalSeparator);134FXHorizontalFrame* frameButtons = new FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame);135new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);136myOKButton = GUIDesigns::buildFXButton(frameButtons, TL("&OK"), "", TL("accept"), GUIIconSubSys::getIcon(GUIIcon::ACCEPT), this, GUIDialog_EditViewport::MID_OK, GUIDesignButtonDialog);137myCancelButton = GUIDesigns::buildFXButton(frameButtons, TL("&Cancel"), "", TL("close"), GUIIconSubSys::getIcon(GUIIcon::CANCEL), this, GUIDialog_EditViewport::MID_CANCEL, GUIDesignButtonDialog);138new FXHorizontalFrame(frameButtons, GUIDesignAuxiliarHorizontalFrame);139// set dialog icon140setIcon(GUIIconSubSys::getIcon(GUIIcon::EDITVIEWPORT));141loadWindowPos();142}143#ifdef _MSC_VER144#pragma warning(pop)145#endif146147148GUIDialog_EditViewport::~GUIDialog_EditViewport() {}149150151void152GUIDialog_EditViewport::show() {153// If testing mode is enabled, we need to place focus in the Z dial154if (OptionsCont::getOptions().getBool("gui-testing")) {155myLoadButton->setFocus();156} else {157myOKButton->setFocus();158}159FXDialogBox::show();160}161162163long164GUIDialog_EditViewport::onCmdOk(FXObject*, FXSelector, void*) {165myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),166#ifdef HAVE_OSG167Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())168#else169Position::INVALID170#endif171, myRotation->getValue()172);173hide();174return 1;175}176177178long179GUIDialog_EditViewport::onCmdCancel(FXObject*, FXSelector, void*) {180myParent->setViewportFromToRot(myOldLookFrom, myOldLookAt, myOldRotation);181hide();182return 1;183}184185186long187GUIDialog_EditViewport::onCmdChanged(FXObject* o, FXSelector, void*) {188if (o == myZOff) {189myZoom->setValue(myParent->getChanger().zPos2Zoom(myZOff->getValue()));190} else if (o == myZoom) {191if (myParent->is3DView()) {192Position camera(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()), lookAt(myLookAtX->getValue(), myLookAtY->getValue(),193myLookAtZ->getValue());194myParent->zoom2Pos(camera, lookAt, myZoom->getValue());195} else {196myZOff->setValue(myParent->getChanger().zoom2ZPos(myZoom->getValue()));197}198}199myParent->setViewportFromToRot(Position(myXOff->getValue(), myYOff->getValue(), myZOff->getValue()),200#ifdef HAVE_OSG201Position(myLookAtX->getValue(), myLookAtY->getValue(), myLookAtZ->getValue())202#else203Position::INVALID204#endif205, myRotation->getValue()206);207return 1;208}209210211long212GUIDialog_EditViewport::onCmdLoad(FXObject*, FXSelector, void*) {213FXFileDialog opendialog(this, TL("Load Viewport"));214opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));215opendialog.setSelectMode(SELECTFILE_ANY);216opendialog.setPatternList(SUMOXMLDefinitions::ViewSettingsFileExtensions.getMultilineString().c_str());217if (gCurrentFolder.length() != 0) {218opendialog.setDirectory(gCurrentFolder);219}220if (opendialog.execute()) {221gCurrentFolder = opendialog.getDirectory();222GUISettingsHandler handler(opendialog.getFilename().text());223handler.applyViewport(myParent);224setValues(myParent->getChanger().getZoom(), myParent->getChanger().getXPos(), myParent->getChanger().getYPos(), myParent->getChanger().getRotation());225}226return 1;227}228229230long231GUIDialog_EditViewport::onCmdSave(FXObject*, FXSelector, void*) {232FXString file = MFXUtils::getFilename2Write(this, TL("Save Viewport"),233SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str(),234GUIIconSubSys::getIcon(GUIIcon::SAVE), gCurrentFolder);235if (file == "") {236return 1;237}238try {239OutputDevice& dev = OutputDevice::getDevice(file.text(), false);240dev.openTag(SUMO_TAG_VIEWSETTINGS);241writeXML(dev);242dev.closeTag();243dev.close();244} catch (IOError& e) {245FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());246}247return 1;248}249250251void252GUIDialog_EditViewport::writeXML(OutputDevice& dev) {253dev.openTag(SUMO_TAG_VIEWPORT);254dev.writeAttr(SUMO_ATTR_ZOOM, myZoom->getValue());255dev.writeAttr(SUMO_ATTR_X, myXOff->getValue());256dev.writeAttr(SUMO_ATTR_Y, myYOff->getValue());257if (myParent->is3DView()) {258dev.writeAttr(SUMO_ATTR_Z, myZOff->getValue());259}260dev.writeAttr(SUMO_ATTR_ANGLE, myRotation->getValue());261if (myParent->is3DView()) {262if (myLookAtX->getValue() != Position::INVALID.x()) {263dev.writeAttr(SUMO_ATTR_CENTER_X, myLookAtX->getValue());264}265if (myLookAtY->getValue() != Position::INVALID.y()) {266dev.writeAttr(SUMO_ATTR_CENTER_Y, myLookAtY->getValue());267}268if (myLookAtZ->getValue() != Position::INVALID.z()) {269dev.writeAttr(SUMO_ATTR_CENTER_Z, myLookAtZ->getValue());270}271}272dev.closeTag();273}274275276void277GUIDialog_EditViewport::setValues(double zoom, double xoff, double yoff, double rotation) {278myZoom->setValue(zoom);279myXOff->setValue(xoff);280myYOff->setValue(yoff);281myZOff->setValue(myParent->getChanger().zoom2ZPos(zoom));282myRotation->setValue(rotation);283}284285286void287GUIDialog_EditViewport::setValues(const Position& lookFrom, const Position& lookAt, double rotation) {288myXOff->setValue(lookFrom.x());289myYOff->setValue(lookFrom.y());290myZOff->setValue(lookFrom.z());291if (!myParent->is3DView()) {292myZoom->setValue(myParent->getChanger().zPos2Zoom(lookFrom.z()));293}294#ifdef HAVE_OSG295myLookAtX->setValue(lookAt.x());296myLookAtY->setValue(lookAt.y());297myLookAtZ->setValue(lookAt.z());298#else299UNUSED_PARAMETER(lookAt);300#endif301myRotation->setValue(rotation);302}303304305void306GUIDialog_EditViewport::setOldValues(const Position& lookFrom, const Position& lookAt, double rotation) {307setValues(lookFrom, lookAt, rotation);308myOldLookFrom = lookFrom;309myOldLookAt = lookAt;310myOldRotation = rotation;311}312313314bool315GUIDialog_EditViewport::haveGrabbed() const {316return false;317//return myZoom->getDial().grabbed() || myXOff->getDial().grabbed() || myYOff->getDial().grabbed();318}319320321double322GUIDialog_EditViewport::getZoomValue() const {323return myZoom->getValue();324}325326void327GUIDialog_EditViewport::setZoomValue(double zoom) {328myZoom->setValue(zoom);329}330331332void333GUIDialog_EditViewport::saveWindowPos() {334getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "x", getX());335getApp()->reg().writeIntEntry("VIEWPORT_DIALOG_SETTINGS", "y", getY());336}337338339/****************************************************************************/340341342