/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-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 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 open simulation/network in netedit420FXMenuCommand* myOpenInNetedit = nullptr;421422/// @brief Buttons showing and running values and triggering statistic windows423std::vector<FXButton*> myStatButtons;424425/// @brief A window to display messages, warnings and error in426GUIMessageWindow* myMessageWindow = nullptr;427428/// @brief The splitter that divides the main window into views and the log window429FXSplitter* myMainSplitter = nullptr;430431/// @brief for some menu detaching fun432FXToolBarShell* myToolBarDrag1 = nullptr,433*myToolBarDrag2 = nullptr,434*myToolBarDrag3 = nullptr,435*myToolBarDrag4 = nullptr,436*myToolBarDrag5 = nullptr,437*myMenuBarDrag = nullptr,438*myToolBarDrag8 = nullptr;439440/// @brief the simulation delay in milliseconds441double mySimDelay = 0.;442443/// @brief Simulation delay target444FXDataTarget* mySimDelayTarget = nullptr;445446/// @brief Simulation delay spinner447FXRealSpinner* mySimDelaySpinner = nullptr;448449/// @brief Simulation delay slider450FXSlider* mySimDelaySlider = nullptr;451452/// @brief the demand scale label453MFXLabelTooltip* myScaleTrafficTooltip = nullptr;454455/// @brief the demand scale456FXRealSpinner* myDemandScaleSpinner = nullptr;457458/// @brief The alternate simulation delay in milliseconds for toggling459double myAlternateSimDelay = 0;460461/// @brief List of got requests462MFXSynchQue<GUIEvent*> myEvents;463464/// @brief The menu used for the MDI-windows465FXMDIMenu* myMDIMenu = nullptr;466467/// @brief The application menu bar468FXMenuBar* myMenuBar = nullptr;469470/// @brief The application tool bar471FXToolBar* myToolBar1 = nullptr,472*myToolBar2 = nullptr,473*myToolBar3 = nullptr,474*myToolBar4 = nullptr,475*myToolBar5 = nullptr,476*myToolBar8 = nullptr;477478/// @brief the simulation step display479MFXLCDLabel* myLCDLabel = nullptr;480481/// @brief io-event with the load-thread482FXEX::MFXThreadEvent myLoadThreadEvent;483484/// @brief io-event with the run-thread485FXEX::MFXThreadEvent myRunThreadEvent;486487/// @brief List of recent networks488MFXRecentNetworks myRecentNetworks;489490/// @brief List of recent configs491MFXRecentNetworks myRecentConfigs;492493/// @brief flag to mark if GUIApplicationWIndow has depend build494bool hadDependentBuild = false;495496/// @brief whether to show time as hour:minute:second497bool myShowTimeAsHMS = false;498499/// @brief whether the simulation end was already announced500bool myHaveNotifiedAboutSimEnd = false;501502/// @brief the mutex for the waiting semaphore503FXMutex myEventMutex;504505/// @brief the semaphore when waiting for event completion506FXCondition myEventCondition;507508/// @brief menu checkbox to activate game mode509FXMenuCheck* myGamingModeCheckbox;510511/// @name game related things512/// {513514/// @brief random list of jam sounds515RandomDistributor<std::string> myJamSounds;516517/// @brief random list of collision sounds518RandomDistributor<std::string> myCollisionSounds;519520/// @brief waiting time after which vehicles trigger jam sounds521double myJamSoundTime = 60;522523/// @brief A random number generator used to choose a gaming sound524static std::mt19937 myGamingRNG;525526/// @brief previous collision number527int myPreviousCollisionNumber = 0;528529/// @brief flag for enable TLS gameMode530bool myTLSGame = false;531532/// @brief waiting time label533MFXLCDLabel* myWaitingTimeLabel = nullptr;534535/// @brief waiting time536SUMOTime myWaitingTime = 0;537538/// @brief time loss label539MFXLCDLabel* myTimeLossLabel = nullptr;540541/// @brief time loss542SUMOTime myTimeLoss = 0;543544/// @brief total distance label545MFXLCDLabel* myTotalDistanceLabel = nullptr;546547/// @brief total distance548double myTotalDistance = 0;549550/// @brief emergency vehicle label551MFXLCDLabel* myEmergencyVehicleLabel = nullptr;552553/// @brief emergency vehicle count554SUMOTime myEmergencyVehicleCount = 0;555556/// @brief toolbars used in game557FXToolBar* myToolBar6 = nullptr,558*myToolBar7 = nullptr,559*myToolBar9 = nullptr,560*myToolBar10 = nullptr;561562/// @brief toolbars shell used in game563FXToolBarShell* myToolBarDrag6 = nullptr,564*myToolBarDrag7 = nullptr,565*myToolBarDrag9 = nullptr,566*myToolBarDrag10 = nullptr;567////}568569/// @brief last time the simulation view was redrawn due to a simStep570long myLastStepEventMillis;571572/// @brief custom hotkeys pressed573std::map<int, Command*> myHotkeyPress;574575/// @brief custom hotkeys released576std::map<int, Command*> myHotkeyRelease;577578/// @brief breakpoint dialog579GUIDialog_Breakpoints* myBreakpointDialog = nullptr;580581std::stringstream* myDynamicSelection = nullptr;582583private:584/// @brief starts to load a simulation585void loadConfigOrNet(const std::string& file);586587/// @brief this method closes all windows and deletes the current simulation588void closeAllWindows();589590/// @brief updates the simulation time display591void updateTimeLCD(SUMOTime time);592593/// @brief update LCD timer tooltip594void updateTimeLCDTooltip();595596/// @brief opens a new simulation display597GUISUMOAbstractView* openNewView(GUISUMOViewParent::ViewType vt = GUISUMOViewParent::VIEW_2D_OPENGL, std::string caption = "");598599/// @brief handles additional game-related events600void checkGamingEvents();601602/// @brief handles additional game-related events (DRT)603void checkGamingEventsDRT();604605/// @brief invalidate copy constructor606GUIApplicationWindow(const GUIApplicationWindow& s) = delete;607608/// @brief invalidate assignment operator609GUIApplicationWindow& operator=(const GUIApplicationWindow& s) = delete;610};611612613