LCOV - code coverage report
Current view: top level - src/gui - GUISUMOViewParent.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 26.8 % 179 48
Test Date: 2025-11-13 15:38:19 Functions: 44.4 % 18 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-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    GUISUMOViewParent.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Laura Bieker
      19              : /// @author  Andreas Gaubatz
      20              : /// @date    Sept 2002
      21              : ///
      22              : // A single child window which contains a view of the simulation area
      23              : /****************************************************************************/
      24              : 
      25              : #include <utils/common/MsgHandler.h>
      26              : #include <utils/foxtools/MFXCheckableButton.h>
      27              : #include <utils/foxtools/MFXMenuButtonTooltip.h>
      28              : #include <utils/gui/globjects/GUIShapeContainer.h>
      29              : #include <utils/gui/div/GUIGlobalSelection.h>
      30              : #include <utils/gui/div/GUIDesigns.h>
      31              : #include <gui/dialogs/GUIDialog_GLObjChooser.h>
      32              : #include <guisim/GUIPerson.h>
      33              : #include <guisim/GUIEdge.h>
      34              : #include <guisim/GUILane.h>
      35              : #include <guisim/GUINet.h>
      36              : #include <guisim/GUIVehicleControl.h>
      37              : #include <guisim/GUITransportableControl.h>
      38              : 
      39              : #include "GUIViewTraffic.h"
      40              : #include "GUIApplicationWindow.h"
      41              : #include "GUISUMOViewParent.h"
      42              : 
      43              : #include <mesogui/GUIMEVehicleControl.h>
      44              : 
      45              : #include <osgview/GUIOSGView.h>
      46              : 
      47              : #define SPEEDFACTOR_SCALE 100.0
      48              : 
      49              : // ===========================================================================
      50              : // FOX callback mapping
      51              : // ===========================================================================
      52              : FXDEFMAP(GUISUMOViewParent) GUISUMOViewParentMap[] = {
      53              :     FXMAPFUNC(SEL_COMMAND,  MID_MAKESNAPSHOT,   GUISUMOViewParent::onCmdMakeSnapshot),
      54              :     //        FXMAPFUNC(SEL_COMMAND,  MID_ALLOWROTATION,  GUISUMOViewParent::onCmdAllowRotation),
      55              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,      GUISUMOViewParent::onCmdLocate),
      56              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_E_LOCATEEDGE,          GUISUMOViewParent::onCmdLocate),
      57              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,       GUISUMOViewParent::onCmdLocate),
      58              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_P_LOCATEPERSON,        GUISUMOViewParent::onCmdLocate),
      59              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_C_LOCATECONTAINER,     GUISUMOViewParent::onCmdLocate),
      60              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_T_LOCATETLS,           GUISUMOViewParent::onCmdLocate),
      61              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,    GUISUMOViewParent::onCmdLocate),
      62              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_O_LOCATEPOI,           GUISUMOViewParent::onCmdLocate),
      63              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_L_LOCATEPOLY,          GUISUMOViewParent::onCmdLocate),
      64              : 
      65              :     FXMAPFUNC(SEL_UPDATE,   MID_SPEEDFACTOR,    GUISUMOViewParent::onUpdSpeedFactor),
      66              :     FXMAPFUNC(SEL_COMMAND,  MID_SPEEDFACTOR,    GUISUMOViewParent::onCmdSpeedFactor),
      67              :     FXMAPFUNC(SEL_COMMAND,  MID_SIMSTEP,        GUISUMOViewParent::onSimStep),
      68              : 
      69              : };
      70              : 
      71              : // Object implementation
      72     16637403 : FXIMPLEMENT(GUISUMOViewParent, GUIGlChildWindow, GUISUMOViewParentMap, ARRAYNUMBER(GUISUMOViewParentMap))
      73              : 
      74              : 
      75              : // ===========================================================================
      76              : // member method definitions
      77              : // ===========================================================================
      78         7547 : GUISUMOViewParent::GUISUMOViewParent(FXMDIClient* p, FXMDIMenu* mdimenu,
      79              :                                      const FXString& name,
      80              :                                      GUIMainWindow* parentWindow,
      81              :                                      FXIcon* ic, FXuint opts,
      82         7547 :                                      FXint x, FXint y, FXint w, FXint h) :
      83         7547 :     GUIGlChildWindow(p, parentWindow, mdimenu, name, nullptr, ic, opts, x, y, w, h) {
      84         7547 :     buildSpeedControlToolbar();
      85         7547 :     myGUIMainWindowParent->addGLChild(this);
      86         7547 : }
      87              : 
      88              : 
      89              : GUISUMOAbstractView*
      90         7547 : GUISUMOViewParent::init(FXGLCanvas* share, GUINet& net, GUISUMOViewParent::ViewType type) {
      91         7547 :     switch (type) {
      92         7111 :         default:
      93              :         case VIEW_2D_OPENGL:
      94         7111 :             myView = new GUIViewTraffic(myChildWindowContentFrame, *myGUIMainWindowParent, this, net, myGUIMainWindowParent->getGLVisual(), share);
      95         7111 :             break;
      96              : #ifdef HAVE_OSG
      97          436 :         case VIEW_3D_OSG:
      98          436 :             myView = new GUIOSGView(myChildWindowContentFrame, *myGUIMainWindowParent, this, net, myGUIMainWindowParent->getGLVisual(), share);
      99          436 :             break;
     100              : #endif
     101              :     }
     102         7547 :     myView->buildViewToolBars(this);
     103         7547 :     if (myGUIMainWindowParent->isGaming()) {
     104            0 :         myStaticNavigationToolBar->hide();
     105              :     }
     106         7547 :     return myView;
     107              : }
     108              : 
     109              : 
     110        15062 : GUISUMOViewParent::~GUISUMOViewParent() {
     111         7531 :     myGUIMainWindowParent->removeGLChild(this);
     112        15062 : }
     113              : 
     114              : 
     115              : void
     116            0 : GUISUMOViewParent::setToolBarVisibility(const bool value) {
     117            0 :     if (value) {
     118            0 :         myStaticNavigationToolBar->show();
     119              :     } else {
     120            0 :         myStaticNavigationToolBar->hide();
     121              :     }
     122            0 : }
     123              : 
     124              : 
     125              : void
     126            0 : GUISUMOViewParent::eraseGLObjChooser(GUIDialog_GLObjChooser* GLObjChooser) {
     127            0 :     myGLObjChooser[GLObjChooser->getMessageId()] = nullptr;
     128            0 : }
     129              : 
     130              : 
     131              : long
     132            0 : GUISUMOViewParent::onCmdMakeSnapshot(FXObject* sender, FXSelector, void*) {
     133            0 :     MFXCheckableButton* button = dynamic_cast<MFXCheckableButton*>(sender);
     134              :     // check if cast was successfully
     135            0 :     if (button) {
     136            0 :         if (button->amChecked()) {
     137            0 :             myView->endSnapshot();
     138            0 :             button->setChecked(false);
     139            0 :             return 1;
     140              :         }
     141              :         // get the new file name
     142            0 :         FXFileDialog opendialog(this, TL("Save Snapshot"));
     143            0 :         opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::CAMERA));
     144            0 :         opendialog.setSelectMode(SELECTFILE_ANY);
     145              : #ifdef HAVE_FFMPEG
     146            0 :         opendialog.setPatternList(SUMOXMLDefinitions::ImageVideoFileExtensions.getMultilineString().c_str());
     147              : #else
     148              :         opendialog.setPatternList(SUMOXMLDefinitions::ImageFileExtensions.getMultilineString().c_str());
     149              : #endif
     150            0 :         if (gCurrentFolder.length() != 0) {
     151            0 :             opendialog.setDirectory(gCurrentFolder);
     152              :         }
     153            0 :         if (!opendialog.execute() || !MFXUtils::userPermitsOverwritingWhenFileExists(this, opendialog.getFilename())) {
     154              :             return 1;
     155              :         }
     156            0 :         gCurrentFolder = opendialog.getDirectory();
     157            0 :         std::string file = opendialog.getFilename().text();
     158            0 :         if (file.find(".") == std::string::npos) {
     159            0 :             file.append(".png");
     160            0 :             WRITE_MESSAGE(TL("No file extension was specified - saving Snapshot as PNG."));
     161              :         }
     162            0 :         std::string error = myView->makeSnapshot(file);
     163            0 :         if (error == "video") {
     164            0 :             button->setChecked(!button->amChecked());
     165            0 :         } else if (error != "") {
     166            0 :             FXMessageBox::error(this, MBOX_OK, TL("Saving failed."), "%s", error.c_str());
     167              :         } else {
     168            0 :             WRITE_MESSAGE(TL("Snapshot successfully saved!"));
     169              :         }
     170            0 :     }
     171              :     return 1;
     172              : }
     173              : 
     174              : 
     175              : std::vector<GUIGlID>
     176            0 : GUISUMOViewParent::getObjectIDs(int messageId) const {
     177            0 :     switch (messageId) {
     178            0 :         case MID_HOTKEY_SHIFT_J_LOCATEJUNCTION:
     179            0 :             return static_cast<GUINet*>(GUINet::getInstance())->getJunctionIDs(myGUIMainWindowParent->listInternal());
     180            0 :         case MID_HOTKEY_SHIFT_E_LOCATEEDGE:
     181            0 :             return GUIEdge::getIDs(myGUIMainWindowParent->listInternal());
     182              :         case MID_HOTKEY_SHIFT_V_LOCATEVEHICLE: {
     183              :             std::vector<GUIGlID> vehicles;
     184            0 :             if (MSGlobals::gUseMesoSim) {
     185            0 :                 static_cast<GUIMEVehicleControl*>(static_cast<GUINet*>(MSNet::getInstance())->getGUIMEVehicleControl())->insertVehicleIDs(vehicles);
     186              :             } else {
     187            0 :                 static_cast<GUIVehicleControl&>(MSNet::getInstance()->getVehicleControl()).insertVehicleIDs(
     188            0 :                     vehicles, myGUIMainWindowParent->listParking(), myGUIMainWindowParent->listTeleporting());
     189              :             }
     190              :             return vehicles;
     191            0 :         }
     192              :         case MID_HOTKEY_SHIFT_P_LOCATEPERSON: {
     193              :             std::vector<GUIGlID> persons;
     194            0 :             static_cast<GUITransportableControl&>(MSNet::getInstance()->getPersonControl()).insertIDs(persons);
     195              :             return persons;
     196            0 :         }
     197              :         case MID_HOTKEY_SHIFT_C_LOCATECONTAINER: {
     198              :             // get containers
     199              :             std::vector<GUIGlID> containers;
     200            0 :             static_cast<GUITransportableControl&>(MSNet::getInstance()->getContainerControl()).insertIDs(containers);
     201              :             return containers;
     202            0 :         }
     203            0 :         case MID_HOTKEY_SHIFT_T_LOCATETLS:
     204            0 :             return static_cast<GUINet*>(GUINet::getInstance())->getTLSIDs();
     205            0 :         case MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL:
     206            0 :             return GUIGlObject_AbstractAdd::getIDList(GLO_ADDITIONALELEMENT);
     207            0 :         case MID_HOTKEY_SHIFT_O_LOCATEPOI:
     208            0 :             return static_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPOIIds();
     209            0 :         case MID_HOTKEY_SHIFT_L_LOCATEPOLY:
     210            0 :             return static_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPolygonIDs();
     211            0 :         default:
     212            0 :             throw ProcessError(TL("Unknown Message ID in onCmdLocate"));
     213              :     }
     214              : }
     215              : 
     216              : 
     217              : long
     218            0 : GUISUMOViewParent::onCmdLocate(FXObject*, FXSelector sel, void*) {
     219            0 :     int messageId = FXSELID(sel);
     220            0 :     if (myGLObjChooser.count(messageId) == 0 || myGLObjChooser[messageId] == nullptr) {
     221              :         FXIcon* icon = nullptr;
     222            0 :         std::string titleString = "";
     223            0 :         switch (messageId) {
     224            0 :             case MID_HOTKEY_SHIFT_J_LOCATEJUNCTION:
     225            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEJUNCTION);
     226            0 :                 titleString = TL("Junction Chooser");
     227              :                 break;
     228            0 :             case MID_HOTKEY_SHIFT_E_LOCATEEDGE:
     229            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEEDGE);
     230            0 :                 titleString = TL("Edge Chooser");
     231              :                 break;
     232            0 :             case MID_HOTKEY_SHIFT_V_LOCATEVEHICLE:
     233            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEVEHICLE);
     234            0 :                 titleString = TL("Vehicle Chooser");
     235              :                 break;
     236            0 :             case MID_HOTKEY_SHIFT_P_LOCATEPERSON:
     237            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEPERSON);
     238            0 :                 titleString = TL("Person Chooser");
     239              :                 break;
     240            0 :             case MID_HOTKEY_SHIFT_C_LOCATECONTAINER:
     241            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATECONTAINER);
     242            0 :                 titleString = TL("Container Chooser");
     243              :                 break;
     244            0 :             case MID_HOTKEY_SHIFT_T_LOCATETLS:
     245            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATETLS);
     246            0 :                 titleString = TL("Traffic Lights Chooser");
     247              :                 break;
     248            0 :             case MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL:
     249            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEADD);
     250            0 :                 titleString = TL("Additional Objects Chooser");
     251              :                 break;
     252            0 :             case MID_HOTKEY_SHIFT_O_LOCATEPOI:
     253            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEPOI);
     254            0 :                 titleString = TL("POI Chooser");
     255              :                 break;
     256            0 :             case MID_HOTKEY_SHIFT_L_LOCATEPOLY:
     257            0 :                 icon = GUIIconSubSys::getIcon(GUIIcon::LOCATEPOLY);
     258            0 :                 titleString = TL("Polygon Chooser");
     259              :                 break;
     260            0 :             default:
     261            0 :                 throw ProcessError(TL("Unknown Message ID in onCmdLocate"));
     262              :         }
     263              : 
     264            0 :         myGLObjChooser[messageId] = new GUIDialog_GLObjChooser(this, messageId, icon, titleString.c_str(), getObjectIDs(messageId), GUIGlObjectStorage::gIDStorage);
     265              : 
     266              :     } else {
     267            0 :         myGLObjChooser[messageId]->restore();
     268            0 :         myGLObjChooser[messageId]->setFocus();
     269            0 :         myGLObjChooser[messageId]->raise();
     270              :     }
     271            0 :     myLocatorPopup->popdown();
     272            0 :     myLocatorButton->killFocus();
     273            0 :     myLocatorPopup->update();
     274            0 :     return 1;
     275              : }
     276              : 
     277              : 
     278              : long
     279      6469704 : GUISUMOViewParent::onSimStep(FXObject*, FXSelector, void*) {
     280      6469704 :     myView->update();
     281      6469704 :     myView->checkSnapshots();
     282      6469704 :     return 1;
     283              : }
     284              : 
     285              : 
     286              : bool
     287            0 : GUISUMOViewParent::isSelected(GUIGlObject* o) const {
     288              :     GUIGlObjectType type = o->getType();
     289            0 :     if (gSelected.isSelected(type, o->getGlID())) {
     290              :         return true;
     291            0 :     } else if (type == GLO_EDGE) {
     292            0 :         GUIEdge* edge = dynamic_cast<GUIEdge*>(o);
     293            0 :         if (edge == nullptr) {
     294              :             // hmph, just some security stuff
     295              :             return false;
     296              :         }
     297              :         const std::vector<MSLane*>& lanes = edge->getLanes();
     298            0 :         for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
     299            0 :             GUILane* l = dynamic_cast<GUILane*>(*j);
     300            0 :             if (l != nullptr && gSelected.isSelected(GLO_LANE, l->getGlID())) {
     301              :                 return true;
     302              :             }
     303              :         }
     304              :         return false;
     305              :     } else {
     306              :         return false;
     307              :     }
     308              : }
     309              : 
     310              : 
     311              : long
     312            0 : GUISUMOViewParent::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
     313            0 :     myView->onKeyPress(o, sel, ptr);
     314            0 :     return 0;
     315              : }
     316              : 
     317              : 
     318              : long
     319            0 : GUISUMOViewParent::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
     320            0 :     myView->onKeyRelease(o, sel, ptr);
     321            0 :     return 0;
     322              : }
     323              : 
     324              : 
     325              : void
     326         7547 : GUISUMOViewParent::buildSpeedControlToolbar() {
     327         7547 :     auto toolbar = myGripNavigationToolbar ? myGripNavigationToolbar : myStaticNavigationToolBar;
     328         7547 :     new FXVerticalSeparator(toolbar, GUIDesignVerticalSeparator);
     329              : 
     330              :     //myToolBarDragSpeed = new FXToolBarShell(this, GUIDesignToolBar);
     331              :     //myToolBarSpeed = new FXToolBar(toolbar, myToolBarDragSpeed, GUIDesignToolBarRaisedSameTop);
     332              :     //mySpeedFactorSlider = new FXSlider(myToolBarSpeed, this, MID_SPEEDFACTOR, LAYOUT_FIX_WIDTH | SLIDER_ARROW_UP | SLIDER_TICKS_TOP, 0, 0, 300, 10, 0, 0, 5, 0);
     333         7547 :     mySpeedFactorSlider = new FXSlider(toolbar, this, MID_SPEEDFACTOR, LAYOUT_FIX_WIDTH | SLIDER_ARROW_UP | SLIDER_TICKS_TOP, 0, 0, 200, 10, 0, 0, 5, 0);
     334         7547 :     mySpeedFactorSlider->setRange(0, 200);
     335         7547 :     mySpeedFactorSlider->setHeadSize(10);
     336         7547 :     mySpeedFactorSlider->setIncrement(1);
     337         7547 :     mySpeedFactorSlider->setTickDelta(100);
     338         7547 :     mySpeedFactorSlider->setValue(100);
     339        15094 :     mySpeedFactorSlider->setHelpText("Control speedFactor of tracked object");
     340              :     //mySpeedFactorSlider->hide();
     341         7547 : }
     342              : 
     343              : long
     344            0 : GUISUMOViewParent::onCmdSpeedFactor(FXObject*, FXSelector, void*) {
     345            0 :     if (myView != nullptr && myView->getTrackedID() != GUIGlObject::INVALID_ID) {
     346            0 :         GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(myView->getTrackedID());
     347            0 :         if (o != nullptr) {
     348            0 :             const double speedFactor = mySpeedFactorSlider->getValue() / SPEEDFACTOR_SCALE;
     349            0 :             if (o->getType() == GLO_VEHICLE) {
     350            0 :                 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(o);
     351            0 :                 veh->setChosenSpeedFactor(speedFactor);
     352              :             } else if (o->getType() == GLO_PERSON) {
     353              :                 //MSPerson* person = dynamic_cast<MSPerson*>(o);
     354              :                 //person->setChosenSpeedFactor(speedFactor);
     355              :             }
     356            0 :             mySpeedFactorSlider->setTipText(toString(speedFactor).c_str());
     357              :         }
     358              : 
     359              :     }
     360            0 :     return 1;
     361              : }
     362              : 
     363              : long
     364       294694 : GUISUMOViewParent::onUpdSpeedFactor(FXObject* sender, FXSelector, void* ptr) {
     365       294694 :     bool disable = myView == nullptr || myView->getTrackedID() == GUIGlObject::INVALID_ID;
     366       294698 :     sender->handle(this, FXSEL(SEL_COMMAND, disable ? ID_DISABLE : ID_ENABLE), ptr);
     367       294694 :     if (disable) {
     368       294690 :         mySpeedFactorSlider->hide();
     369              :     } else {
     370            4 :         GUIGlObject* o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(myView->getTrackedID());
     371            4 :         if (o != nullptr) {
     372            4 :             if (o->getType() == GLO_VEHICLE) {
     373            4 :                 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(o);
     374            4 :                 mySpeedFactorSlider->setValue((int)(veh->getChosenSpeedFactor() * SPEEDFACTOR_SCALE));
     375            0 :             } else if (o->getType() == GLO_PERSON) {
     376            0 :                 MSPerson* person = dynamic_cast<MSPerson*>(o);
     377            0 :                 mySpeedFactorSlider->setValue((int)(person->getChosenSpeedFactor() * SPEEDFACTOR_SCALE));
     378              :             }
     379            4 :             mySpeedFactorSlider->show();
     380              :         } else {
     381            0 :             myView->stopTrack();
     382            0 :             mySpeedFactorSlider->hide();
     383              :         }
     384              :     }
     385       294694 :     return 1;
     386              : }
     387              : 
     388              : 
     389              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1