/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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 GUIApplicationWindow.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Christian Roessel17/// @author Michael Behrisch18/// @date Sept 200219///20// The main window of the SUMO-gui.21/****************************************************************************/22#pragma once23#include <config.h>2425#include <utils/foxtools/MFXRecentNetworks.h>26#include <utils/foxtools/MFXInterThreadEventClient.h>27#include <utils/gui/windows/GUIMainWindow.h>2829#include "GUISUMOViewParent.h"303132// ===========================================================================33// class declarations34// ===========================================================================3536class Command;37class GUILoadThread;38class GUIRunThread;39class GUIMessageWindow;40class GUIEvent;41class GUIParameterTracker;42class GUIParameterTableWindow;43class GUIDialog_Breakpoints;44class MFXLCDLabel;45class MFXLabelTooltip;464748// ===========================================================================49// class definition50// ===========================================================================51/**52* @class GUIApplicationWindow53* @brief The main window of the SUMO-gui.54*55* Beside views on the simulation, shown within a MDI-window, the main window56* may also have some further views (children) assigned which are stored57* within a separate list.58*/59class GUIApplicationWindow : public GUIMainWindow, public MFXInterThreadEventClient {60// FOX-declarations61FXDECLARE(GUIApplicationWindow)6263public:64/// @brief Constructor65GUIApplicationWindow(FXApp* a);6667/// @brief Destructor68virtual ~GUIApplicationWindow();6970/// @name FOX-interactions71/// {7273/// @brief Creates the main window (required by FOX)74virtual void create();7576/// @brief Detaches the tool/menu bar77virtual void detach();7879/// @}8081/// @brief config or net on startup82void loadOnStartup(const bool wait = false);8384/// @brief get run thread85GUIRunThread* getRunner();8687/// @brief build dependt88void dependentBuild(const bool isLibsumo);8990/// @brief set status bar text91void setStatusBarText(const std::string& text);9293/// @brief add recent network to recent file list94void addRecentNetwork(const FX::FXString& f);9596/// @brief add recent config to recent file list97void addRecentConfig(const FX::FXString& f);9899/// @brief get build GLCanvas100FXGLCanvas* getBuildGLCanvas() const;101102/// @brief get current simulation time103SUMOTime getCurrentSimTime() const;104105/// @brief get tracker interval106double getTrackerInterval() const;107108/// @brief get default cursor109FXCursor* getDefaultCursor();110111/// @name Inter-thread event handling112/// @{113114/// @brief a certain event ocurred115virtual void eventOccurred();116117/// @brief called when event "simulation loaded" ocurred118void handleEvent_SimulationLoaded(GUIEvent* e);119120/// @brief called when event "simulation step" ocurred121void handleEvent_SimulationStep(GUIEvent* e);122123/// @brief called when event "message" ocurred124void handleEvent_Message(GUIEvent* e);125126/// @brief called when event "simulation ended" ocurred127void handleEvent_SimulationEnded(GUIEvent* e);128129/// @}130131/// @name FOX-callbacks132/// @{133134/// @brief Called on menu File->New Window135long onCmdNewWindow(FXObject*, FXSelector, void*);136137/// @brief Called on menu File->Open Configuration138long onCmdOpenConfiguration(FXObject*, FXSelector, void*);139140/// @brief Called on menu File->Open Network141long onCmdOpenNetwork(FXObject*, FXSelector, void*);142143/// @brief Called on menu File->Load Shapes144long onCmdOpenShapes(FXObject*, FXSelector, void*);145146/// @brief Called on menu File->Load EdgeData147long onCmdOpenEdgeData(FXObject*, FXSelector, void*);148149/// @brief Called on reload150long onCmdReload(FXObject*, FXSelector, void*);151152/// @brief Called on quick-reload153long onCmdQuickReload(FXObject*, FXSelector, void*);154155/// @brief Called on opening a recent file156long onCmdOpenRecent(FXObject*, FXSelector, void*);157158/// @brief Called on menu File->Close159long onCmdSaveConfig(FXObject*, FXSelector, void*);160161/// @brief Called on menu File->Close162long onCmdClose(FXObject*, FXSelector, void*);163164/// @brief Called by FOX if the application shall be closed (Called either by FileMenu->Quit, the normal close-menu or SIGINT)165long onCmdQuit(FXObject*, FXSelector, void*);166167/// @brief Called on menu Edit->Edit Chosen168long onCmdEditChosen(FXObject*, FXSelector, void*);169170/// @brief Called on menu Edit->Edit Breakpoints171long onCmdEditBreakpoints(FXObject*, FXSelector, void*);172173/// @brief Called on menu Edit->Visualization174long onCmdEditViewScheme(FXObject*, FXSelector, void*);175176/// @brief Called on menu Edit->Viewport177long onCmdEditViewport(FXObject*, FXSelector, void*);178179/// @brief called if the user selects help->Documentation180long onCmdHelp(FXObject* sender, FXSelector sel, void* ptr);181182/// @brief called if the user selects help->Changelog183long onCmdChangelog(FXObject* sender, FXSelector sel, void* ptr);184185/// @brief called if the user selects help->Hotkeys186long onCmdHotkeys(FXObject* sender, FXSelector sel, void* ptr);187188/// @brief called if the user selects help->Tutorial189long onCmdTutorial(FXObject* sender, FXSelector sel, void* ptr);190191/// @brief Called on menu Edit->open in Netedit192long onCmdOpenInNetedit(FXObject*, FXSelector, void*);193194/// @brief Opens the application settings menu (Settings->Application Settings...)195long onCmdAppSettings(FXObject*, FXSelector, void*);196197/// @brief Toggle gaming mode198long onCmdGaming(FXObject*, FXSelector, void*);199200/// @brief Toggle draw junction shape201long onCmdToggleDrawJunctionShape(FXObject*, FXSelector, void*);202203/// @brief Toggle draw junction shape204long onCmdToggleSecondaryShape(FXObject*, FXSelector, void*);205206/// @brief Toggle full screen mode207long onCmdFullScreen(FXObject*, FXSelector, void*);208209/// @brief Toggle listing of internal structures210long onCmdListInternal(FXObject*, FXSelector, void*);211212/// @brief Toggle listing of parking vehicles213long onCmdListParking(FXObject*, FXSelector, void*);214215/// @brief Toggle listing of teleporting vehicles216long onCmdListTeleporting(FXObject*, FXSelector, void*);217218/// @brief Shows the feedback dialog219long onCmdFeedback(FXObject*, FXSelector, void*);220221/// @brief Shows the about dialog222long onCmdAbout(FXObject*, FXSelector, void*);223224/// @brief Shows the Hall of Fame dialog225long onCmdHallOfFame(FXObject*, FXSelector, void*);226227/// @brief Called on "play"228long onCmdStart(FXObject*, FXSelector, void*);229230/// @brief Called on "stop"231long onCmdStop(FXObject*, FXSelector, void*);232233/// @brief Called on "step"234long onCmdStep(FXObject*, FXSelector, void*);235236/// @brief Called on "save state"237long onCmdSaveState(FXObject*, FXSelector, void*);238239/// @brief Called on "save state"240long onCmdLoadState(FXObject*, FXSelector, void*);241242/// @brief Called on "time toggle"243long onCmdTimeToggle(FXObject*, FXSelector, void*);244245/// @brief Called on "delay inc"246long onCmdDelayInc(FXObject*, FXSelector, void*);247248/// @brief Called on "delay dec"249long onCmdDelayDec(FXObject*, FXSelector, void*);250251/// @brief Called on "delay toggle"252long onCmdDelayToggle(FXObject*, FXSelector, void*);253254/// @brief Called on "demand scale"255long onCmdDemandScale(FXObject*, FXSelector, void*);256257/// @brief Called if a new view shall be opened (2D view)258long onCmdNewView(FXObject*, FXSelector, void*);259260#ifdef HAVE_OSG261/// @brief Called if a new 3D view shall be opened262long onCmdNewOSG(FXObject*, FXSelector, void*);263#endif264265/// @brief Determines whether opening is enabled266long onUpdOpen(FXObject*, FXSelector, void*);267268/// @brief Determines whether reloading is enabled269long onUpdReload(FXObject*, FXSelector, void*);270271/// @brief Determines whether opening a recent file is enabled272long onUpdOpenRecent(FXObject*, FXSelector, void*);273274/// @brief Determines whether adding a view is enabled275long onUpdAddView(FXObject*, FXSelector, void*);276277/// @brief Determines whether "play" is enabled278long onUpdStart(FXObject* sender, FXSelector, void* ptr);279280/// @brief Determines whether "stop" is enabled281long onUpdStop(FXObject*, FXSelector, void*);282283/// @brief Determines whether "step" is enabled284long onUpdStep(FXObject*, FXSelector, void*);285286/// @brief Determines whether some buttons which require an active network may be shown287long onUpdNeedsNetwork(FXObject*, FXSelector, void*);288289/// @brief Determines whether some buttons which require an sumoConfig may be shown290long onUpdNeedsSumoConfig(FXObject*, FXSelector, void*);291292/// @brief Determines whether traci is active293long onUpdTraCIStatus(FXObject*, FXSelector, void*);294295/// @brief Called if the message window shall be cleared296long onCmdClearMsgWindow(FXObject*, FXSelector, void*);297298/// @brief Called to set a breakpoint via hotkey299long onCmdBreakpoint(FXObject*, FXSelector, void*);300301/// @brief Called to set an early breakpoint via hotkey302long onCmdBreakpointEarly(FXObject*, FXSelector, void*);303304/// @brief Called on menu commands from the Locator menu305long onCmdLocate(FXObject*, FXSelector, void*);306307/// @brief Called on commands from the statistic buttons308long onCmdShowStats(FXObject*, FXSelector, void*);309310/// @brief Called on an event from the loading thread311long onLoadThreadEvent(FXObject*, FXSelector, void*);312313/// @brief Called on an event from the simulation thread314long onRunThreadEvent(FXObject*, FXSelector, void*);315316/// @brief Somebody wants our clipped text317long onClipboardRequest(FXObject* sender, FXSelector sel, void* ptr);318319/// @brief called when a key is pressed320long onKeyPress(FXObject* o, FXSelector sel, void* data);321322/// @brief called when a key is released323long onKeyRelease(FXObject* o, FXSelector sel, void* data);324325/// @}326327/// @brief Returns the simulation delay in miliseconds328virtual double getDelay() const;329330/// @brief Sets the delay of the parent application in milliseconds331virtual void setDelay(double delay);332333/// @brief Sets the breakpoints of the parent application334virtual void setBreakpoints(const std::vector<SUMOTime>& breakpoints);335336/// @brief Adds the given breakpoint337void addBreakpoint(SUMOTime time);338339/// @brief Sends an event from the application thread to the GUI and waits until it is handled340virtual void sendBlockingEvent(GUIEvent* event);341342/// @brief retrieve list of breakpoints343const std::vector<SUMOTime> retrieveBreakpoints() const;344345/// @brief erase current breakpoint dialog346void eraseBreakpointDialog();347348/// @brief register custom hotkey action349void addHotkey(int key, Command* press, Command* release);350351protected:352/// @brief FOX need this353FOX_CONSTRUCTOR(GUIApplicationWindow)354355/// @brief add the given menuPane to windows Menu356virtual void addToWindowsMenu(FXMenuPane* menuPane);357358/// Builds the menu bar359virtual void fillMenuBar();360361/// Builds the tool bar362virtual void buildToolBars();363364/// @brief build recent networks365void buildRecentNetworks(FXMenuPane* fileMenu, FXMenuPane* fileMenuRecentNetworks);366367/// @brief build recent configs368void buildRecentConfigs(FXMenuPane* fileMenu, FXMenuPane* fileMenuRecentConfigs);369370/// @brief the name of the simulation371std::string myName;372373/// @brief the thread that loads simulations374GUILoadThread* myLoadThread = nullptr;375376/// @brief the thread that runs simulations377GUIRunThread* myRunThread = nullptr;378379/// @brief the information whether the simulation was started before380bool myWasStarted = false;381382/// @brief The current view number383int myViewNumber;384385/// @brief information whether the gui is currently loading and the load-options shall be greyed out386bool myAmLoading = false;387388/// @brief whether we are reloading the simulation389bool myIsReload = false;390391/// @brief last modification time of the gui setting file392long long myGuiSettingsFileMTime = -2;393394/// @brief the submenus395FXMenuPane* myFileMenu = nullptr,396*myEditMenu = nullptr,397*mySelectByPermissions = nullptr,398*mySettingsMenu = nullptr,399*myLocatorMenu = nullptr,400*myControlMenu = nullptr,401*myWindowMenu = nullptr,402*myHelpMenu = nullptr;403404/// @brief FXMenu pane for recent networks405FXMenuPane* myFileMenuRecentNetworks = nullptr;406407/// @brief FXMenu pane for recent configs408FXMenuPane* myFileMenuRecentConfigs = nullptr;409410/// @brief the menu cascades411FXMenuCascade* mySelectLanesMenuCascade = nullptr;412413/// @brief menuCheck for enable/disable load additionals in netedit414FXMenuCheck* myLoadAdditionalsInNetedit = nullptr;415416/// @brief menuCheck for enable/disable load demand elements in netedit417FXMenuCheck* myLoadDemandInNetedit = nullptr;418419/// @brief menuCommand for opening simulation/network in netedit420FXMenuCommand* myOpenInNetedit = nullptr;421/// @brief menuCommand for opening only the network in netedit422FXMenuCommand* myOpenNetInNetedit = nullptr;423424/// @brief Buttons showing and running values and triggering statistic windows425std::vector<FXButton*> myStatButtons;426427/// @brief A window to display messages, warnings and error in428GUIMessageWindow* myMessageWindow = nullptr;429430/// @brief The splitter that divides the main window into views and the log window431FXSplitter* myMainSplitter = nullptr;432433/// @brief for some menu detaching fun434FXToolBarShell* myToolBarDrag1 = nullptr,435*myToolBarDrag2 = nullptr,436*myToolBarDrag3 = nullptr,437*myToolBarDrag4 = nullptr,438*myToolBarDrag5 = nullptr,439*myMenuBarDrag = nullptr,440*myToolBarDrag8 = nullptr;441442/// @brief the simulation delay in milliseconds443double mySimDelay = 0.;444445/// @brief Simulation delay target446FXDataTarget* mySimDelayTarget = nullptr;447448/// @brief Simulation delay spinner449FXRealSpinner* mySimDelaySpinner = nullptr;450451/// @brief Simulation delay slider452FXSlider* mySimDelaySlider = nullptr;453454/// @brief the demand scale label455MFXLabelTooltip* myScaleTrafficTooltip = nullptr;456457/// @brief the demand scale458FXRealSpinner* myDemandScaleSpinner = nullptr;459460/// @brief The alternate simulation delay in milliseconds for toggling461double myAlternateSimDelay = 0;462463/// @brief List of got requests464MFXSynchQue<GUIEvent*> myEvents;465466/// @brief The menu used for the MDI-windows467FXMDIMenu* myMDIMenu = nullptr;468469/// @brief The application menu bar470FXMenuBar* myMenuBar = nullptr;471472/// @brief The application tool bar473FXToolBar* myToolBar1 = nullptr,474*myToolBar2 = nullptr,475*myToolBar3 = nullptr,476*myToolBar4 = nullptr,477*myToolBar5 = nullptr,478*myToolBar8 = nullptr;479480/// @brief the simulation step display481MFXLCDLabel* myLCDLabel = nullptr;482483/// @brief io-event with the load-thread484FXEX::MFXThreadEvent myLoadThreadEvent;485486/// @brief io-event with the run-thread487FXEX::MFXThreadEvent myRunThreadEvent;488489/// @brief List of recent networks490MFXRecentNetworks myRecentNetworks;491492/// @brief List of recent configs493MFXRecentNetworks myRecentConfigs;494495/// @brief flag to mark if GUIApplicationWIndow has depend build496bool hadDependentBuild = false;497498/// @brief whether to show time as hour:minute:second499bool myShowTimeAsHMS = false;500501/// @brief whether the simulation end was already announced502bool myHaveNotifiedAboutSimEnd = false;503504/// @brief the mutex for the waiting semaphore505FXMutex myEventMutex;506507/// @brief the semaphore when waiting for event completion508FXCondition myEventCondition;509510/// @brief menu checkbox to activate game mode511FXMenuCheck* myGamingModeCheckbox;512513/// @name game related things514/// {515516/// @brief random list of jam sounds517RandomDistributor<std::string> myJamSounds;518519/// @brief random list of collision sounds520RandomDistributor<std::string> myCollisionSounds;521522/// @brief waiting time after which vehicles trigger jam sounds523double myJamSoundTime = 60;524525/// @brief A random number generator used to choose a gaming sound526static std::mt19937 myGamingRNG;527528/// @brief previous collision number529int myPreviousCollisionNumber = 0;530531/// @brief flag for enable TLS gameMode532bool myTLSGame = false;533534/// @brief waiting time label535MFXLCDLabel* myWaitingTimeLabel = nullptr;536537/// @brief waiting time538SUMOTime myWaitingTime = 0;539540/// @brief time loss label541MFXLCDLabel* myTimeLossLabel = nullptr;542543/// @brief time loss544SUMOTime myTimeLoss = 0;545546/// @brief total distance label547MFXLCDLabel* myTotalDistanceLabel = nullptr;548549/// @brief total distance550double myTotalDistance = 0;551552/// @brief emergency vehicle label553MFXLCDLabel* myEmergencyVehicleLabel = nullptr;554555/// @brief emergency vehicle count556SUMOTime myEmergencyVehicleCount = 0;557558/// @brief toolbars used in game559FXToolBar* myToolBar6 = nullptr,560*myToolBar7 = nullptr,561*myToolBar9 = nullptr,562*myToolBar10 = nullptr;563564/// @brief toolbars shell used in game565FXToolBarShell* myToolBarDrag6 = nullptr,566*myToolBarDrag7 = nullptr,567*myToolBarDrag9 = nullptr,568*myToolBarDrag10 = nullptr;569////}570571/// @brief last time the simulation view was redrawn due to a simStep572long myLastStepEventMillis;573574/// @brief custom hotkeys pressed575std::map<int, Command*> myHotkeyPress;576577/// @brief custom hotkeys released578std::map<int, Command*> myHotkeyRelease;579580/// @brief breakpoint dialog581GUIDialog_Breakpoints* myBreakpointDialog = nullptr;582583std::stringstream* myDynamicSelection = nullptr;584585private:586/// @brief starts to load a simulation587void loadConfigOrNet(const std::string& file);588589/// @brief this method closes all windows and deletes the current simulation590void closeAllWindows();591592/// @brief updates the simulation time display593void updateTimeLCD(SUMOTime time);594595/// @brief update LCD timer tooltip596void updateTimeLCDTooltip();597598/// @brief opens a new simulation display599GUISUMOAbstractView* openNewView(GUISUMOViewParent::ViewType vt = GUISUMOViewParent::VIEW_2D_OPENGL, std::string caption = "");600601/// @brief handles additional game-related events602void checkGamingEvents();603604/// @brief handles additional game-related events (DRT)605void checkGamingEventsDRT();606607/// @brief invalidate copy constructor608GUIApplicationWindow(const GUIApplicationWindow& s) = delete;609610/// @brief invalidate assignment operator611GUIApplicationWindow& operator=(const GUIApplicationWindow& s) = delete;612};613614615