1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file GUIApplicationWindow.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Michael Behrisch
14 /// @author Andreas Gaubatz
15 /// @date Sept 2002
16 /// @version $Id$
17 ///
18 // The main window of the SUMO-gui.
19 /****************************************************************************/
20
21
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26
27 #ifdef HAVE_VERSION_H
28 #include <version.h>
29 #endif
30
31 #include <string>
32 #include <sstream>
33 #include <algorithm>
34 #include <iomanip>
35
36 #include <guisim/GUINet.h>
37 #include <guisim/GUILane.h>
38 #include <netload/NLHandler.h>
39 #include <traci-server/TraCIServer.h>
40 #include <microsim/MSGlobals.h>
41 #include <microsim/MSEdge.h>
42 #include <microsim/MSVehicle.h>
43 #include <microsim/MSStateHandler.h>
44 #include <microsim/MSVehicleControl.h>
45 #include <microsim/MSEdgeControl.h>
46 #include <microsim/MSInsertionControl.h>
47 #include <microsim/MSTransportableControl.h>
48
49 #include "GUISUMOViewParent.h"
50 #include "GUILoadThread.h"
51 #include "GUIRunThread.h"
52 #include "GUIApplicationWindow.h"
53 #include "GUIEvent_SimulationLoaded.h"
54 #include "GUIEvent_SimulationEnded.h"
55
56 #include <utils/common/ToString.h>
57 #include <utils/common/RandHelper.h>
58 #include <utils/foxtools/MFXUtils.h>
59 #include <utils/foxtools/FXLCDLabel.h>
60 #include <utils/foxtools/FXThreadEvent.h>
61 #include <utils/foxtools/FXLinkLabel.h>
62
63 #include <utils/xml/XMLSubSys.h>
64 #include <utils/gui/images/GUITexturesHelper.h>
65 #include <utils/gui/events/GUIEvent_SimulationStep.h>
66 #include <utils/gui/events/GUIEvent_Message.h>
67 #include <utils/gui/div/GUIMessageWindow.h>
68 #include <utils/gui/div/GUIDialog_GLChosenEditor.h>
69 #include <utils/gui/tracker/GUIParameterTracker.h>
70 #include <utils/gui/div/GUIParameterTableWindow.h>
71 #include <utils/gui/images/GUIIconSubSys.h>
72 #include <utils/gui/cursors/GUICursorSubSys.h>
73 #include <utils/gui/shortcuts/GUIShortcutsSubSys.h>
74 #include <utils/gui/div/GUIIOGlobals.h>
75 #include <utils/gui/div/GUIUserIO.h>
76 #include <utils/gui/div/GLHelper.h>
77 #include <utils/gui/settings/GUICompleteSchemeStorage.h>
78 #include <utils/gui/globjects/GUIGlObjectStorage.h>
79 #include <utils/gui/globjects/GUIShapeContainer.h>
80 #include <utils/gui/div/GUIGlobalSelection.h>
81 #include <utils/gui/div/GUIDesigns.h>
82 #include <utils/gui/settings/GUISettingsHandler.h>
83 #include <utils/gui/windows/GUIAppEnum.h>
84 #include <utils/gui/windows/GUISUMOAbstractView.h>
85 #include <utils/gui/windows/GUIPerspectiveChanger.h>
86 #include <utils/options/OptionsCont.h>
87 #include "GUIGlobals.h"
88 #include "dialogs/GUIDialog_AboutSUMO.h"
89 #include "dialogs/GUIDialog_AppSettings.h"
90 #include "dialogs/GUIDialog_Breakpoints.h"
91
92
93 //#define HAVE_DANGEROUS_SOUNDS
94
95 // ===========================================================================
96 // FOX-declarations
97 // ===========================================================================
98 FXDEFMAP(GUIApplicationWindow) GUIApplicationWindowMap[] = {
99 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_Q_CLOSE, GUIApplicationWindow::onCmdQuit),
100 FXMAPFUNC(SEL_SIGNAL, MID_HOTKEY_CTRL_Q_CLOSE, GUIApplicationWindow::onCmdQuit),
101 FXMAPFUNC(SEL_CLOSE, MID_WINDOW, GUIApplicationWindow::onCmdQuit),
102
103 FXMAPFUNC(SEL_COMMAND, MID_OPEN_CONFIG, GUIApplicationWindow::onCmdOpenConfiguration),
104 FXMAPFUNC(SEL_COMMAND, MID_OPEN_NETWORK, GUIApplicationWindow::onCmdOpenNetwork),
105 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_P, GUIApplicationWindow::onCmdOpenShapes),
106 FXMAPFUNC(SEL_COMMAND, MID_OPEN_EDGEDATA, GUIApplicationWindow::onCmdOpenEdgeData),
107 FXMAPFUNC(SEL_COMMAND, MID_RECENTFILE, GUIApplicationWindow::onCmdOpenRecent),
108 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_R_RELOAD, GUIApplicationWindow::onCmdReload),
109 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_W_CLOSESIMULATION, GUIApplicationWindow::onCmdClose),
110 FXMAPFUNC(SEL_COMMAND, MID_EDITCHOSEN, GUIApplicationWindow::onCmdEditChosen),
111 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_B_EDITBREAKPOINT, GUIApplicationWindow::onCmdEditBreakpoints),
112 FXMAPFUNC(SEL_COMMAND, MID_EDITVIEWSCHEME, GUIApplicationWindow::onCmdEditViewScheme),
113 FXMAPFUNC(SEL_COMMAND, MID_EDITVIEWPORT, GUIApplicationWindow::onCmdEditViewport),
114 FXMAPFUNC(SEL_COMMAND, MID_NETEDIT, GUIApplicationWindow::onCmdNetedit),
115
116 FXMAPFUNC(SEL_COMMAND, MID_APPSETTINGS, GUIApplicationWindow::onCmdAppSettings),
117 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_G_GAMINGMODE_TOOGLEGRID, GUIApplicationWindow::onCmdGaming),
118 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_F_FULSCREENMODE, GUIApplicationWindow::onCmdFullScreen),
119 FXMAPFUNC(SEL_COMMAND, MID_LISTINTERNAL, GUIApplicationWindow::onCmdListInternal),
120 FXMAPFUNC(SEL_COMMAND, MID_LISTPARKING, GUIApplicationWindow::onCmdListParking),
121 FXMAPFUNC(SEL_COMMAND, MID_LISTTELEPORTING, GUIApplicationWindow::onCmdListTeleporting),
122 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_F2_ABOUT, GUIApplicationWindow::onCmdAbout),
123 FXMAPFUNC(SEL_COMMAND, MID_NEW_MICROVIEW, GUIApplicationWindow::onCmdNewView),
124 #ifdef HAVE_OSG
125 FXMAPFUNC(SEL_COMMAND, MID_NEW_OSGVIEW, GUIApplicationWindow::onCmdNewOSG),
126 #endif
127 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALS, GUIApplicationWindow::onCmdStart),
128 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK, GUIApplicationWindow::onCmdStop),
129 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMAND, GUIApplicationWindow::onCmdStep),
130 FXMAPFUNC(SEL_COMMAND, MID_SIMSAVE, GUIApplicationWindow::onCmdSaveState),
131 FXMAPFUNC(SEL_COMMAND, MID_TIME_TOOGLE, GUIApplicationWindow::onCmdTimeToggle),
132 FXMAPFUNC(SEL_COMMAND, MID_DELAY_TOOGLE, GUIApplicationWindow::onCmdDelayToggle),
133 FXMAPFUNC(SEL_COMMAND, MID_DEMAND_SCALE, GUIApplicationWindow::onCmdDemandScale),
134 FXMAPFUNC(SEL_COMMAND, MID_CLEARMESSAGEWINDOW, GUIApplicationWindow::onCmdClearMsgWindow),
135
136 FXMAPFUNC(SEL_COMMAND, MID_SHOWNETSTATS, GUIApplicationWindow::onCmdShowStats),
137 FXMAPFUNC(SEL_COMMAND, MID_SHOWVEHSTATS, GUIApplicationWindow::onCmdShowStats),
138 FXMAPFUNC(SEL_COMMAND, MID_SHOWPERSONSTATS, GUIApplicationWindow::onCmdShowStats),
139
140 FXMAPFUNC(SEL_UPDATE, MID_OPEN_CONFIG, GUIApplicationWindow::onUpdOpen),
141 FXMAPFUNC(SEL_UPDATE, MID_OPEN_NETWORK, GUIApplicationWindow::onUpdOpen),
142 FXMAPFUNC(SEL_UPDATE, MID_OPEN_NETWORK, GUIApplicationWindow::onUpdOpen),
143 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_P, GUIApplicationWindow::onUpdNeedsSimulation),
144 FXMAPFUNC(SEL_UPDATE, MID_OPEN_EDGEDATA, GUIApplicationWindow::onUpdNeedsSimulation),
145 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_R_RELOAD, GUIApplicationWindow::onUpdReload),
146 FXMAPFUNC(SEL_UPDATE, MID_RECENTFILE, GUIApplicationWindow::onUpdOpenRecent),
147 FXMAPFUNC(SEL_UPDATE, MID_NEW_MICROVIEW, GUIApplicationWindow::onUpdAddView),
148 #ifdef HAVE_OSG
149 FXMAPFUNC(SEL_UPDATE, MID_NEW_OSGVIEW, GUIApplicationWindow::onUpdAddView),
150 #endif
151 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALS, GUIApplicationWindow::onUpdStart),
152 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK, GUIApplicationWindow::onUpdStop),
153 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMAND, GUIApplicationWindow::onUpdStep),
154 FXMAPFUNC(SEL_UPDATE, MID_SIMSAVE, GUIApplicationWindow::onUpdNeedsSimulation),
155 FXMAPFUNC(SEL_UPDATE, MID_EDITCHOSEN, GUIApplicationWindow::onUpdNeedsSimulation),
156 FXMAPFUNC(SEL_UPDATE, MID_HOTKEY_CTRL_B_EDITBREAKPOINT, GUIApplicationWindow::onUpdNeedsSimulation),
157 FXMAPFUNC(SEL_UPDATE, MID_EDITVIEWSCHEME, GUIApplicationWindow::onUpdNeedsSimulation),
158 FXMAPFUNC(SEL_UPDATE, MID_EDITVIEWPORT, GUIApplicationWindow::onUpdNeedsSimulation),
159 FXMAPFUNC(SEL_UPDATE, MID_NETEDIT, GUIApplicationWindow::onUpdNeedsSimulation),
160 FXMAPFUNC(SEL_UPDATE, MID_DEMAND_SCALE, GUIApplicationWindow::onUpdNeedsSimulation),
161 FXMAPFUNC(SEL_UPDATE, MID_TRACI_STATUS, GUIApplicationWindow::onUpdTraCIStatus),
162 FXMAPFUNC(SEL_COMMAND, MID_HOTKEY_F1_ONLINEDOCUMENTATION, GUIApplicationWindow::onCmdHelp),
163
164 // forward requests to the active view
165 FXMAPFUNC(SEL_COMMAND, MID_LOCATEJUNCTION, GUIApplicationWindow::onCmdLocate),
166 FXMAPFUNC(SEL_COMMAND, MID_LOCATEEDGE, GUIApplicationWindow::onCmdLocate),
167 FXMAPFUNC(SEL_COMMAND, MID_LOCATEVEHICLE, GUIApplicationWindow::onCmdLocate),
168 FXMAPFUNC(SEL_COMMAND, MID_LOCATEPERSON, GUIApplicationWindow::onCmdLocate),
169 FXMAPFUNC(SEL_COMMAND, MID_LOCATETLS, GUIApplicationWindow::onCmdLocate),
170 FXMAPFUNC(SEL_COMMAND, MID_LOCATEADD, GUIApplicationWindow::onCmdLocate),
171 FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOI, GUIApplicationWindow::onCmdLocate),
172 FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOLY, GUIApplicationWindow::onCmdLocate),
173 FXMAPFUNC(SEL_UPDATE, MID_LOCATEJUNCTION, GUIApplicationWindow::onUpdNeedsSimulation),
174 FXMAPFUNC(SEL_UPDATE, MID_LOCATEEDGE, GUIApplicationWindow::onUpdNeedsSimulation),
175 FXMAPFUNC(SEL_UPDATE, MID_LOCATEVEHICLE, GUIApplicationWindow::onUpdNeedsSimulation),
176 FXMAPFUNC(SEL_UPDATE, MID_LOCATEPERSON, GUIApplicationWindow::onUpdNeedsSimulation),
177 FXMAPFUNC(SEL_UPDATE, MID_LOCATETLS, GUIApplicationWindow::onUpdNeedsSimulation),
178 FXMAPFUNC(SEL_UPDATE, MID_LOCATEADD, GUIApplicationWindow::onUpdNeedsSimulation),
179 FXMAPFUNC(SEL_UPDATE, MID_LOCATEPOI, GUIApplicationWindow::onUpdNeedsSimulation),
180 FXMAPFUNC(SEL_UPDATE, MID_LOCATEPOLY, GUIApplicationWindow::onUpdNeedsSimulation),
181 FXMAPFUNC(SEL_KEYPRESS, 0, GUIApplicationWindow::onKeyPress),
182 FXMAPFUNC(SEL_KEYRELEASE, 0, GUIApplicationWindow::onKeyRelease),
183
184 FXMAPFUNC(SEL_CLIPBOARD_REQUEST, 0, GUIApplicationWindow::onClipboardRequest),
185
186 FXMAPFUNC(FXEX::SEL_THREAD_EVENT, ID_LOADTHREAD_EVENT, GUIApplicationWindow::onLoadThreadEvent),
187 FXMAPFUNC(FXEX::SEL_THREAD_EVENT, ID_RUNTHREAD_EVENT, GUIApplicationWindow::onRunThreadEvent),
188 FXMAPFUNC(FXEX::SEL_THREAD, ID_LOADTHREAD_EVENT, GUIApplicationWindow::onLoadThreadEvent),
189 FXMAPFUNC(FXEX::SEL_THREAD, ID_RUNTHREAD_EVENT, GUIApplicationWindow::onRunThreadEvent),
190 };
191
192 // Object implementation
193 FXIMPLEMENT(GUIApplicationWindow, FXMainWindow, GUIApplicationWindowMap, ARRAYNUMBER(GUIApplicationWindowMap))
194
195 // ===========================================================================
196 // static members
197 // ===========================================================================
198 std::mt19937 GUIApplicationWindow::myGamingRNG;
199
200 // ===========================================================================
201 // member method definitions
202 // ===========================================================================
GUIApplicationWindow(FXApp * a,const std::string & configPattern)203 GUIApplicationWindow::GUIApplicationWindow(FXApp* a, const std::string& configPattern) :
204 GUIMainWindow(a),
205 myLoadThread(nullptr), myRunThread(nullptr),
206 myAmLoading(false),
207 myAlternateSimDelay(0),
208 myRecentNets(a, "nets"),
209 myConfigPattern(configPattern),
210 hadDependentBuild(false),
211 myShowTimeAsHMS(false),
212 myHaveNotifiedAboutSimEnd(false),
213 // game specific
214 myJamSoundTime(60),
215 myPreviousCollisionNumber(0),
216 myWaitingTime(0),
217 myTimeLoss(0),
218 myTotalDistance(0) {
219 // init icons
220 GUIIconSubSys::initIcons(a);
221 // init cursors
222 GUICursorSubSys::initCursors(a);
223 }
224
225
226 void
dependentBuild()227 GUIApplicationWindow::dependentBuild() {
228 // don't do this twice
229 if (hadDependentBuild) {
230 return;
231 }
232 hadDependentBuild = true;
233
234 setTarget(this);
235 setSelector(MID_WINDOW);
236
237 // build menu bar
238 myMenuBarDrag = new FXToolBarShell(this, GUIDesignToolBar);
239 myMenuBar = new FXMenuBar(myTopDock, myMenuBarDrag, GUIDesignToolbarMenuBar);
240 new FXToolBarGrip(myMenuBar, myMenuBar, FXMenuBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
241 buildToolBars();
242 // build the thread - io
243 myLoadThreadEvent.setTarget(this), myLoadThreadEvent.setSelector(ID_LOADTHREAD_EVENT);
244 myRunThreadEvent.setTarget(this), myRunThreadEvent.setSelector(ID_RUNTHREAD_EVENT);
245
246 // build the status bar
247 myStatusbar = new FXStatusBar(this, GUIDesignStatusBar);
248 {
249 myGeoFrame = new FXHorizontalFrame(myStatusbar, GUIDesignHorizontalFrameStatusBar);
250 myGeoCoordinate = new FXLabel(myGeoFrame, "N/A\t\tOriginal coordinate (before coordinate transformation in NETCONVERT)", nullptr, LAYOUT_CENTER_Y);
251 myCartesianFrame = new FXHorizontalFrame(myStatusbar, GUIDesignHorizontalFrameStatusBar);
252 myCartesianCoordinate = new FXLabel(myCartesianFrame, "N/A\t\tNetwork coordinate", nullptr, LAYOUT_CENTER_Y);
253 myStatButtons.push_back(new FXButton(myStatusbar, "-", GUIIconSubSys::getIcon(ICON_GREENVEHICLE), this, MID_SHOWVEHSTATS));
254 myStatButtons.push_back(new FXButton(myStatusbar, "-", GUIIconSubSys::getIcon(ICON_GREENPERSON), this, MID_SHOWPERSONSTATS));
255 myStatButtons.back()->hide();
256 myStatButtons.push_back(new FXButton(myStatusbar, "-", GUIIconSubSys::getIcon(ICON_GREENEDGE), this, MID_SHOWVEHSTATS));
257 myStatButtons.back()->hide();
258 }
259
260 // make the window a mdi-window
261 myMainSplitter = new FXSplitter(this, GUIDesignSplitter | SPLITTER_VERTICAL | SPLITTER_REVERSED);
262 myMDIClient = new FXMDIClient(myMainSplitter, GUIDesignSplitterMDI);
263 myMDIMenu = new FXMDIMenu(this, myMDIClient);
264 new FXMDIWindowButton(myMenuBar, myMDIMenu, myMDIClient, FXMDIClient::ID_MDI_MENUWINDOW, GUIDesignMDIButtonLeft);
265 new FXMDIDeleteButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENUCLOSE, GUIDesignMDIButtonRight);
266 new FXMDIRestoreButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENURESTORE, GUIDesignMDIButtonRight);
267 new FXMDIMinimizeButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENUMINIMIZE, GUIDesignMDIButtonRight);
268
269 // build the message window
270 myMessageWindow = new GUIMessageWindow(myMainSplitter);
271 // fill menu and tool bar
272 fillMenuBar();
273 myToolBar6->hide();
274 myToolBar7->hide();
275 myToolBar9->hide();
276 // build additional threads
277 myLoadThread = new GUILoadThread(getApp(), this, myEvents, myLoadThreadEvent);
278 myRunThread = new GUIRunThread(getApp(), this, mySimDelay, myEvents, myRunThreadEvent);
279 // set the status bar
280 myStatusbar->getStatusLine()->setText("Ready.");
281 // set the caption
282 setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING));
283
284 // start the simulation-thread (it will loop until the application ends deciding by itself whether to perform a step or not)
285 myRunThread->start();
286 setIcon(GUIIconSubSys::getIcon(ICON_SUMO));
287 setMiniIcon(GUIIconSubSys::getIcon(ICON_SUMO_MINI));
288 }
289
290
291 void
create()292 GUIApplicationWindow::create() {
293 setWindowSizeAndPos();
294 gCurrentFolder = getApp()->reg().readStringEntry("SETTINGS", "basedir", "");
295 FXMainWindow::create();
296 myMenuBarDrag->create();
297 myToolBarDrag1->create();
298 myToolBarDrag2->create();
299 myToolBarDrag3->create();
300 myToolBarDrag4->create();
301 myToolBarDrag5->create();
302 myToolBarDrag6->create();
303 myToolBarDrag7->create();
304 myFileMenu->create();
305 mySelectByPermissions->create();
306 myEditMenu->create();
307 mySettingsMenu->create();
308 myLocatorMenu->create();
309 myControlMenu->create();
310 myWindowsMenu->create();
311 myHelpMenu->create();
312
313 FXint width = getApp()->getNormalFont()->getTextWidth("8", 1) * 24;
314 myCartesianFrame->setWidth(width);
315 myGeoFrame->setWidth(width);
316
317 show(PLACEMENT_DEFAULT);
318 if (!OptionsCont::getOptions().isSet("window-size")) {
319 if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 1) {
320 maximize();
321 }
322 }
323 myShowTimeAsHMS = (getApp()->reg().readIntEntry("gui", "timeasHMS", 0) == 1);
324 myAlternateSimDelay = getApp()->reg().readIntEntry("gui", "alternateSimDelay", 100);
325 }
326
327
~GUIApplicationWindow()328 GUIApplicationWindow::~GUIApplicationWindow() {
329 myRunThread->prepareDestruction();
330 myRunThread->join();
331 closeAllWindows();
332 //
333 GUIIconSubSys::close();
334 delete myGLVisual;
335 // delete some non-parented windows
336 delete myToolBarDrag1;
337 //
338 delete myRunThread;
339 delete myFileMenu;
340 delete myEditMenu;
341 delete mySelectByPermissions;
342 delete mySettingsMenu;
343 delete myLocatorMenu;
344 delete myControlMenu;
345 delete myWindowsMenu;
346 delete myHelpMenu;
347
348 delete myLoadThread;
349
350 while (!myEvents.empty()) {
351 // get the next event
352 GUIEvent* e = myEvents.top();
353 myEvents.pop();
354 delete e;
355 }
356 }
357
358
359 void
detach()360 GUIApplicationWindow::detach() {
361 FXMainWindow::detach();
362 myMenuBarDrag->detach();
363 myToolBarDrag1->detach();
364 }
365
366
367 void
fillMenuBar()368 GUIApplicationWindow::fillMenuBar() {
369 // build file menu
370 myFileMenu = new FXMenuPane(this);
371 new FXMenuTitle(myMenuBar, "&File", nullptr, myFileMenu);
372 new FXMenuCommand(myFileMenu,
373 "&Open Simulation...\tCtrl+O\tOpen a simulation (Configuration file).",
374 GUIIconSubSys::getIcon(ICON_OPEN_CONFIG), this, MID_OPEN_CONFIG);
375 new FXMenuCommand(myFileMenu,
376 "Open &Network...\tCtrl+N\tOpen a network.",
377 GUIIconSubSys::getIcon(ICON_OPEN_NET), this, MID_OPEN_NETWORK);
378 new FXMenuCommand(myFileMenu,
379 "Open Shapes \tCtrl+P\tLoad POIs and Polygons for visualization.",
380 GUIIconSubSys::getIcon(ICON_OPEN_SHAPES), this, MID_HOTKEY_CTRL_P);
381 new FXMenuCommand(myFileMenu,
382 "Open EdgeData \tCtrl+U\tLoad edge related data for visualization.",
383 GUIIconSubSys::getIcon(ICON_OPEN_NET), this, MID_OPEN_EDGEDATA);
384 new FXMenuCommand(myFileMenu,
385 "&Reload\tCtrl+R\tReloads the simulation / the network.",
386 GUIIconSubSys::getIcon(ICON_RELOAD), this, MID_HOTKEY_CTRL_R_RELOAD);
387 new FXMenuSeparator(myFileMenu);
388 new FXMenuCommand(myFileMenu,
389 "Close\tCtrl+W\tClose the simulation.",
390 GUIIconSubSys::getIcon(ICON_CLOSE), this, MID_HOTKEY_CTRL_W_CLOSESIMULATION);
391 // Recent files
392 FXMenuSeparator* sep1 = new FXMenuSeparator(myFileMenu);
393 sep1->setTarget(&myRecentConfigs);
394 sep1->setSelector(FXRecentFiles::ID_ANYFILES);
395 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_1);
396 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_2);
397 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_3);
398 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_4);
399 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_5);
400 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_6);
401 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_7);
402 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_8);
403 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_9);
404 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentConfigs, FXRecentFiles::ID_FILE_10);
405 new FXMenuCommand(myFileMenu, "C&lear Recent Configurations", nullptr, &myRecentConfigs, FXRecentFiles::ID_CLEAR);
406 myRecentConfigs.setTarget(this);
407 myRecentConfigs.setSelector(MID_RECENTFILE);
408 FXMenuSeparator* sep2 = new FXMenuSeparator(myFileMenu);
409 sep2->setTarget(&myRecentNets);
410 sep2->setSelector(FXRecentFiles::ID_ANYFILES);
411 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_1);
412 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_2);
413 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_3);
414 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_4);
415 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_5);
416 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_6);
417 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_7);
418 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_8);
419 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_9);
420 new FXMenuCommand(myFileMenu, "", nullptr, &myRecentNets, FXRecentFiles::ID_FILE_10);
421 new FXMenuCommand(myFileMenu, "Cl&ear Recent Networks", nullptr, &myRecentNets, FXRecentFiles::ID_CLEAR);
422 myRecentNets.setTarget(this);
423 myRecentNets.setSelector(MID_RECENTFILE);
424 new FXMenuSeparator(myFileMenu);
425 new FXMenuCommand(myFileMenu,
426 "&Quit\tCtrl+Q\tQuit the Application.",
427 nullptr, this, MID_HOTKEY_CTRL_Q_CLOSE, 0);
428
429 // build edit menu
430 mySelectByPermissions = new FXMenuPane(this);
431 std::vector<std::string> vehicleClasses = SumoVehicleClassStrings.getStrings();
432 for (auto i : vehicleClasses) {
433 new FXMenuCommand(mySelectByPermissions, i.c_str(), nullptr, this, MID_EDITCHOSEN);
434 }
435
436 myEditMenu = new FXMenuPane(this);
437 new FXMenuTitle(myMenuBar, "&Edit", nullptr, myEditMenu);
438 new FXMenuCommand(myEditMenu,
439 "Edit Selected...\tCtrl+E\tOpens a dialog for editing the list of selected items.",
440 GUIIconSubSys::getIcon(ICON_FLAG), this, MID_EDITCHOSEN);
441 mySelectLanesMenuCascade = new FXMenuCascade(myEditMenu,
442 "Select lanes which allow...\t\tOpens a menu for selecting a vehicle class by which to selected lanes.",
443 GUIIconSubSys::getIcon(ICON_FLAG), mySelectByPermissions);
444 new FXMenuSeparator(myEditMenu);
445 new FXMenuCommand(myEditMenu,
446 "Edit Breakpoints\tCtrl+B\tOpens a dialog for editing breakpoints.",
447 nullptr, this, MID_HOTKEY_CTRL_B_EDITBREAKPOINT);
448 new FXMenuCommand(myEditMenu,
449 "Edit Visualisation\tCtrl+V\tOpens a dialog for editing visualization settings.",
450 nullptr, this, MID_EDITVIEWSCHEME);
451 new FXMenuCommand(myEditMenu,
452 "Edit Viewport\tCtrl+I\tOpens a dialog for editing viewing are, zoom and rotation.",
453 nullptr, this, MID_EDITVIEWPORT);
454 new FXMenuSeparator(myEditMenu);
455 new FXMenuCommand(myEditMenu,
456 "Open in Netedit\tCtrl+T\tOpens the netedit application with the current network.",
457 nullptr, this, MID_NETEDIT);
458
459 // build settings menu
460 mySettingsMenu = new FXMenuPane(this);
461 new FXMenuTitle(myMenuBar, "&Settings", nullptr, mySettingsMenu);
462 new FXMenuCommand(mySettingsMenu,
463 "Application Settings...\t\tOpen a Dialog for Application Settings editing.",
464 nullptr, this, MID_APPSETTINGS);
465 new FXMenuCheck(mySettingsMenu,
466 "Gaming Mode\tCtrl+G\tToggle gaming mode on/off.",
467 this, MID_HOTKEY_CTRL_G_GAMINGMODE_TOOGLEGRID);
468 new FXMenuCheck(mySettingsMenu,
469 "Full Screen Mode\tCtrl+F\tToggle full screen mode on/off.",
470 this, MID_HOTKEY_CTRL_F_FULSCREENMODE);
471 // build Locate menu
472 myLocatorMenu = new FXMenuPane(this);
473 new FXMenuTitle(myMenuBar, "&Locate", nullptr, myLocatorMenu);
474 new FXMenuCommand(myLocatorMenu,
475 "Locate &Junctions\t\tOpen a Dialog for Locating a Junction.",
476 GUIIconSubSys::getIcon(ICON_LOCATEJUNCTION), this, MID_LOCATEJUNCTION);
477 new FXMenuCommand(myLocatorMenu,
478 "Locate &Edges\t\tOpen a Dialog for Locating an Edge.",
479 GUIIconSubSys::getIcon(ICON_LOCATEEDGE), this, MID_LOCATEEDGE);
480 if (!MSGlobals::gUseMesoSim) { // there are no gui-vehicles in mesosim
481 new FXMenuCommand(myLocatorMenu,
482 "Locate &Vehicles\t\tOpen a Dialog for Locating a Vehicle.",
483 GUIIconSubSys::getIcon(ICON_LOCATEVEHICLE), this, MID_LOCATEVEHICLE);
484 }
485 new FXMenuCommand(myLocatorMenu,
486 "Locate &Persons\t\tOpen a Dialog for Locating a Person.",
487 GUIIconSubSys::getIcon(ICON_LOCATEPERSON), this, MID_LOCATEPERSON);
488 new FXMenuCommand(myLocatorMenu,
489 "Locate &TLS\t\tOpen a Dialog for Locating a Traffic Light.",
490 GUIIconSubSys::getIcon(ICON_LOCATETLS), this, MID_LOCATETLS);
491 new FXMenuCommand(myLocatorMenu,
492 "Locate &Additional\t\tOpen a Dialog for Locating an Additional Structure.",
493 GUIIconSubSys::getIcon(ICON_LOCATEADD), this, MID_LOCATEADD);
494 new FXMenuCommand(myLocatorMenu,
495 "Locate P&oI\t\tOpen a Dialog for Locating a Point of Intereset.",
496 GUIIconSubSys::getIcon(ICON_LOCATEPOI), this, MID_LOCATEPOI);
497 new FXMenuCommand(myLocatorMenu,
498 "Locate Po&lygon\t\tOpen a Dialog for Locating a Polygon.",
499 GUIIconSubSys::getIcon(ICON_LOCATEPOLY), this, MID_LOCATEPOLY);
500 new FXMenuSeparator(myLocatorMenu);
501 new FXMenuCheck(myLocatorMenu,
502 "Show Internal Structures\t\tShow internal junctions and streets in locator dialog.",
503 this, MID_LISTINTERNAL);
504 FXMenuCheck* listParking = new FXMenuCheck(myLocatorMenu,
505 "Show Parking Vehicles\t\tShow parking vehicles in locator dialog.",
506 this, MID_LISTPARKING);
507 listParking->setCheck(myListParking);
508 new FXMenuCheck(myLocatorMenu,
509 "Show vehicles outside the road network\t\tShow vehicles that are teleporting or driving remote-controlled outside the road network in locator dialog.",
510 this, MID_LISTTELEPORTING);
511 // build control menu
512 myControlMenu = new FXMenuPane(this);
513 new FXMenuTitle(myMenuBar, "Simulation", nullptr, myControlMenu);
514 new FXMenuCommand(myControlMenu,
515 "Run\tCtrl+A\tStart running the simulation.",
516 GUIIconSubSys::getIcon(ICON_START), this, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALS);
517 new FXMenuCommand(myControlMenu,
518 "Stop\tCtrl+S\tStop running the simulation.",
519 GUIIconSubSys::getIcon(ICON_STOP), this, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK);
520 new FXMenuCommand(myControlMenu,
521 "Step\tCtrl+D\tPerform one simulation step.",
522 GUIIconSubSys::getIcon(ICON_STEP), this, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMAND);
523 new FXMenuCommand(myControlMenu,
524 "Save\t\tSave the current simulation state to a file.",
525 GUIIconSubSys::getIcon(ICON_SAVE), this, MID_SIMSAVE);
526
527 // build windows menu
528 myWindowsMenu = new FXMenuPane(this);
529 new FXMenuTitle(myMenuBar, "&Windows", nullptr, myWindowsMenu);
530 new FXMenuCheck(myWindowsMenu,
531 "Show Status Line\t\tToggle the Status Bar on/off.",
532 myStatusbar, FXWindow::ID_TOGGLESHOWN);
533 new FXMenuCheck(myWindowsMenu,
534 "Show Message Window\t\tToggle the Message Window on/off.",
535 myMessageWindow, FXWindow::ID_TOGGLESHOWN);
536 new FXMenuCheck(myWindowsMenu,
537 "Show Simulation Time\t\tToggle the Simulation Time on/off.",
538 myToolBar3, FXWindow::ID_TOGGLESHOWN);
539 new FXMenuCheck(myWindowsMenu,
540 "Show Simulation Delay\t\tToggle the Simulation Delay Entry on/off.",
541 myToolBar4, FXWindow::ID_TOGGLESHOWN);
542 addToWindowsMenu(myWindowsMenu);
543 new FXMenuSeparator(myWindowsMenu);
544 new FXMenuCommand(myWindowsMenu, "Tile &Horizontally",
545 GUIIconSubSys::getIcon(ICON_WINDOWS_TILE_HORI),
546 myMDIClient, FXMDIClient::ID_MDI_TILEHORIZONTAL);
547 new FXMenuCommand(myWindowsMenu, "Tile &Vertically",
548 GUIIconSubSys::getIcon(ICON_WINDOWS_TILE_VERT),
549 myMDIClient, FXMDIClient::ID_MDI_TILEVERTICAL);
550 new FXMenuCommand(myWindowsMenu, "Cascade",
551 GUIIconSubSys::getIcon(ICON_WINDOWS_CASCADE),
552 myMDIClient, FXMDIClient::ID_MDI_CASCADE);
553 new FXMenuCommand(myWindowsMenu, "&Close", nullptr,
554 myMDIClient, FXMDIClient::ID_MDI_CLOSE);
555 sep1 = new FXMenuSeparator(myWindowsMenu);
556 sep1->setTarget(myMDIClient);
557 sep1->setSelector(FXMDIClient::ID_MDI_ANY);
558 new FXMenuCommand(myWindowsMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_1);
559 new FXMenuCommand(myWindowsMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_2);
560 new FXMenuCommand(myWindowsMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_3);
561 new FXMenuCommand(myWindowsMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_4);
562 new FXMenuCommand(myWindowsMenu, "&Others...", nullptr, myMDIClient, FXMDIClient::ID_MDI_OVER_5);
563 new FXMenuSeparator(myWindowsMenu);
564 new FXMenuCommand(myWindowsMenu,
565 "Clear Message Window\t\tClear the message window.",
566 nullptr, this, MID_CLEARMESSAGEWINDOW);
567
568 // build help menu
569 myHelpMenu = new FXMenuPane(this);
570 new FXMenuTitle(myMenuBar, "&Help", nullptr, myHelpMenu);
571 new FXMenuCommand(myHelpMenu, "&Online Documentation\tF1\tOpen Online documentation", nullptr, this, MID_HOTKEY_F1_ONLINEDOCUMENTATION);
572 new FXMenuCommand(myHelpMenu, "&About\tF2\tAbout sumo-gui", GUIIconSubSys::getIcon(ICON_SUMO_MINI), this, MID_HOTKEY_F2_ABOUT);
573
574 //new FXButton(myMenuBar, "\t\tShows TraCI status", GUIIconSubSys::getIcon(ICON_ADD), this, MID_TRACI_STATUS, 0, 0, 0, 14, 14, 0, 0, 0, 0);
575
576 // build SUMO Accelerators (hotkeys)
577 GUIShortcutsSubSys::buildSUMOAccelerators(this);
578 }
579
580
581 void
buildToolBars()582 GUIApplicationWindow::buildToolBars() {
583 // build tool bars
584 {
585 // file and simulation tool bar
586 myToolBarDrag1 = new FXToolBarShell(this, GUIDesignToolBar);
587 myToolBar1 = new FXToolBar(myTopDock, myToolBarDrag1, GUIDesignToolBarRaisedNextTop);
588 new FXToolBarGrip(myToolBar1, myToolBar1, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
589 // build file tools
590 new FXButton(myToolBar1, "\t\tOpen a simulation (Configuration file).", GUIIconSubSys::getIcon(ICON_OPEN_CONFIG), this, MID_OPEN_CONFIG, GUIDesignButtonToolbar);
591 new FXButton(myToolBar1, "\t\tOpen a network.", GUIIconSubSys::getIcon(ICON_OPEN_NET), this, MID_OPEN_NETWORK, GUIDesignButtonToolbar);
592 new FXButton(myToolBar1, "\t\tReloads the simulation / the network.", GUIIconSubSys::getIcon(ICON_RELOAD), this, MID_HOTKEY_CTRL_R_RELOAD, GUIDesignButtonToolbar);
593 }
594 {
595 // simulation toolbar
596 myToolBarDrag2 = new FXToolBarShell(this, GUIDesignToolBar);
597 myToolBar2 = new FXToolBar(myTopDock, myToolBarDrag2, GUIDesignToolBarRaisedSameTop);
598 new FXToolBarGrip(myToolBar2, myToolBar2, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
599 // build simulation tools
600 new FXButton(myToolBar2, "\t\tStart the loaded simulation.", GUIIconSubSys::getIcon(ICON_START), this, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALS, GUIDesignButtonToolbar);
601 new FXButton(myToolBar2, "\t\tStop the running simulation.", GUIIconSubSys::getIcon(ICON_STOP), this, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK, GUIDesignButtonToolbar);
602 new FXButton(myToolBar2, "\t\tPerform a single simulation step.", GUIIconSubSys::getIcon(ICON_STEP), this, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMAND, GUIDesignButtonToolbar);
603 }
604 {
605 // Simulation Step Display
606 myToolBarDrag3 = new FXToolBarShell(this, GUIDesignToolBar);
607 myToolBar3 = new FXToolBar(myTopDock, myToolBarDrag3, GUIDesignToolBarRaisedSameTop);
608 new FXToolBarGrip(myToolBar3, myToolBar3, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
609 new FXButton(myToolBar3, "Time:\t\tToggle between seconds and hour:minute:seconds display", nullptr, this, MID_TIME_TOOGLE, GUIDesignButtonToolbarText);
610
611 myLCDLabel = new FXEX::FXLCDLabel(myToolBar3, 16, nullptr, 0, JUSTIFY_RIGHT);
612 myLCDLabel->setHorizontal(2);
613 myLCDLabel->setVertical(6);
614 myLCDLabel->setThickness(2);
615 myLCDLabel->setGroove(2);
616 myLCDLabel->setText("----------------");
617 }
618 {
619 // Simulation Delay
620 myToolBarDrag4 = new FXToolBarShell(this, GUIDesignToolBar);
621 myToolBar4 = new FXToolBar(myTopDock, myToolBarDrag4, GUIDesignToolBarRaisedSameTop);
622 new FXToolBarGrip(myToolBar4, myToolBar4, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
623 new FXButton(myToolBar4, "Delay (ms):\t\tDelay per simulated second. Click to toggle between the last two delay values", nullptr, this, MID_DELAY_TOOGLE, GUIDesignButtonToolbarText);
624
625 mySimDelay = 0;
626 mySimDelayTarget = new FXDataTarget(mySimDelay);
627 mySimDelaySpinner = new FXRealSpinner(myToolBar4, 7, mySimDelayTarget, FXDataTarget::ID_VALUE, GUIDesignSpinDial);
628 mySimDelaySlider = new FXSlider(myToolBar4, mySimDelayTarget, FXDataTarget::ID_VALUE, LAYOUT_FIX_WIDTH | SLIDER_ARROW_UP | SLIDER_TICKS_TOP, 0, 0, 300, 10, 0, 0, 5, 0);
629 mySimDelaySlider->setRange(0, 1000);
630 mySimDelaySlider->setHeadSize(10);
631 mySimDelaySlider->setIncrement(50);
632 mySimDelaySlider->setTickDelta(100);
633 mySimDelaySlider->setValue((int)mySimDelay);
634 //mySimDelayTarget->setNumberFormat(0);
635 //mySimDelayTarget->setIncrements(1, 10, 10);
636 mySimDelaySpinner->setIncrement(10);
637 mySimDelaySpinner->setRange(0, 10000);
638 mySimDelaySpinner->setValue(mySimDelay);
639 }
640 {
641 // Scale traffic (flows and incrementally loaded vehicles)
642 myToolBarDrag8 = new FXToolBarShell(this, GUIDesignToolBar);
643 myToolBar8 = new FXToolBar(myTopDock, myToolBarDrag8, GUIDesignToolBarRaisedSameTop);
644 new FXToolBarGrip(myToolBar8, myToolBar8, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
645 new FXLabel(myToolBar8, "Scale Traffic:\t\tScale traffic from flows and vehicles that are loaded incrementally from route files", nullptr, LAYOUT_TOP | LAYOUT_LEFT);
646 myDemandScaleSpinner = new FXRealSpinner(myToolBar8, 7, this, MID_DEMAND_SCALE, GUIDesignSpinDial);
647 myDemandScaleSpinner->setIncrement(0.5);
648 myDemandScaleSpinner->setRange(0, 1000);
649 myDemandScaleSpinner->setValue(1);
650 }
651 {
652 // Views
653 myToolBarDrag5 = new FXToolBarShell(this, GUIDesignToolBar);
654 myToolBar5 = new FXToolBar(myTopDock, myToolBarDrag5, GUIDesignToolBarRaisedSameTop);
655 new FXToolBarGrip(myToolBar5, myToolBar5, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
656 // build view tools
657 new FXButton(myToolBar5, "\t\tOpen a new microscopic view.",
658 GUIIconSubSys::getIcon(ICON_MICROVIEW), this, MID_NEW_MICROVIEW, GUIDesignButtonToolbar);
659 #ifdef HAVE_OSG
660 new FXButton(myToolBar5, "\t\tOpen a new 3D view.",
661 GUIIconSubSys::getIcon(ICON_OSGVIEW), this, MID_NEW_OSGVIEW, GUIDesignButtonToolbar);
662 #endif
663 }
664 {
665 /// game specific stuff
666 // total waitingTime
667 myToolBarDrag6 = new FXToolBarShell(this, GUIDesignToolBar);
668 myToolBar6 = new FXToolBar(myTopDock, myToolBarDrag6, GUIDesignToolBarRaisedSameTop);
669 new FXToolBarGrip(myToolBar6, myToolBar6, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
670 new FXLabel(myToolBar6, "Waiting Time:\t\tTime spent waiting accumulated for all vehicles", nullptr, LAYOUT_TOP | LAYOUT_LEFT);
671 myWaitingTimeLabel = new FXEX::FXLCDLabel(myToolBar6, 13, nullptr, 0, JUSTIFY_RIGHT);
672 myWaitingTimeLabel->setHorizontal(2);
673 myWaitingTimeLabel->setVertical(6);
674 myWaitingTimeLabel->setThickness(2);
675 myWaitingTimeLabel->setGroove(2);
676 myWaitingTimeLabel->setText("-------------");
677
678 // idealistic time loss
679 myToolBarDrag7 = new FXToolBarShell(this, GUIDesignToolBar);
680 myToolBar7 = new FXToolBar(myTopDock, myToolBarDrag7, GUIDesignToolBarRaisedSameTop);
681 new FXToolBarGrip(myToolBar7, myToolBar7, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
682 new FXLabel(myToolBar7, "Time Loss:\t\tTime lost due to being unable to drive with maximum speed for all vehicles", nullptr, LAYOUT_TOP | LAYOUT_LEFT);
683 myTimeLossLabel = new FXEX::FXLCDLabel(myToolBar7, 13, nullptr, 0, JUSTIFY_RIGHT);
684 myTimeLossLabel->setHorizontal(2);
685 myTimeLossLabel->setVertical(6);
686 myTimeLossLabel->setThickness(2);
687 myTimeLossLabel->setGroove(2);
688 myTimeLossLabel->setText("-------------");
689
690 // total driving distance
691 myToolBarDrag9 = new FXToolBarShell(this, GUIDesignToolBar);
692 myToolBar9 = new FXToolBar(myTopDock, myToolBarDrag9, GUIDesignToolBarRaisedSameTop);
693 new FXToolBarGrip(myToolBar9, myToolBar9, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
694 new FXLabel(myToolBar9, "Distance (km):\t\tTotal distance driven by DRT vehicles", nullptr, LAYOUT_TOP | LAYOUT_LEFT);
695 myTotalDistanceLabel = new FXEX::FXLCDLabel(myToolBar9, 13, nullptr, 0, JUSTIFY_RIGHT);
696 myTotalDistanceLabel->setHorizontal(2);
697 myTotalDistanceLabel->setVertical(6);
698 myTotalDistanceLabel->setThickness(2);
699 myTotalDistanceLabel->setGroove(2);
700 myTotalDistanceLabel->setText("-------------");
701 }
702 }
703
704
705 long
onCmdQuit(FXObject *,FXSelector,void *)706 GUIApplicationWindow::onCmdQuit(FXObject*, FXSelector, void*) {
707 storeWindowSizeAndPos();
708 getApp()->reg().writeStringEntry("SETTINGS", "basedir", gCurrentFolder.text());
709 getApp()->reg().writeIntEntry("SETTINGS", "maximized", isMaximized() ? 1 : 0);
710 getApp()->reg().writeIntEntry("gui", "timeasHMS", myShowTimeAsHMS ? 1 : 0);
711 getApp()->reg().writeIntEntry("gui", "alternateSimDelay", (int)myAlternateSimDelay);
712 getApp()->exit(0);
713 return 1;
714 }
715
716
717 long
onCmdEditChosen(FXObject * menu,FXSelector,void *)718 GUIApplicationWindow::onCmdEditChosen(FXObject* menu, FXSelector, void*) {
719 FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
720 if (mc->getText() == "Edit Selected...") {
721 GUIDialog_GLChosenEditor* chooser =
722 new GUIDialog_GLChosenEditor(this, &gSelected);
723 chooser->create();
724 chooser->show();
725 } else {
726 if (!myAmLoading && myRunThread->simulationAvailable()) {
727 const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
728 for (MSEdgeVector::const_iterator i = MSEdge::getAllEdges().begin(); i != MSEdge::getAllEdges().end(); ++i) {
729 const std::vector<MSLane*>& lanes = (*i)->getLanes();
730 for (std::vector<MSLane*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) {
731 GUILane* lane = dynamic_cast<GUILane*>(*it);
732 assert(lane != 0);
733 if ((lane->getPermissions() & svc) != 0) {
734 gSelected.select(lane->getGlID());
735 }
736 }
737 }
738 if (myMDIClient->numChildren() > 0) {
739 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
740 if (w != nullptr) {
741 // color by selection
742 w->getView()->getVisualisationSettings()->laneColorer.setActive(1);
743 }
744 }
745 }
746 updateChildren();
747 }
748 return 1;
749 }
750
751
752 long
onCmdEditBreakpoints(FXObject *,FXSelector,void *)753 GUIApplicationWindow::onCmdEditBreakpoints(FXObject*, FXSelector, void*) {
754 GUIDialog_Breakpoints* chooser = new GUIDialog_Breakpoints(this, myRunThread->getBreakpoints(), myRunThread->getBreakpointLock());
755 chooser->create();
756 chooser->show();
757 return 1;
758 }
759
760 long
onCmdEditViewport(FXObject *,FXSelector,void *)761 GUIApplicationWindow::onCmdEditViewport(FXObject*, FXSelector, void*) {
762 if (!myGLWindows.empty()) {
763 myGLWindows[0]->getView()->showViewportEditor();
764 }
765 return 1;
766 }
767
768
769 long
onCmdEditViewScheme(FXObject *,FXSelector,void *)770 GUIApplicationWindow::onCmdEditViewScheme(FXObject*, FXSelector, void*) {
771 if (!myGLWindows.empty()) {
772 myGLWindows[0]->getView()->showViewschemeEditor();
773 }
774 return 1;
775 }
776
777
778 long
onCmdHelp(FXObject *,FXSelector,void *)779 GUIApplicationWindow::onCmdHelp(FXObject*, FXSelector, void*) {
780 FXLinkLabel::fxexecute("https://sumo.dlr.de/wiki/SUMO-GUI");
781 return 1;
782 }
783
784
785 long
onCmdNetedit(FXObject *,FXSelector,void *)786 GUIApplicationWindow::onCmdNetedit(FXObject*, FXSelector, void*) {
787 if (myGLWindows.empty()) {
788 return 1;
789 }
790 FXRegistry reg("SUMO netedit", "Eclipse");
791 reg.read();
792 const GUISUMOAbstractView* const v = myGLWindows[0]->getView();
793 reg.writeRealEntry("viewport", "x", v->getChanger().getXPos());
794 reg.writeRealEntry("viewport", "y", v->getChanger().getYPos());
795 reg.writeRealEntry("viewport", "z", v->getChanger().getZPos());
796 reg.write();
797 std::string netedit = "netedit";
798 const char* sumoPath = getenv("SUMO_HOME");
799 if (sumoPath != nullptr) {
800 std::string newPath = std::string(sumoPath) + "/bin/netedit";
801 if (FileHelpers::isReadable(newPath) || FileHelpers::isReadable(newPath + ".exe")) {
802 netedit = "\"" + newPath + "\"";
803 }
804 }
805 std::string cmd = netedit + " --registry-viewport -s " + OptionsCont::getOptions().getString("net-file");
806 // start in background
807 #ifndef WIN32
808 cmd = cmd + " &";
809 #else
810 // see "help start" for the parameters
811 cmd = "start /B \"\" " + cmd;
812 #endif
813 WRITE_MESSAGE("Running " + cmd + ".");
814 // yay! fun with dangerous commands... Never use this over the internet
815 SysUtils::runHiddenCommand(cmd);
816 return 1;
817 }
818
819
820 long
onCmdOpenConfiguration(FXObject *,FXSelector,void *)821 GUIApplicationWindow::onCmdOpenConfiguration(FXObject*, FXSelector, void*) {
822 // get the new file name
823 FXFileDialog opendialog(this, "Open Simulation Configuration");
824 opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
825 opendialog.setSelectMode(SELECTFILE_EXISTING);
826 opendialog.setPatternList(myConfigPattern.c_str());
827 if (gCurrentFolder.length() != 0) {
828 opendialog.setDirectory(gCurrentFolder);
829 }
830 if (opendialog.execute()) {
831 gCurrentFolder = opendialog.getDirectory();
832 std::string file = opendialog.getFilename().text();
833 loadConfigOrNet(file, false);
834 myRecentConfigs.appendFile(file.c_str());
835 }
836 return 1;
837 }
838
839
840 long
onCmdOpenNetwork(FXObject *,FXSelector,void *)841 GUIApplicationWindow::onCmdOpenNetwork(FXObject*, FXSelector, void*) {
842 // get the new file name
843 FXFileDialog opendialog(this, "Open Network");
844 opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
845 opendialog.setSelectMode(SELECTFILE_EXISTING);
846 opendialog.setPatternList("SUMO nets (*.net.xml)\nAll files (*)");
847 if (gCurrentFolder.length() != 0) {
848 opendialog.setDirectory(gCurrentFolder);
849 }
850 if (opendialog.execute()) {
851 gCurrentFolder = opendialog.getDirectory();
852 std::string file = opendialog.getFilename().text();
853 loadConfigOrNet(file, true);
854 myRecentNets.appendFile(file.c_str());
855 }
856 return 1;
857 }
858
859
860 long
onCmdOpenShapes(FXObject *,FXSelector,void *)861 GUIApplicationWindow::onCmdOpenShapes(FXObject*, FXSelector, void*) {
862 // get the shape file name
863 FXFileDialog opendialog(this, "Open Shapes");
864 opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
865 opendialog.setSelectMode(SELECTFILE_EXISTING);
866 opendialog.setPatternList("Additional files (*.xml)\nAll files (*)");
867 if (gCurrentFolder.length() != 0) {
868 opendialog.setDirectory(gCurrentFolder);
869 }
870 if (opendialog.execute()) {
871 gCurrentFolder = opendialog.getDirectory();
872 std::string file = opendialog.getFilename().text();
873
874 dynamic_cast<GUIShapeContainer&>(myRunThread->getNet().getShapeContainer()).allowReplacement();
875 NLShapeHandler handler(file, myRunThread->getNet().getShapeContainer());
876 if (!XMLSubSys::runParser(handler, file, false)) {
877 WRITE_MESSAGE("Loading of " + file + " failed.");
878 }
879 update();
880 if (myMDIClient->numChildren() > 0) {
881 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
882 if (w != nullptr) {
883 w->getView()->update();
884 }
885 }
886 }
887 return 1;
888 }
889
890 long
onCmdOpenEdgeData(FXObject *,FXSelector,void *)891 GUIApplicationWindow::onCmdOpenEdgeData(FXObject*, FXSelector, void*) {
892 // get the shape file name
893 FXFileDialog opendialog(this, "Open EdgeData");
894 opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
895 opendialog.setSelectMode(SELECTFILE_EXISTING);
896 opendialog.setPatternList("EdgeData files (*.xml)\nAll files (*)");
897 if (gCurrentFolder.length() != 0) {
898 opendialog.setDirectory(gCurrentFolder);
899 }
900 if (opendialog.execute()) {
901 gCurrentFolder = opendialog.getDirectory();
902 std::string file = opendialog.getFilename().text();
903 if (!GUINet::getGUIInstance()->loadEdgeData(file)) {
904 WRITE_MESSAGE("Loading of " + file + " failed.");
905 }
906 update();
907 if (myMDIClient->numChildren() > 0) {
908 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
909 if (w != nullptr) {
910 w->getView()->update();
911 }
912 }
913 }
914 return 1;
915 }
916
917 long
onCmdReload(FXObject *,FXSelector,void *)918 GUIApplicationWindow::onCmdReload(FXObject*, FXSelector, void*) {
919 storeWindowSizeAndPos();
920 getApp()->beginWaitCursor();
921 myAmLoading = true;
922 closeAllWindows();
923 myLoadThread->start();
924 setStatusBarText("Reloading.");
925 update();
926 return 1;
927 }
928
929
930 long
onCmdOpenRecent(FXObject * sender,FXSelector,void * data)931 GUIApplicationWindow::onCmdOpenRecent(FXObject* sender, FXSelector, void* data) {
932 if (myAmLoading) {
933 myStatusbar->getStatusLine()->setText("Already loading!");
934 return 1;
935 }
936 std::string file((const char*)data);
937 loadConfigOrNet(file, sender == &myRecentNets);
938 return 1;
939 }
940
941
942 long
onCmdClose(FXObject *,FXSelector,void *)943 GUIApplicationWindow::onCmdClose(FXObject*, FXSelector, void*) {
944 closeAllWindows();
945 return 1;
946 }
947
948
949 long
onUpdOpen(FXObject * sender,FXSelector,void * ptr)950 GUIApplicationWindow::onUpdOpen(FXObject* sender, FXSelector, void* ptr) {
951 sender->handle(this,
952 myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
953 ptr);
954 return 1;
955 }
956
957
958 long
onUpdReload(FXObject * sender,FXSelector,void * ptr)959 GUIApplicationWindow::onUpdReload(FXObject* sender, FXSelector, void* ptr) {
960 sender->handle(this,
961 myAmLoading || myLoadThread->getFileName() == "" || TraCIServer::getInstance() != nullptr
962 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
963 ptr);
964 return 1;
965 }
966
967
968 long
onUpdOpenRecent(FXObject * sender,FXSelector,void * ptr)969 GUIApplicationWindow::onUpdOpenRecent(FXObject* sender, FXSelector, void* ptr) {
970 sender->handle(this,
971 myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
972 ptr);
973 return 1;
974 }
975
976
977 long
onUpdAddView(FXObject * sender,FXSelector,void * ptr)978 GUIApplicationWindow::onUpdAddView(FXObject* sender, FXSelector, void* ptr) {
979 sender->handle(this,
980 myAmLoading || !myRunThread->simulationAvailable()
981 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
982 ptr);
983 return 1;
984 }
985
986
987 long
onCmdStart(FXObject *,FXSelector,void *)988 GUIApplicationWindow::onCmdStart(FXObject*, FXSelector, void*) {
989 // check whether a net was loaded successfully
990 if (!myRunThread->simulationAvailable()) {
991 myStatusbar->getStatusLine()->setText("No simulation loaded!");
992 return 1;
993 }
994 // check whether it was started before and paused;
995 if (!myWasStarted) {
996 myRunThread->begin();
997 myWasStarted = true;
998 }
999 myRunThread->resume();
1000 getApp()->forceRefresh(); // only callking myToolBar2->forceRefresh somehow loses keyboard focus
1001 return 1;
1002 }
1003
1004
1005 long
onCmdStop(FXObject *,FXSelector,void *)1006 GUIApplicationWindow::onCmdStop(FXObject*, FXSelector, void*) {
1007 myRunThread->stop();
1008 getApp()->forceRefresh(); // only callking myToolBar2->forceRefresh somehow loses keyboard focus
1009 return 1;
1010 }
1011
1012
1013 long
onCmdStep(FXObject *,FXSelector,void *)1014 GUIApplicationWindow::onCmdStep(FXObject*, FXSelector, void*) {
1015 // check whether a net was loaded successfully
1016 if (!myRunThread->simulationAvailable()) {
1017 myStatusbar->getStatusLine()->setText("No simulation loaded!");
1018 return 1;
1019 }
1020 // check whether it was started before and paused;
1021 if (!myWasStarted) {
1022 myRunThread->begin();
1023 myWasStarted = true;
1024 }
1025 myRunThread->singleStep();
1026 return 1;
1027 }
1028
1029
1030 long
onCmdSaveState(FXObject *,FXSelector,void *)1031 GUIApplicationWindow::onCmdSaveState(FXObject*, FXSelector, void*) {
1032 // get the new file name
1033 FXFileDialog opendialog(this, "Save Simulation State");
1034 opendialog.setIcon(GUIIconSubSys::getIcon(ICON_SAVE));
1035 opendialog.setSelectMode(SELECTFILE_ANY);
1036 opendialog.setPatternList("Binary State (*.sbx)\nXML State (*.xml)");
1037 if (gCurrentFolder.length() != 0) {
1038 opendialog.setDirectory(gCurrentFolder);
1039 }
1040 if (!opendialog.execute() || !MFXUtils::userPermitsOverwritingWhenFileExists(this, opendialog.getFilename())) {
1041 return 1;
1042 }
1043
1044 FXString file = MFXUtils::assureExtension(opendialog.getFilename(),
1045 opendialog.getPatternText(opendialog.getCurrentPattern()).after('.').before(')'));
1046 MSStateHandler::saveState(file.text(), MSNet::getInstance()->getCurrentTimeStep());
1047 myStatusbar->getStatusLine()->setText("Simulation saved to " + file);
1048 return 1;
1049 }
1050
1051
1052 long
onCmdTimeToggle(FXObject *,FXSelector,void *)1053 GUIApplicationWindow::onCmdTimeToggle(FXObject*, FXSelector, void*) {
1054 myShowTimeAsHMS = !myShowTimeAsHMS;
1055 if (myRunThread->simulationAvailable()) {
1056 updateTimeLCD(myRunThread->getNet().getCurrentTimeStep());
1057 }
1058 return 1;
1059 }
1060
1061
1062 long
onCmdDelayToggle(FXObject *,FXSelector,void *)1063 GUIApplicationWindow::onCmdDelayToggle(FXObject*, FXSelector, void*) {
1064 const double tmp = myAlternateSimDelay;
1065 myAlternateSimDelay = mySimDelay;
1066 mySimDelay = tmp;
1067 return 1;
1068 }
1069
1070
1071 long
onCmdDemandScale(FXObject *,FXSelector,void *)1072 GUIApplicationWindow::onCmdDemandScale(FXObject*, FXSelector, void*) {
1073 if (myRunThread->simulationAvailable()) {
1074 myRunThread->getNet().getVehicleControl().setScale(myDemandScaleSpinner->getValue());
1075 }
1076 return 1;
1077 }
1078
1079
1080 long
onCmdClearMsgWindow(FXObject *,FXSelector,void *)1081 GUIApplicationWindow::onCmdClearMsgWindow(FXObject*, FXSelector, void*) {
1082 myMessageWindow->clear();
1083 return 1;
1084 }
1085
1086
1087 long
onUpdStart(FXObject * sender,FXSelector,void * ptr)1088 GUIApplicationWindow::onUpdStart(FXObject* sender, FXSelector, void* ptr) {
1089 sender->handle(this,
1090 !myRunThread->simulationIsStartable() || myAmLoading
1091 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
1092 ptr);
1093 return 1;
1094 }
1095
1096
1097 long
onUpdStop(FXObject * sender,FXSelector,void * ptr)1098 GUIApplicationWindow::onUpdStop(FXObject* sender, FXSelector, void* ptr) {
1099 sender->handle(this,
1100 !myRunThread->simulationIsStopable() || myAmLoading
1101 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
1102 ptr);
1103 return 1;
1104 }
1105
1106
1107 long
onUpdStep(FXObject * sender,FXSelector,void * ptr)1108 GUIApplicationWindow::onUpdStep(FXObject* sender, FXSelector, void* ptr) {
1109 sender->handle(this,
1110 !myRunThread->simulationIsStepable() || myAmLoading
1111 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
1112 ptr);
1113 return 1;
1114 }
1115
1116
1117 long
onUpdNeedsSimulation(FXObject * sender,FXSelector,void * ptr)1118 GUIApplicationWindow::onUpdNeedsSimulation(FXObject* sender, FXSelector, void* ptr) {
1119 bool disable = !myRunThread->simulationAvailable() || myAmLoading;
1120 sender->handle(this, disable ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
1121 // mySelectLanesMenuCascade has to be disabled manually
1122 if (disable) {
1123 mySelectLanesMenuCascade->disable();
1124 } else {
1125 mySelectLanesMenuCascade->enable();
1126 }
1127 return 1;
1128 }
1129
1130 long
onUpdTraCIStatus(FXObject * sender,FXSelector,void * ptr)1131 GUIApplicationWindow::onUpdTraCIStatus(FXObject* sender, FXSelector, void* ptr) {
1132 sender->handle(this, TraCIServer::getInstance() == nullptr ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
1133 return 1;
1134 }
1135
1136
1137 long
onCmdLocate(FXObject *,FXSelector sel,void *)1138 GUIApplicationWindow::onCmdLocate(FXObject*, FXSelector sel, void*) {
1139 if (myMDIClient->numChildren() > 0) {
1140 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1141 if (w != nullptr) {
1142 w->onCmdLocate(nullptr, sel, nullptr);
1143 }
1144 }
1145 return 1;
1146 }
1147
1148
1149 long
onCmdShowStats(FXObject *,FXSelector,void *)1150 GUIApplicationWindow::onCmdShowStats(FXObject*, FXSelector, void*) {
1151 if (myMDIClient->numChildren() > 0) {
1152 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1153 GUINet::getGUIInstance()->getParameterWindow(*this, *w->getView());
1154 }
1155 return 1;
1156 }
1157
1158
1159 long
onCmdAppSettings(FXObject *,FXSelector,void *)1160 GUIApplicationWindow::onCmdAppSettings(FXObject*, FXSelector, void*) {
1161 GUIDialog_AppSettings* d = new GUIDialog_AppSettings(this);
1162 d->create();
1163 d->show(PLACEMENT_OWNER);
1164 return 1;
1165 }
1166
1167
1168 long
onCmdGaming(FXObject *,FXSelector,void *)1169 GUIApplicationWindow::onCmdGaming(FXObject*, FXSelector, void*) {
1170 myAmGaming = !myAmGaming;
1171 if (myAmGaming) {
1172 myMenuBar->hide();
1173 myStatusbar->hide();
1174 myToolBar1->hide();
1175 myToolBar2->hide();
1176 myToolBar4->hide();
1177 myToolBar5->hide();
1178 myToolBar6->show();
1179 myToolBar8->hide();
1180 if (myTLSGame) {
1181 myToolBar7->show();
1182 } else {
1183 myToolBar9->show();
1184 }
1185 myMessageWindow->hide();
1186 myLCDLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
1187 myWaitingTimeLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
1188 myTimeLossLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
1189 myTotalDistanceLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
1190 gSchemeStorage.getDefault().gaming = true;
1191 } else {
1192 myMenuBar->show();
1193 myStatusbar->show();
1194 myToolBar1->show();
1195 myToolBar2->show();
1196 myToolBar4->show();
1197 myToolBar5->show();
1198 myToolBar6->hide();
1199 myToolBar7->hide();
1200 myToolBar8->show();
1201 myToolBar9->hide();
1202 myMessageWindow->show();
1203 myLCDLabel->setFgColor(MFXUtils::getFXColor(RGBColor::GREEN));
1204 gSchemeStorage.getDefault().gaming = false;
1205 }
1206 if (myMDIClient->numChildren() > 0) {
1207 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1208 if (w != nullptr) {
1209 w->setToolBarVisibility(!myAmGaming && !myAmFullScreen);
1210 }
1211 }
1212 update();
1213 return 1;
1214 }
1215
1216
1217 long
onCmdFullScreen(FXObject *,FXSelector,void *)1218 GUIApplicationWindow::onCmdFullScreen(FXObject*, FXSelector, void*) {
1219 myAmFullScreen = !myAmFullScreen;
1220 if (myAmFullScreen) {
1221 getApp()->reg().writeIntEntry("SETTINGS", "x", getX());
1222 getApp()->reg().writeIntEntry("SETTINGS", "y", getY());
1223 getApp()->reg().writeIntEntry("SETTINGS", "width", getWidth());
1224 getApp()->reg().writeIntEntry("SETTINGS", "height", getHeight());
1225 maximize();
1226 setDecorations(DECOR_NONE);
1227 place(PLACEMENT_MAXIMIZED);
1228 myMenuBar->hide();
1229 myStatusbar->hide();
1230 myToolBar1->hide();
1231 myToolBar2->hide();
1232 myToolBar3->hide();
1233 myToolBar4->hide();
1234 myToolBar5->hide();
1235 myToolBar6->hide();
1236 myToolBar7->hide();
1237 myToolBar8->hide();
1238 myMessageWindow->hide();
1239 if (myMDIClient->numChildren() > 0) {
1240 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1241 if (w != nullptr) {
1242 w->setToolBarVisibility(false);
1243 }
1244 }
1245 update();
1246 } else {
1247 place(PLACEMENT_VISIBLE);
1248 setDecorations(DECOR_ALL);
1249 restore();
1250 myToolBar3->show();
1251 myAmGaming = !myAmGaming;
1252 onCmdGaming(nullptr, 0, nullptr);
1253 setWidth(getApp()->reg().readIntEntry("SETTINGS", "width", 600));
1254 setHeight(getApp()->reg().readIntEntry("SETTINGS", "height", 400));
1255 setX(getApp()->reg().readIntEntry("SETTINGS", "x", 150));
1256 setY(getApp()->reg().readIntEntry("SETTINGS", "y", 150));
1257 }
1258 return 1;
1259 }
1260
1261
1262 long
onCmdListInternal(FXObject *,FXSelector,void *)1263 GUIApplicationWindow::onCmdListInternal(FXObject*, FXSelector, void*) {
1264 myListInternal = !myListInternal;
1265 return 1;
1266 }
1267
1268
1269 long
onCmdListParking(FXObject *,FXSelector,void *)1270 GUIApplicationWindow::onCmdListParking(FXObject*, FXSelector, void*) {
1271 myListParking = !myListParking;
1272 return 1;
1273 }
1274
1275 long
onCmdListTeleporting(FXObject *,FXSelector,void *)1276 GUIApplicationWindow::onCmdListTeleporting(FXObject*, FXSelector, void*) {
1277 myListTeleporting = !myListTeleporting;
1278 return 1;
1279 }
1280
1281
1282 long
onCmdNewView(FXObject *,FXSelector,void *)1283 GUIApplicationWindow::onCmdNewView(FXObject*, FXSelector, void*) {
1284 openNewView(GUISUMOViewParent::VIEW_2D_OPENGL);
1285 return 1;
1286 }
1287
1288
1289 #ifdef HAVE_OSG
1290 long
onCmdNewOSG(FXObject *,FXSelector,void *)1291 GUIApplicationWindow::onCmdNewOSG(FXObject*, FXSelector, void*) {
1292 openNewView(GUISUMOViewParent::VIEW_3D_OSG);
1293 return 1;
1294 }
1295 #endif
1296
1297
1298 long
onCmdAbout(FXObject *,FXSelector,void *)1299 GUIApplicationWindow::onCmdAbout(FXObject*, FXSelector, void*) {
1300 GUIDialog_AboutSUMO* about = new GUIDialog_AboutSUMO(this);
1301 about->create();
1302 about->show(PLACEMENT_OWNER);
1303 return 1;
1304 }
1305
1306
onClipboardRequest(FXObject *,FXSelector,void * ptr)1307 long GUIApplicationWindow::onClipboardRequest(FXObject* /* sender */, FXSelector /* sel */, void* ptr) {
1308 FXEvent* event = (FXEvent*)ptr;
1309 FXString string = GUIUserIO::clipped.c_str();
1310 setDNDData(FROM_CLIPBOARD, event->target, string);
1311 return 1;
1312 }
1313
1314
1315 long
onLoadThreadEvent(FXObject *,FXSelector,void *)1316 GUIApplicationWindow::onLoadThreadEvent(FXObject*, FXSelector, void*) {
1317 eventOccurred();
1318 return 1;
1319 }
1320
1321
1322 long
onRunThreadEvent(FXObject *,FXSelector,void *)1323 GUIApplicationWindow::onRunThreadEvent(FXObject*, FXSelector, void*) {
1324 eventOccurred();
1325 return 1;
1326 }
1327
1328
1329 void
eventOccurred()1330 GUIApplicationWindow::eventOccurred() {
1331 while (!myEvents.empty()) {
1332 // get the next event
1333 GUIEvent* e = myEvents.top();
1334 myEvents.pop();
1335 // process
1336 switch (e->getOwnType()) {
1337 case EVENT_SIMULATION_LOADED:
1338 handleEvent_SimulationLoaded(e);
1339 break;
1340 case EVENT_SIMULATION_STEP:
1341 if (myRunThread->simulationAvailable()) { // avoid race-condition related crash if reload was pressed
1342 handleEvent_SimulationStep(e);
1343 }
1344 break;
1345 case EVENT_MESSAGE_OCCURRED:
1346 case EVENT_WARNING_OCCURRED:
1347 case EVENT_ERROR_OCCURRED:
1348 case EVENT_DEBUG_OCCURRED:
1349 case EVENT_GLDEBUG_OCCURRED:
1350 case EVENT_STATUS_OCCURRED:
1351 handleEvent_Message(e);
1352 break;
1353 case EVENT_SIMULATION_ENDED:
1354 handleEvent_SimulationEnded(e);
1355 break;
1356 default:
1357 break;
1358 }
1359 delete e;
1360 }
1361 myToolBar2->forceRefresh();
1362 myToolBar3->forceRefresh();
1363 }
1364
1365
1366 void
handleEvent_SimulationLoaded(GUIEvent * e)1367 GUIApplicationWindow::handleEvent_SimulationLoaded(GUIEvent* e) {
1368 myAmLoading = false;
1369 GUIEvent_SimulationLoaded* ec = static_cast<GUIEvent_SimulationLoaded*>(e);
1370 // check whether the loading was successfull
1371 if (ec->myNet == nullptr) {
1372 // report failure
1373 setStatusBarText("Loading of '" + ec->myFile + "' failed!");
1374 if (GUIGlobals::gQuitOnEnd) {
1375 closeAllWindows();
1376 getApp()->exit(1);
1377 }
1378 } else {
1379 // initialise simulation thread
1380 if (!myRunThread->init(ec->myNet, ec->myBegin, ec->myEnd)) {
1381 if (GUIGlobals::gQuitOnEnd) {
1382 closeAllWindows();
1383 getApp()->exit(1);
1384 }
1385 } else {
1386 // report success
1387 setStatusBarText("'" + ec->myFile + "' loaded.");
1388 setWindowSizeAndPos();
1389 myWasStarted = false;
1390 myHaveNotifiedAboutSimEnd = false;
1391 // initialise views
1392 myViewNumber = 0;
1393 const GUISUMOViewParent::ViewType defaultType = ec->myOsgView ? GUISUMOViewParent::VIEW_3D_OSG : GUISUMOViewParent::VIEW_2D_OPENGL;
1394 if (ec->mySettingsFiles.size() > 0) {
1395 // open a view for each file and apply settings
1396 for (std::vector<std::string>::const_iterator it = ec->mySettingsFiles.begin(); it != ec->mySettingsFiles.end(); ++it) {
1397 GUISettingsHandler settings(*it);
1398 GUISUMOViewParent::ViewType vt = defaultType;
1399 if (settings.getViewType() == "osg" || settings.getViewType() == "3d") {
1400 vt = GUISUMOViewParent::VIEW_3D_OSG;
1401 }
1402 if (settings.getViewType() == "opengl" || settings.getViewType() == "2d") {
1403 vt = GUISUMOViewParent::VIEW_2D_OPENGL;
1404 }
1405 GUISUMOAbstractView* view = openNewView(vt);
1406 if (view == nullptr) {
1407 break;
1408 }
1409 std::string settingsName = settings.addSettings(view);
1410 view->addDecals(settings.getDecals());
1411 settings.applyViewport(view);
1412 settings.setSnapshots(view);
1413 if (settings.getDelay() > 0.) {
1414 mySimDelay = settings.getDelay();
1415 }
1416 if (settings.getBreakpoints().size() > 0) {
1417 myRunThread->getBreakpointLock().lock();
1418 myRunThread->getBreakpoints().assign(settings.getBreakpoints().begin(), settings.getBreakpoints().end());
1419 myRunThread->getBreakpointLock().unlock();
1420 }
1421 if (!OptionsCont::getOptions().isDefault("breakpoints")) {
1422 std::vector<SUMOTime> breakpoints;
1423 for (const std::string& val : OptionsCont::getOptions().getStringVector("breakpoints")) {
1424 breakpoints.push_back(string2time(val));
1425 }
1426 std::sort(breakpoints.begin(), breakpoints.end());
1427 myRunThread->getBreakpointLock().lock();
1428 myRunThread->getBreakpoints().assign(breakpoints.begin(), breakpoints.end());
1429 myRunThread->getBreakpointLock().unlock();
1430 }
1431 myJamSounds = settings.getEventDistribution("jam");
1432 myCollisionSounds = settings.getEventDistribution("collision");
1433 if (settings.getJamSoundTime() > 0) {
1434 myJamSoundTime = settings.getJamSoundTime();
1435 }
1436 }
1437 } else {
1438 openNewView(defaultType);
1439 }
1440 if (!OptionsCont::getOptions().isDefault("breakpoints")) {
1441 std::vector<SUMOTime> breakpoints;
1442 for (const std::string& val : OptionsCont::getOptions().getStringVector("breakpoints")) {
1443 breakpoints.push_back(string2time(val));
1444 }
1445 std::sort(breakpoints.begin(), breakpoints.end());
1446 myRunThread->getBreakpointLock().lock();
1447 myRunThread->getBreakpoints().assign(breakpoints.begin(), breakpoints.end());
1448 myRunThread->getBreakpointLock().unlock();
1449 }
1450
1451 if (OptionsCont::getOptions().getBool("game")) {
1452 if (OptionsCont::getOptions().getString("game.mode") == "tls") {
1453 myTLSGame = true;
1454 setTitle("SUMO Interactive Traffic Light");
1455 } else {
1456 myTLSGame = false;
1457 setTitle("SUMO Interactive Demand-Responsive-Transport");
1458 }
1459 onCmdGaming(nullptr, 0, nullptr);
1460 } else {
1461 // set simulation name on the caption
1462 setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING, ec->myFile.c_str()));
1463 }
1464 if (ec->myViewportFromRegistry) {
1465 Position off;
1466 off.set(getApp()->reg().readRealEntry("viewport", "x"),
1467 getApp()->reg().readRealEntry("viewport", "y"),
1468 getApp()->reg().readRealEntry("viewport", "z"));
1469 Position p(off.x(), off.y(), 0);
1470 GUISUMOAbstractView* view = myGLWindows[0]->getView();
1471 view->setViewportFromToRot(off, p, 0);
1472 }
1473 // set simulation step begin information
1474 myLCDLabel->setText("----------------");
1475 for (std::vector<FXButton*>::const_iterator it = myStatButtons.begin(); it != myStatButtons.end(); ++it) {
1476 (*it)->setText("-");
1477 }
1478 // initialize scale from options
1479 myDemandScaleSpinner->setValue(OptionsCont::getOptions().getFloat("scale"));
1480 }
1481 }
1482 getApp()->endWaitCursor();
1483 // start if wished
1484 if (GUIGlobals::gRunAfterLoad && ec->myNet != nullptr && myRunThread->simulationIsStartable()) {
1485 onCmdStart(nullptr, 0, nullptr);
1486 }
1487 update();
1488 }
1489
1490
1491 void
handleEvent_SimulationStep(GUIEvent *)1492 GUIApplicationWindow::handleEvent_SimulationStep(GUIEvent*) {
1493 updateTimeLCD(myRunThread->getNet().getCurrentTimeStep());
1494 const int running = myRunThread->getNet().getVehicleControl().getRunningVehicleNo();
1495 const int backlog = myRunThread->getNet().getInsertionControl().getWaitingVehicleNo();
1496 if (backlog > running) {
1497 if (myStatButtons.front()->getIcon() == GUIIconSubSys::getIcon(ICON_GREENVEHICLE)) {
1498 myStatButtons.front()->setIcon(GUIIconSubSys::getIcon(ICON_YELLOWVEHICLE));
1499 }
1500 } else {
1501 if (myStatButtons.front()->getIcon() == GUIIconSubSys::getIcon(ICON_YELLOWVEHICLE)) {
1502 myStatButtons.front()->setIcon(GUIIconSubSys::getIcon(ICON_GREENVEHICLE));
1503 }
1504 }
1505 myStatButtons.front()->setText(toString(running).c_str());
1506 if (myRunThread->getNet().hasPersons()) {
1507 if (!myStatButtons[1]->shown()) {
1508 myStatButtons[1]->show();
1509 }
1510 myStatButtons[1]->setText(toString(myRunThread->getNet().getPersonControl().getRunningNumber()).c_str());
1511 }
1512 if (myRunThread->getNet().hasContainers()) {
1513 if (!myStatButtons[2]->shown()) {
1514 myStatButtons[2]->show();
1515 }
1516 myStatButtons[2]->setText(toString(myRunThread->getNet().getContainerControl().getRunningNumber()).c_str());
1517 }
1518 if (myAmGaming) {
1519 if (myTLSGame) {
1520 checkGamingEvents();
1521 } else {
1522 checkGamingEventsDRT();
1523 }
1524 }
1525 if (myRunThread->simulationIsStartable()) {
1526 getApp()->forceRefresh(); // restores keyboard focus
1527 }
1528 updateChildren();
1529 update();
1530 }
1531
1532
1533 void
handleEvent_Message(GUIEvent * e)1534 GUIApplicationWindow::handleEvent_Message(GUIEvent* e) {
1535 GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);
1536 if (ec->getOwnType() == EVENT_STATUS_OCCURRED) {
1537 setStatusBarText(ec->getMsg());
1538 } else {
1539 myMessageWindow->appendMsg(ec->getOwnType(), ec->getMsg());
1540 }
1541 }
1542
1543
1544 void
handleEvent_SimulationEnded(GUIEvent * e)1545 GUIApplicationWindow::handleEvent_SimulationEnded(GUIEvent* e) {
1546 GUIEvent_SimulationEnded* ec = static_cast<GUIEvent_SimulationEnded*>(e);
1547 onCmdStop(nullptr, 0, nullptr);
1548 if (ec->getReason() == MSNet::SIMSTATE_LOADING) {
1549 onCmdReload(nullptr, 0, nullptr);
1550 } else if (GUIGlobals::gQuitOnEnd) {
1551 closeAllWindows();
1552 getApp()->exit(ec->getReason() == MSNet::SIMSTATE_ERROR_IN_SIM);
1553 } else if (GUIGlobals::gDemoAutoReload) {
1554 onCmdReload(nullptr, 0, nullptr);
1555 } else if (!myHaveNotifiedAboutSimEnd) {
1556 // build the text
1557 const std::string text = "Simulation ended at time: " + time2string(ec->getTimeStep()) +
1558 ".\nReason: " + MSNet::getStateMessage(ec->getReason()) +
1559 "\nDo you want to close all open files and views?";
1560 FXuint answer = FXMessageBox::question(this, MBOX_YES_NO, "Simulation ended", "%s", text.c_str());
1561 if (answer == 1) { //1:yes, 2:no, 4:esc
1562 closeAllWindows();
1563 }
1564 myHaveNotifiedAboutSimEnd = true;
1565 }
1566 }
1567
1568
1569 void
checkGamingEvents()1570 GUIApplicationWindow::checkGamingEvents() {
1571 MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
1572 MSVehicleControl::constVehIt it = vc.loadedVehBegin();
1573 MSVehicleControl::constVehIt end = vc.loadedVehEnd();
1574 #ifdef HAVE_DANGEROUS_SOUNDS // disable user-configurable command execution for public build
1575 if (myJamSounds.getOverallProb() > 0) {
1576 // play honking sound if some vehicle is waiting too long
1577 for (; it != end; ++it) {
1578 // XXX use impatience instead of waiting time ?
1579 if (it->second->getWaitingTime() > TIME2STEPS(myJamSoundTime)) {
1580 const std::string cmd = myJamSounds.get(&myGamingRNG);
1581 if (cmd != "") {
1582 // yay! fun with dangerous commands... Never use this over the internet
1583 SysUtils::runHiddenCommand(cmd);
1584 // one sound per simulation step is enough
1585 break;
1586 }
1587 }
1588 }
1589 }
1590 if (myCollisionSounds.getOverallProb() > 0) {
1591 int collisions = MSNet::getInstance()->getVehicleControl().getCollisionCount();
1592 if (myPreviousCollisionNumber != collisions) {
1593 const std::string cmd = myCollisionSounds.get(&myGamingRNG);
1594 if (cmd != "") {
1595 // yay! fun with dangerous commands... Never use this over the internet
1596 SysUtils::runHiddenCommand(cmd);
1597 }
1598 myPreviousCollisionNumber = collisions;
1599 }
1600 }
1601 #endif
1602
1603 // update performance indicators
1604 for (it = vc.loadedVehBegin(); it != end; ++it) {
1605 const MSVehicle* veh = dynamic_cast<MSVehicle*>(it->second);
1606 assert(veh != 0);
1607 if (veh->isOnRoad() && !veh->isStopped()) {
1608 const double vmax = MIN2(veh->getVehicleType().getMaxSpeed(), veh->getEdge()->getSpeedLimit());
1609 if (veh->getSpeed() < SUMO_const_haltingSpeed) {
1610 myWaitingTime += DELTA_T;
1611 }
1612 myTimeLoss += TIME2STEPS(TS * (vmax - veh->getSpeed()) / vmax); // may be negative with speedFactor > 1
1613 }
1614 }
1615 myWaitingTimeLabel->setText(time2string(myWaitingTime).c_str());
1616 myTimeLossLabel->setText(time2string(myTimeLoss).c_str());
1617 }
1618
1619 void
checkGamingEventsDRT()1620 GUIApplicationWindow::checkGamingEventsDRT() {
1621 // update performance indicators
1622 MSTransportableControl& pc = myRunThread->getNet().getPersonControl();
1623 myWaitingTime += pc.getWaitingForVehicleNumber() * DELTA_T;
1624 myWaitingTimeLabel->setText(time2string(myWaitingTime).c_str());
1625
1626 MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
1627 MSVehicleControl::constVehIt end = vc.loadedVehEnd();
1628 for (auto it = vc.loadedVehBegin(); it != end; ++it) {
1629 const MSVehicle* veh = dynamic_cast<MSVehicle*>(it->second);
1630 assert(veh != 0);
1631 if (veh->isOnRoad() && !veh->isStopped()) {
1632 myTotalDistance += SPEED2DIST(veh->getSpeed());
1633 }
1634 }
1635 myTotalDistanceLabel->setText(toString(myTotalDistance / 100).c_str());
1636 }
1637
1638 void
loadConfigOrNet(const std::string & file,bool isNet)1639 GUIApplicationWindow::loadConfigOrNet(const std::string& file, bool isNet) {
1640 storeWindowSizeAndPos();
1641 getApp()->beginWaitCursor();
1642 myAmLoading = true;
1643 closeAllWindows();
1644 gSchemeStorage.saveViewport(0, 0, -1, 0); // recenter view
1645 myLoadThread->loadConfigOrNet(file, isNet);
1646 setStatusBarText("Loading '" + file + "'.");
1647 update();
1648 }
1649
1650
1651 GUISUMOAbstractView*
openNewView(GUISUMOViewParent::ViewType vt)1652 GUIApplicationWindow::openNewView(GUISUMOViewParent::ViewType vt) {
1653 if (!myRunThread->simulationAvailable()) {
1654 myStatusbar->getStatusLine()->setText("No simulation loaded!");
1655 return nullptr;
1656 }
1657 GUISUMOAbstractView* oldView = nullptr;
1658 if (myMDIClient->numChildren() > 0) {
1659 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1660 if (w != nullptr) {
1661 oldView = w->getView();
1662 }
1663 }
1664 std::string caption = "View #" + toString(myViewNumber++);
1665 FXuint opts = MDI_TRACKING;
1666 GUISUMOViewParent* w = new GUISUMOViewParent(myMDIClient, myMDIMenu, FXString(caption.c_str()),
1667 this, GUIIconSubSys::getIcon(ICON_SUMO_MINI), opts, 10, 10, 300, 200);
1668 GUISUMOAbstractView* v = w->init(getBuildGLCanvas(), myRunThread->getNet(), vt);
1669 if (oldView != nullptr) {
1670 // copy viewport
1671 oldView->copyViewportTo(v);
1672 }
1673 w->create();
1674 if (myMDIClient->numChildren() == 1) {
1675 w->maximize();
1676 } else {
1677 myMDIClient->vertical(true);
1678 }
1679 myMDIClient->setActiveChild(w);
1680
1681 return v;
1682 }
1683
1684
1685 FXGLCanvas*
getBuildGLCanvas() const1686 GUIApplicationWindow::getBuildGLCanvas() const {
1687 if (myMDIClient->numChildren() == 0) {
1688 return nullptr;
1689 }
1690 GUISUMOViewParent* share_tmp1 =
1691 static_cast<GUISUMOViewParent*>(myMDIClient->childAtIndex(0));
1692 return share_tmp1->getBuildGLCanvas();
1693 }
1694
1695
1696 void
closeAllWindows()1697 GUIApplicationWindow::closeAllWindows() {
1698 myTrackerLock.lock();
1699 myLCDLabel->setText("----------------");
1700 for (std::vector<FXButton*>::const_iterator it = myStatButtons.begin(); it != myStatButtons.end(); ++it) {
1701 (*it)->setText("-");
1702 if (it != myStatButtons.begin()) {
1703 (*it)->hide();
1704 }
1705 }
1706 // delete the simulation
1707 myRunThread->deleteSim();
1708 // reset the caption
1709 setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING));
1710 // remove trackers and other external windows (must be delayed until deleteSim)
1711 while (!myGLWindows.empty()) {
1712 delete myGLWindows.front();
1713 }
1714 for (FXMainWindow* const window : myTrackerWindows) {
1715 delete window;
1716 }
1717 myTrackerWindows.clear();
1718 // clear selected items
1719 gSelected.clear();
1720 // add a separator to the log
1721 myMessageWindow->addSeparator();
1722 myTrackerLock.unlock();
1723 // remove coordinate information
1724 myGeoCoordinate->setText("N/A");
1725 myCartesianCoordinate->setText("N/A");
1726 //
1727 GUITexturesHelper::clearTextures();
1728 GLHelper::resetFont();
1729 update();
1730 }
1731
1732
1733 FXCursor*
getDefaultCursor()1734 GUIApplicationWindow::getDefaultCursor() {
1735 return getApp()->getDefaultCursor(DEF_ARROW_CURSOR);
1736 }
1737
1738
1739 SUMOTime
getCurrentSimTime() const1740 GUIApplicationWindow::getCurrentSimTime() const {
1741 return myRunThread->getNet().getCurrentTimeStep();
1742 }
1743
1744
1745 double
getTrackerInterval() const1746 GUIApplicationWindow::getTrackerInterval() const {
1747 return GUIGlobals::gTrackerInterval;
1748 }
1749
1750
1751 void
loadOnStartup()1752 GUIApplicationWindow::loadOnStartup() {
1753 loadConfigOrNet("", false);
1754 }
1755
1756
1757 void
setStatusBarText(const std::string & text)1758 GUIApplicationWindow::setStatusBarText(const std::string& text) {
1759 myStatusbar->getStatusLine()->setText(text.c_str());
1760
1761 myStatusbar->getStatusLine()->setNormalText(text.c_str());
1762 }
1763
1764
1765 void
addRecentFile(const FX::FXString & f,const bool isNet)1766 GUIApplicationWindow::addRecentFile(const FX::FXString& f, const bool isNet) {
1767 if (isNet) {
1768 myRecentNets.appendFile(f);
1769 } else {
1770 myRecentConfigs.appendFile(f);
1771 }
1772 }
1773
1774
1775 void
updateTimeLCD(SUMOTime time)1776 GUIApplicationWindow::updateTimeLCD(SUMOTime time) {
1777 time -= DELTA_T; // synchronize displayed time with netstate output
1778 if (time < 0) {
1779 myLCDLabel->setText("----------------");
1780 return;
1781 }
1782 if (myAmGaming) {
1783 // show time counting backwards
1784 time = myRunThread->getSimEndTime() - time;
1785 }
1786 std::ostringstream str;
1787 str << std::setfill('0');
1788 const bool hideFraction = myAmGaming || DELTA_T % 1000 == 0;
1789 if (myShowTimeAsHMS) {
1790 SUMOTime day = time / 86400000;
1791 if (day > 0) {
1792 str << day << '-';
1793 time %= 86400000;
1794 }
1795 str << std::setw(2);
1796 str << time / 3600000 << '-';
1797 time %= 3600000;
1798 str << std::setw(2) << time / 60000 << '-';
1799 time %= 60000;
1800 }
1801 str << std::setw(2) << time / 1000;
1802 if (!hideFraction) {
1803 str << '.' << std::setw(3) << time % 1000;
1804 }
1805 myLCDLabel->setText(str.str().c_str());
1806 }
1807
1808
1809 long
onKeyPress(FXObject * o,FXSelector sel,void * data)1810 GUIApplicationWindow::onKeyPress(FXObject* o, FXSelector sel, void* data) {
1811 const long handled = FXMainWindow::onKeyPress(o, sel, data);
1812 if (handled == 0 && myMDIClient->numChildren() > 0) {
1813 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1814 if (w != nullptr) {
1815 w->onKeyPress(nullptr, sel, data);
1816 }
1817 }
1818 return 0;
1819 }
1820
1821
1822 long
onKeyRelease(FXObject * o,FXSelector sel,void * data)1823 GUIApplicationWindow::onKeyRelease(FXObject* o, FXSelector sel, void* data) {
1824 const long handled = FXMainWindow::onKeyRelease(o, sel, data);
1825 if (handled == 0 && myMDIClient->numChildren() > 0) {
1826 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
1827 if (w != nullptr) {
1828 w->onKeyRelease(nullptr, sel, data);
1829 }
1830 }
1831 return 0;
1832 }
1833
1834
1835 void
sendBlockingEvent(GUIEvent * event)1836 GUIApplicationWindow::sendBlockingEvent(GUIEvent* event) {
1837 myEventMutex.lock();
1838 myEvents.push_back(event);
1839 myRunThreadEvent.signal();
1840 myEventCondition.wait(myEventMutex);
1841 myEventMutex.unlock();
1842 }
1843
1844 void
setBreakpoints(const std::vector<SUMOTime> & breakpoints)1845 GUIApplicationWindow::setBreakpoints(const std::vector<SUMOTime>& breakpoints) {
1846 if (myRunThread != nullptr) {
1847 myRunThread->getBreakpointLock().lock();
1848 myRunThread->getBreakpoints().assign(breakpoints.begin(), breakpoints.end());
1849 myRunThread->getBreakpointLock().unlock();
1850 }
1851 }
1852
1853 const std::vector<SUMOTime>
retrieveBreakpoints() const1854 GUIApplicationWindow::retrieveBreakpoints() const {
1855 myRunThread->getBreakpointLock().lock();
1856 std::vector<SUMOTime> result = myRunThread->getBreakpoints();
1857 myRunThread->getBreakpointLock().unlock();
1858 return result;
1859 }
1860
1861 /****************************************************************************/
1862