SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUIApplicationWindow.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // The main window of the SUMO-gui.
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #ifdef HAVE_VERSION_H
35 #include <version.h>
36 #endif
37 
38 #include <string>
39 #include <sstream>
40 #include <algorithm>
41 
42 #include <guisim/GUINet.h>
43 #include <guisim/GUILane.h>
44 #include <microsim/MSEdge.h>
45 #include <microsim/MSVehicle.h>
46 
47 #include "GUISUMOViewParent.h"
48 #include "GUILoadThread.h"
49 #include "GUIRunThread.h"
50 #include "GUIApplicationWindow.h"
53 
54 #include <utils/common/ToString.h>
60 
76 #include "GUIGlobals.h"
80 
81 #ifdef CHECK_MEMORY_LEAKS
82 #include <foreign/nvwa/debug_new.h>
83 #endif
84 
85 
86 // ===========================================================================
87 // FOX-declarations
88 // ===========================================================================
89 FXDEFMAP(GUIApplicationWindow) GUIApplicationWindowMap[] = {
90  FXMAPFUNC(SEL_COMMAND, MID_QUIT, GUIApplicationWindow::onCmdQuit),
91  FXMAPFUNC(SEL_SIGNAL, MID_QUIT, GUIApplicationWindow::onCmdQuit),
92  FXMAPFUNC(SEL_CLOSE, MID_WINDOW, GUIApplicationWindow::onCmdQuit),
93 
97  FXMAPFUNC(SEL_COMMAND, MID_RELOAD, GUIApplicationWindow::onCmdReload),
98  FXMAPFUNC(SEL_COMMAND, MID_CLOSE, GUIApplicationWindow::onCmdClose),
101 
103  FXMAPFUNC(SEL_COMMAND, MID_GAMING, GUIApplicationWindow::onCmdGaming),
105  FXMAPFUNC(SEL_COMMAND, MID_ABOUT, GUIApplicationWindow::onCmdAbout),
106  FXMAPFUNC(SEL_COMMAND, MID_NEW_MICROVIEW, GUIApplicationWindow::onCmdNewView),
107 #ifdef HAVE_OSG
108  FXMAPFUNC(SEL_COMMAND, MID_NEW_OSGVIEW, GUIApplicationWindow::onCmdNewOSG),
109 #endif
110  FXMAPFUNC(SEL_COMMAND, MID_START, GUIApplicationWindow::onCmdStart),
111  FXMAPFUNC(SEL_COMMAND, MID_STOP, GUIApplicationWindow::onCmdStop),
112  FXMAPFUNC(SEL_COMMAND, MID_STEP, GUIApplicationWindow::onCmdStep),
116 
117  FXMAPFUNC(SEL_UPDATE, MID_OPEN_CONFIG, GUIApplicationWindow::onUpdOpen),
118  FXMAPFUNC(SEL_UPDATE, MID_OPEN_NETWORK, GUIApplicationWindow::onUpdOpen),
119  FXMAPFUNC(SEL_UPDATE, MID_RELOAD, GUIApplicationWindow::onUpdReload),
122 #ifdef HAVE_OSG
123  FXMAPFUNC(SEL_COMMAND, MID_NEW_OSGVIEW, GUIApplicationWindow::onUpdAddView),
124 #endif
125  FXMAPFUNC(SEL_UPDATE, MID_START, GUIApplicationWindow::onUpdStart),
126  FXMAPFUNC(SEL_UPDATE, MID_STOP, GUIApplicationWindow::onUpdStop),
127  FXMAPFUNC(SEL_UPDATE, MID_STEP, GUIApplicationWindow::onUpdStep),
130 
131  // forward requests to the active view
132  FXMAPFUNC(SEL_COMMAND, MID_LOCATEJUNCTION, GUIApplicationWindow::onCmdLocate),
133  FXMAPFUNC(SEL_COMMAND, MID_LOCATEEDGE, GUIApplicationWindow::onCmdLocate),
134  FXMAPFUNC(SEL_COMMAND, MID_LOCATEVEHICLE, GUIApplicationWindow::onCmdLocate),
135  FXMAPFUNC(SEL_COMMAND, MID_LOCATETLS, GUIApplicationWindow::onCmdLocate),
136  FXMAPFUNC(SEL_COMMAND, MID_LOCATEADD, GUIApplicationWindow::onCmdLocate),
137  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOI, GUIApplicationWindow::onCmdLocate),
138  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOLY, GUIApplicationWindow::onCmdLocate),
146 
147  FXMAPFUNC(SEL_CLIPBOARD_REQUEST, 0, GUIApplicationWindow::onClipboardRequest),
148 
153 };
154 
155 // Object implementation
156 FXIMPLEMENT(GUIApplicationWindow, FXMainWindow, GUIApplicationWindowMap, ARRAYNUMBER(GUIApplicationWindowMap))
157 
158 // ===========================================================================
159 // static members
160 // ===========================================================================
161 MTRand GUIApplicationWindow::myGamingRNG;
162 
163 // ===========================================================================
164 // member method definitions
165 // ===========================================================================
167  const std::string& configPattern)
168  : GUIMainWindow(a),
169  myLoadThread(0), myRunThread(0),
170  myAmLoading(false),
171  myAlternateSimDelay(0),
172  myRecentNets(a, "nets"), myConfigPattern(configPattern),
173  hadDependentBuild(false),
174  myShowTimeAsHMS(false),
175  // game specific
176  myJamSoundTime(60),
177  myWaitingTime(0),
178  myTimeLoss(0) {
180 }
181 
182 
183 void
185  // do this not twice
186  if (hadDependentBuild) {
187  return;
188  }
189  hadDependentBuild = true;
190 
191  setTarget(this);
192  setSelector(MID_WINDOW);
193 
194  // build menu bar
195  myMenuBarDrag = new FXToolBarShell(this, FRAME_NORMAL);
196  myMenuBar = new FXMenuBar(myTopDock, myMenuBarDrag,
197  LAYOUT_SIDE_TOP | LAYOUT_FILL_X | FRAME_RAISED);
198  new FXToolBarGrip(myMenuBar, myMenuBar, FXMenuBar::ID_TOOLBARGRIP,
199  TOOLBARGRIP_DOUBLE);
200  buildToolBars();
201  // build the thread - io
206 
207  // build the status bar
208  myStatusbar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X | FRAME_RAISED);
209  {
210  myGeoFrame =
211  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
212  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
213  myGeoCoordinate = new FXLabel(myGeoFrame, "N/A", 0, LAYOUT_CENTER_Y);
215  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
216  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
217  myCartesianCoordinate = new FXLabel(myCartesianFrame, "N/A", 0, LAYOUT_CENTER_Y);
218  }
219 
220  // make the window a mdi-window
221  myMainSplitter = new FXSplitter(this,
222  SPLITTER_REVERSED | SPLITTER_VERTICAL | LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | FRAME_RAISED | FRAME_THICK);
223  myMDIClient = new FXMDIClient(myMainSplitter,
224  LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK);
225  myMDIMenu = new FXMDIMenu(this, myMDIClient);
226  new FXMDIWindowButton(myMenuBar, myMDIMenu, myMDIClient,
227  FXMDIClient::ID_MDI_MENUWINDOW, LAYOUT_LEFT);
228  new FXMDIDeleteButton(myMenuBar, myMDIClient,
229  FXMDIClient::ID_MDI_MENUCLOSE, FRAME_RAISED | LAYOUT_RIGHT);
230  new FXMDIRestoreButton(myMenuBar, myMDIClient,
231  FXMDIClient::ID_MDI_MENURESTORE, FRAME_RAISED | LAYOUT_RIGHT);
232  new FXMDIMinimizeButton(myMenuBar, myMDIClient,
233  FXMDIClient::ID_MDI_MENUMINIMIZE, FRAME_RAISED | LAYOUT_RIGHT);
234 
235  // build the message window
237  // fill menu and tool bar
238  fillMenuBar();
239  if (game) {
240  onCmdGaming(0, 0, 0);
241  } else {
242  myToolBar6->hide();
243  myToolBar7->hide();
244  }
245  // build additional threads
246  myLoadThread = new GUILoadThread(getApp(), this, myEvents, myLoadThreadEvent);
247  myRunThread = new GUIRunThread(getApp(), this, *mySimDelayTarget, myEvents,
249  // set the status bar
250  myStatusbar->getStatusLine()->setText("Ready.");
251  // set the caption
252  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
253 
254  // start the simulation-thread (it will loop until the application ends deciding by itself whether to perform a step or not)
255  myRunThread->start();
257 }
258 
259 
260 void
262  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 0) {
263  setX(getApp()->reg().readIntEntry("SETTINGS", "x", 150));
264  setY(getApp()->reg().readIntEntry("SETTINGS", "y", 150));
265  setWidth(getApp()->reg().readIntEntry("SETTINGS", "width", 600));
266  setHeight(getApp()->reg().readIntEntry("SETTINGS", "height", 400));
267  }
268  gCurrentFolder = getApp()->reg().readStringEntry("SETTINGS", "basedir", "");
270  myMenuBarDrag->create();
271  myToolBarDrag1->create();
272  myToolBarDrag2->create();
273  myToolBarDrag3->create();
274  myToolBarDrag4->create();
275  myToolBarDrag5->create();
276  myToolBarDrag6->create();
277  myToolBarDrag7->create();
278  myFileMenu->create();
279  mySelectByPermissions->create();
280  myEditMenu->create();
281  mySettingsMenu->create();
282  myLocatorMenu->create();
283  myControlMenu->create();
284  myWindowsMenu->create();
285  myHelpMenu->create();
286 
287  FXint width = getApp()->getNormalFont()->getTextWidth("8", 1) * 24;
288  myCartesianFrame->setWidth(width);
289  myGeoFrame->setWidth(width);
290 
291  show(PLACEMENT_SCREEN);
292  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 1) {
293  maximize();
294  }
295  myShowTimeAsHMS = (getApp()->reg().readIntEntry("gui", "timeasHMS", 0) == 1);
296  myAlternateSimDelay = getApp()->reg().readIntEntry("gui", "alternateSimDelay", 100);
297 }
298 
299 
302  myRunThread->join();
303  closeAllWindows();
304  //
306  delete myGLVisual;
307  // delete some non-parented windows
308  delete myToolBarDrag1;
309  //
310  delete myRunThread;
311  delete myFileMenu;
312  delete myEditMenu;
313  delete mySelectByPermissions;
314  delete mySettingsMenu;
315  delete myLocatorMenu;
316  delete myControlMenu;
317  delete myWindowsMenu;
318  delete myHelpMenu;
319 
320  delete myLoadThread;
321 
322  while (!myEvents.empty()) {
323  // get the next event
324  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
325  myEvents.pop();
326  delete e;
327  }
328 }
329 
330 
331 void
334  myMenuBarDrag->detach();
335  myToolBarDrag1->detach();
336 }
337 
338 
339 void
341  // build file menu
342  myFileMenu = new FXMenuPane(this);
343  new FXMenuTitle(myMenuBar, "&File", NULL, myFileMenu);
345  "&Open Simulation...\tCtl-O\tOpen a simulation (Configuration file).",
348  "Open &Network...\tCtl-N\tOpen a network.",
351  "&Reload\tCtl-R\tReloads the simulation / the network.",
353  new FXMenuSeparator(myFileMenu);
355  "&Close\tCtl-W\tClose the simulation.",
357  // Recent files
358  FXMenuSeparator* sep1 = new FXMenuSeparator(myFileMenu);
359  sep1->setTarget(&myRecentConfigs);
360  sep1->setSelector(FXRecentFiles::ID_ANYFILES);
361  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_1);
362  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_2);
363  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_3);
364  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_4);
365  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_5);
366  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_6);
367  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_7);
368  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_8);
369  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_9);
370  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_10);
371  new FXMenuCommand(myFileMenu, "C&lear Recent Configurations", NULL, &myRecentConfigs, FXRecentFiles::ID_CLEAR);
372  myRecentConfigs.setTarget(this);
373  myRecentConfigs.setSelector(MID_RECENTFILE);
374  FXMenuSeparator* sep2 = new FXMenuSeparator(myFileMenu);
375  sep2->setTarget(&myRecentNets);
376  sep2->setSelector(FXRecentFiles::ID_ANYFILES);
377  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_1);
378  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_2);
379  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_3);
380  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_4);
381  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_5);
382  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_6);
383  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_7);
384  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_8);
385  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_9);
386  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_10);
387  new FXMenuCommand(myFileMenu, "Cl&ear Recent Networks", NULL, &myRecentNets, FXRecentFiles::ID_CLEAR);
388  myRecentNets.setTarget(this);
389  myRecentNets.setSelector(MID_RECENTFILE);
390  new FXMenuSeparator(myFileMenu);
392  "&Quit\tCtl-Q\tQuit the Application.",
393  0, this, MID_QUIT, 0);
394 
395  // build edit menu
396  mySelectByPermissions = new FXMenuPane(this);
397  std::vector<std::string> vehicleClasses = SumoVehicleClassStrings.getStrings();
398  for (std::vector<std::string>::iterator it = vehicleClasses.begin(); it != vehicleClasses.end(); ++it) {
400  (*it).c_str(), NULL, this, MID_EDITCHOSEN);
401  }
402 
403  myEditMenu = new FXMenuPane(this);
404  new FXMenuTitle(myMenuBar, "&Edit", NULL, myEditMenu);
406  "Edit Selected...\tCtl-E\tOpens a Dialog for editing the List of Selected Items.",
408  new FXMenuCascade(myEditMenu,
409  "Select lanes which allow...\t\tOpens a menu for selecting a vehicle class by which to selected lanes.",
411  new FXMenuSeparator(myEditMenu);
413  "Edit Breakpoints...\tCtl-B\tOpens a Dialog for editing breakpoints.",
414  0, this, MID_EDIT_BREAKPOINTS);
415 
416  // build settings menu
417  mySettingsMenu = new FXMenuPane(this);
418  new FXMenuTitle(myMenuBar, "&Settings", NULL, mySettingsMenu);
420  "Application Settings...\t\tOpen a Dialog for Application Settings editing.",
421  NULL, this, MID_APPSETTINGS);
422  new FXMenuCheck(mySettingsMenu,
423  "Gaming Mode\tCtl-G\tToggle gaming mode on/off.",
424  this, MID_GAMING);
425  // build Locate menu
426  myLocatorMenu = new FXMenuPane(this);
427  new FXMenuTitle(myMenuBar, "&Locate", NULL, myLocatorMenu);
429  "Locate &Junctions\t\tOpen a Dialog for Locating a Junction.",
432  "Locate &Edges\t\tOpen a Dialog for Locating an Edge.",
434  if (!MSGlobals::gUseMesoSim) { // there are no gui-vehicles in mesosim
436  "Locate &Vehicles\t\tOpen a Dialog for Locating a Vehicle.",
438  }
440  "Locate &TLS\t\tOpen a Dialog for Locating a Traffic Light.",
443  "Locate &Additional\t\tOpen a Dialog for Locating an Additional Structure.",
446  "Locate &PoI\t\tOpen a Dialog for Locating a Point of Intereset.",
449  "Locate P&olygon\t\tOpen a Dialog for Locating a Polygon.",
451  new FXMenuSeparator(myLocatorMenu);
452  new FXMenuCheck(myLocatorMenu,
453  "Show Internal Structures\t\tShow internal junctions and streets in locator Dialog.",
454  this, MID_LISTINTERNAL);
455  // build control menu
456  myControlMenu = new FXMenuPane(this);
457  new FXMenuTitle(myMenuBar, "Simulation", NULL, myControlMenu);
459  "Run\tCtl-A\tStart running the simulation.",
460  NULL, this, MID_START);
462  "Stop\tCtl-S\tStop running the simulation.",
463  NULL, this, MID_STOP);
465  "Step\tCtl-D\tPerform one simulation step.",
466  NULL, this, MID_STEP);
467 
468  // build windows menu
469  myWindowsMenu = new FXMenuPane(this);
470  new FXMenuTitle(myMenuBar, "&Windows", NULL, myWindowsMenu);
471  new FXMenuCheck(myWindowsMenu,
472  "Show Status Line\t\tToggle the Status Bar on/off.",
473  myStatusbar, FXWindow::ID_TOGGLESHOWN);
474  new FXMenuCheck(myWindowsMenu,
475  "Show Message Window\t\tToggle the Message Window on/off.",
476  myMessageWindow, FXWindow::ID_TOGGLESHOWN);
477  new FXMenuCheck(myWindowsMenu,
478  "Show Simulation Time\t\tToggle the Simulation Time on/off.",
479  myToolBar3, FXWindow::ID_TOGGLESHOWN);
480  new FXMenuCheck(myWindowsMenu,
481  "Show Simulation Delay\t\tToggle the Simulation Delay Entry on/off.",
482  myToolBar4, FXWindow::ID_TOGGLESHOWN);
484  new FXMenuSeparator(myWindowsMenu);
485  new FXMenuCommand(myWindowsMenu, "Tile &Horizontally",
487  myMDIClient, FXMDIClient::ID_MDI_TILEHORIZONTAL);
488  new FXMenuCommand(myWindowsMenu, "Tile &Vertically",
490  myMDIClient, FXMDIClient::ID_MDI_TILEVERTICAL);
491  new FXMenuCommand(myWindowsMenu, "Cascade",
493  myMDIClient, FXMDIClient::ID_MDI_CASCADE);
494  new FXMenuCommand(myWindowsMenu, "&Close", NULL,
495  myMDIClient, FXMDIClient::ID_MDI_CLOSE);
496  sep1 = new FXMenuSeparator(myWindowsMenu);
497  sep1->setTarget(myMDIClient);
498  sep1->setSelector(FXMDIClient::ID_MDI_ANY);
499  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_1);
500  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_2);
501  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_3);
502  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_4);
503  new FXMenuCommand(myWindowsMenu, "&Others...", 0, myMDIClient, FXMDIClient::ID_MDI_OVER_5);
504  new FXMenuSeparator(myWindowsMenu);
506  "Clear Message Window\t\tClear the message window.",
507  0, this, MID_CLEARMESSAGEWINDOW);
508 
509  // build help menu
510  myHelpMenu = new FXMenuPane(this);
511  new FXMenuTitle(myMenuBar, "&Help", NULL, myHelpMenu);
513  this, MID_ABOUT);
514 }
515 
516 
517 void
519  // build tool bars
520  {
521  // file and simulation tool bar
522  myToolBarDrag1 = new FXToolBarShell(this, FRAME_NORMAL);
523  myToolBar1 = new FXToolBar(myTopDock, myToolBarDrag1,
524  LAYOUT_DOCK_NEXT | LAYOUT_SIDE_TOP | FRAME_RAISED);
525  new FXToolBarGrip(myToolBar1, myToolBar1, FXToolBar::ID_TOOLBARGRIP,
526  TOOLBARGRIP_DOUBLE);
527  // build file tools
528  new FXButton(myToolBar1, "\t\tOpen a simulation (Configuration file).",
530  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
531  new FXButton(myToolBar1, "\t\tOpen a network.",
533  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
534  new FXButton(myToolBar1, "\t\tReloads the simulation / the network.",
536  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
537  }
538  {
539  // build simulation tools
540  myToolBarDrag2 = new FXToolBarShell(this, FRAME_NORMAL);
541  myToolBar2 = new FXToolBar(myTopDock, myToolBarDrag2,
542  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
543  new FXToolBarGrip(myToolBar2, myToolBar2, FXToolBar::ID_TOOLBARGRIP,
544  TOOLBARGRIP_DOUBLE);
545  new FXButton(myToolBar2, "\t\tStart the loaded simulation.",
547  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
548  new FXButton(myToolBar2, "\t\tStop the running simulation.",
550  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
551  new FXButton(myToolBar2, "\t\tPerform a single simulation step.",
553  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
554  }
555  {
556  // Simulation Step Display
557  myToolBarDrag3 = new FXToolBarShell(this, FRAME_NORMAL);
558  myToolBar3 = new FXToolBar(myTopDock, myToolBarDrag3,
559  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
560  new FXToolBarGrip(myToolBar3, myToolBar3, FXToolBar::ID_TOOLBARGRIP,
561  TOOLBARGRIP_DOUBLE);
562  new FXButton(myToolBar3, "Time:\t\tToggle between seconds and hour:minute:seconds display", 0, this, MID_TIME_TOOGLE,
563  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
564  myLCDLabel = new FXEX::FXLCDLabel(myToolBar3, 13, 0, 0, JUSTIFY_RIGHT);
568  myLCDLabel->setGroove(2);
569  myLCDLabel->setText("-------------");
570  }
571  {
572  // Simulation Delay
573  myToolBarDrag4 = new FXToolBarShell(this, FRAME_NORMAL);
574  myToolBar4 = new FXToolBar(myTopDock, myToolBarDrag4,
575  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED | LAYOUT_FILL_Y);
576  new FXToolBarGrip(myToolBar4, myToolBar4, FXToolBar::ID_TOOLBARGRIP,
577  TOOLBARGRIP_DOUBLE);
578  new FXButton(myToolBar4, "Delay (ms):\t\tToggle between alternative delay values", 0, this, MID_DELAY_TOOGLE,
579  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
582  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK | LAYOUT_FILL_Y);
584  mySimDelayTarget->setIncrements(1, 10, 10);
585  mySimDelayTarget->setRange(0, 1000);
587  }
588  {
589  // Views
590  myToolBarDrag5 = new FXToolBarShell(this, FRAME_NORMAL);
591  myToolBar5 = new FXToolBar(myTopDock, myToolBarDrag5,
592  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
593  new FXToolBarGrip(myToolBar5, myToolBar5, FXToolBar::ID_TOOLBARGRIP,
594  TOOLBARGRIP_DOUBLE);
595  // build view tools
596  new FXButton(myToolBar5, "\t\tOpen a new microscopic view.",
598  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
599 #ifdef HAVE_OSG
600  new FXButton(myToolBar5, "\t\tOpen a new 3D view.",
602  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
603 #endif
604  }
605  {
607  // total waitingTime
608  myToolBarDrag6 = new FXToolBarShell(this, FRAME_NORMAL);
609  myToolBar6 = new FXToolBar(myTopDock, myToolBarDrag6, LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
610  new FXToolBarGrip(myToolBar6, myToolBar6, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
611  new FXLabel(myToolBar6, "Waiting Time:\t\tTime spent waiting accumulated for all vehicles", 0, LAYOUT_TOP | LAYOUT_LEFT);
612  myWaitingTimeLabel = new FXEX::FXLCDLabel(myToolBar6, 13, 0, 0, JUSTIFY_RIGHT);
617  myWaitingTimeLabel->setText("-------------");
618 
619  // idealistic time loss
620  myToolBarDrag7 = new FXToolBarShell(this, FRAME_NORMAL);
621  myToolBar7 = new FXToolBar(myTopDock, myToolBarDrag7, LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
622  new FXToolBarGrip(myToolBar7, myToolBar7, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
623  new FXLabel(myToolBar7, "Time Loss:\t\tTime lost due to being unable to drive with maximum speed for all vehicles", 0, LAYOUT_TOP | LAYOUT_LEFT);
624  myTimeLossLabel = new FXEX::FXLCDLabel(myToolBar7, 13, 0, 0, JUSTIFY_RIGHT);
629  myTimeLossLabel->setText("-------------");
630  }
631 }
632 
633 
634 long
636  getApp()->reg().writeIntEntry("SETTINGS", "x", getX());
637  getApp()->reg().writeIntEntry("SETTINGS", "y", getY());
638  getApp()->reg().writeIntEntry("SETTINGS", "width", getWidth());
639  getApp()->reg().writeIntEntry("SETTINGS", "height", getHeight());
640  getApp()->reg().writeStringEntry("SETTINGS", "basedir", gCurrentFolder.text());
641  getApp()->reg().writeIntEntry("SETTINGS", "maximized", isMaximized() ? 1 : 0);
642  getApp()->reg().writeIntEntry("gui", "timeasHMS", myShowTimeAsHMS ? 1 : 0);
643  getApp()->reg().writeIntEntry("gui", "alternateSimDelay", myAlternateSimDelay);
644  getApp()->exit(0);
645  return 1;
646 }
647 
648 
649 long
651  FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
652  if (mc->getText() == "Edit Selected...") {
653  GUIDialog_GLChosenEditor* chooser =
655  chooser->create();
656  chooser->show();
657  } else {
659  const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
660  for (size_t i = 0; i < MSEdge::dictSize(); ++i) {
661  const std::vector<MSLane*>& lanes = MSEdge::dictionary(i)->getLanes();
662  for (std::vector<MSLane*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) {
663  GUILane* lane = dynamic_cast<GUILane*>(*it);
664  assert(lane != 0);
665  if ((lane->getPermissions() & svc) != 0) {
666  gSelected.select(lane->getGlID());
667  }
668  }
669  }
670  if (myMDIClient->numChildren() > 0) {
671  GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
672  if (w != 0) {
673  // color by selection
675  }
676  }
677  }
678  updateChildren();
679  }
680  return 1;
681 }
682 
683 
684 long
687  chooser->create();
688  chooser->show();
689  return 1;
690 }
691 
692 
693 long
695  // get the new file name
696  FXFileDialog opendialog(this, "Open Simulation Configuration");
697  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
698  opendialog.setSelectMode(SELECTFILE_EXISTING);
699  opendialog.setPatternList(myConfigPattern.c_str());
700  if (gCurrentFolder.length() != 0) {
701  opendialog.setDirectory(gCurrentFolder);
702  }
703  if (opendialog.execute()) {
704  gCurrentFolder = opendialog.getDirectory();
705  std::string file = opendialog.getFilename().text();
706  load(file, false);
707  myRecentConfigs.appendFile(file.c_str());
708  }
709  return 1;
710 }
711 
712 
713 long
715  // get the new file name
716  FXFileDialog opendialog(this, "Open Network");
717  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
718  opendialog.setSelectMode(SELECTFILE_EXISTING);
719  opendialog.setPatternList("SUMO nets (*.net.xml)\nAll files (*)");
720  if (gCurrentFolder.length() != 0) {
721  opendialog.setDirectory(gCurrentFolder);
722  }
723  if (opendialog.execute()) {
724  gCurrentFolder = opendialog.getDirectory();
725  std::string file = opendialog.getFilename().text();
726  load(file, true);
727  myRecentNets.appendFile(file.c_str());
728  }
729  return 1;
730 }
731 
732 
733 long
735  load("", false, true);
736  return 1;
737 }
738 
739 
740 long
741 GUIApplicationWindow::onCmdOpenRecent(FXObject* sender, FXSelector, void* data) {
742  if (myAmLoading) {
743  myStatusbar->getStatusLine()->setText("Already loading!");
744  return 1;
745  }
746  std::string file((const char*)data);
747  load(file, sender == &myRecentNets);
748  return 1;
749 }
750 
751 
752 long
754  closeAllWindows();
755  return 1;
756 }
757 
758 
759 long
760 GUIApplicationWindow::onUpdOpen(FXObject* sender, FXSelector, void* ptr) {
761  sender->handle(this,
762  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
763  ptr);
764  return 1;
765 }
766 
767 
768 long
769 GUIApplicationWindow::onUpdReload(FXObject* sender, FXSelector, void* ptr) {
770  sender->handle(this,
772  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
773  ptr);
774  return 1;
775 }
776 
777 
778 long
779 GUIApplicationWindow::onUpdOpenRecent(FXObject* sender, FXSelector, void* ptr) {
780  sender->handle(this,
781  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
782  ptr);
783  return 1;
784 }
785 
786 
787 long
788 GUIApplicationWindow::onUpdAddView(FXObject* sender, FXSelector, void* ptr) {
789  sender->handle(this,
791  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
792  ptr);
793  return 1;
794 }
795 
796 
797 long
799  // check whether a net was loaded successfully
801  myStatusbar->getStatusLine()->setText("No simulation loaded!");
802  return 1;
803  }
804  // check whether it was started before and paused;
805  if (!myWasStarted) {
806  myRunThread->begin();
807  myWasStarted = true;
808  }
809  myRunThread->resume();
810  return 1;
811 }
812 
813 
814 long
816  myRunThread->stop();
817  return 1;
818 }
819 
820 
821 long
823  // check whether a net was loaded successfully
825  myStatusbar->getStatusLine()->setText("No simulation loaded!");
826  return 1;
827  }
828  // check whether it was started before and paused;
829  if (!myWasStarted) {
830  myRunThread->begin();
831  myWasStarted = true;
832  }
834  return 1;
835 }
836 
837 
838 long
843  }
844  return 1;
845 }
846 
847 
848 long
850  const SUMOTime tmp = myAlternateSimDelay;
853  return 1;
854 }
855 
856 
857 long
860  return 1;
861 }
862 
863 
864 long
865 GUIApplicationWindow::onUpdStart(FXObject* sender, FXSelector, void* ptr) {
866  sender->handle(this,
868  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
869  ptr);
870  return 1;
871 }
872 
873 
874 long
875 GUIApplicationWindow::onUpdStop(FXObject* sender, FXSelector, void* ptr) {
876  sender->handle(this,
878  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
879  ptr);
880  return 1;
881 }
882 
883 
884 long
885 GUIApplicationWindow::onUpdStep(FXObject* sender, FXSelector, void* ptr) {
886  sender->handle(this,
888  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
889  ptr);
890  return 1;
891 }
892 
893 
894 long
895 GUIApplicationWindow::onUpdNeedsSimulation(FXObject* sender, FXSelector, void* ptr) {
896  sender->handle(this,
898  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
899  ptr);
900  return 1;
901 }
902 
903 
904 long
905 GUIApplicationWindow::onCmdLocate(FXObject*, FXSelector sel, void*) {
906  if (myMDIClient->numChildren() > 0) {
907  GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
908  if (w != 0) {
909  w->onCmdLocate(0, sel, 0);
910  }
911  }
912  return 1;
913 }
914 
915 long
918  d->create();
919  d->show(PLACEMENT_OWNER);
920  return 1;
921 }
922 
923 
924 long
927  if (myAmGaming) {
928  myMenuBar->hide();
929  myStatusbar->hide();
930  myToolBar1->hide();
931  myToolBar2->hide();
932  myToolBar4->hide();
933  myToolBar5->hide();
934  myToolBar6->show();
935  myToolBar7->show();
936  myMessageWindow->hide();
941  } else {
942  myMenuBar->show();
943  myStatusbar->show();
944  myToolBar1->show();
945  myToolBar2->show();
946  myToolBar4->show();
947  myToolBar5->show();
948  myToolBar6->hide();
949  myToolBar7->hide();
950  myMessageWindow->show();
952  gSchemeStorage.getDefault().gaming = false;
953  }
954  update();
955  return 1;
956 }
957 
958 
959 long
962  return 1;
963 }
964 
965 
966 long
969  return 1;
970 }
971 
972 
973 #ifdef HAVE_OSG
974 long
975 GUIApplicationWindow::onCmdNewOSG(FXObject*, FXSelector, void*) {
977  return 1;
978 }
979 #endif
980 
981 
982 long
984  GUIDialog_AboutSUMO* about =
985  new GUIDialog_AboutSUMO(this, "About SUMO", 0, 0);
986  about->create();
987  about->show(PLACEMENT_OWNER);
988  return 1;
989 }
990 
991 
992 long GUIApplicationWindow::onClipboardRequest(FXObject* /* sender */, FXSelector /* sel */, void* ptr) {
993  FXEvent* event = (FXEvent*)ptr;
994  FXString string = GUIUserIO::clipped.c_str();
995  setDNDData(FROM_CLIPBOARD, event->target, string);
996  return 1;
997 }
998 
999 
1000 long
1002  eventOccured();
1003  return 1;
1004 }
1005 
1006 
1007 long
1009  eventOccured();
1010  return 1;
1011 }
1012 
1013 
1014 void
1016  while (!myEvents.empty()) {
1017  // get the next event
1018  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
1019  myEvents.pop();
1020  // process
1021  switch (e->getOwnType()) {
1024  break;
1025  case EVENT_SIMULATION_STEP:
1026  if (myRunThread->simulationAvailable()) { // avoid race-condition related crash if reload was pressed
1028  }
1029  break;
1030  case EVENT_MESSAGE_OCCURED:
1031  case EVENT_WARNING_OCCURED:
1032  case EVENT_ERROR_OCCURED:
1034  break;
1037  break;
1038  default:
1039  break;
1040  }
1041  delete e;
1042  }
1043  myToolBar2->forceRefresh();
1044  myToolBar3->forceRefresh();
1045 }
1046 
1047 
1048 void
1050  myAmLoading = false;
1052  // check whether the loading was successfull
1053  if (ec->myNet == 0) {
1054  // report failure
1055  setStatusBarText("Loading of '" + ec->myFile + "' failed!");
1056  if (GUIGlobals::gQuitOnEnd) {
1057  closeAllWindows();
1058  getApp()->exit(1);
1059  }
1060  } else {
1061  // initialise simulation thread
1062  if (!myRunThread->init(ec->myNet, ec->myBegin, ec->myEnd)) {
1063  if (GUIGlobals::gQuitOnEnd) {
1064  closeAllWindows();
1065  getApp()->exit(1);
1066  }
1067  } else {
1068  // report success
1069  setStatusBarText("'" + ec->myFile + "' loaded.");
1070  myWasStarted = false;
1071  // initialise views
1072  myViewNumber = 0;
1074  if (ec->mySettingsFiles.size() > 0) {
1075  // open a view for each file and apply settings
1076  for (std::vector<std::string>::const_iterator it = ec->mySettingsFiles.begin(); it != ec->mySettingsFiles.end(); ++it) {
1077  GUISettingsHandler settings(*it);
1078  GUISUMOViewParent::ViewType vt = defaultType;
1079  if (settings.getViewType() == "osg" || settings.getViewType() == "3d") {
1081  }
1082  if (settings.getViewType() == "opengl" || settings.getViewType() == "2d") {
1084  }
1085  GUISUMOAbstractView* view = openNewView(vt);
1086  if (view == 0) {
1087  break;
1088  }
1089  std::string settingsName = settings.addSettings(view);
1090  view->addDecals(settings.getDecals());
1091  settings.setViewport(view);
1092  settings.setSnapshots(view);
1093  if (settings.getDelay() > 0) {
1094  mySimDelayTarget->setValue(settings.getDelay());
1095  }
1096  if (settings.getBreakpoints().size() > 0) {
1098  myRunThread->getBreakpoints().assign(settings.getBreakpoints().begin(), settings.getBreakpoints().end());
1100  }
1101  myJamSounds = settings.getEventDistribution("jam");
1102  if (settings.getJamSoundTime() > 0) {
1103  myJamSoundTime = settings.getJamSoundTime();
1104  }
1105  }
1106  } else {
1107  openNewView(defaultType);
1108  }
1109 
1110  if (isGaming()) {
1111  setTitle("SUMO Traffic Light Game");
1112  } else {
1113  // set simulation name on the caption
1114  std::string caption = "SUMO " + std::string(VERSION_STRING);
1115  setTitle(MFXUtils::getTitleText(caption.c_str(), ec->myFile.c_str()));
1116  }
1117  // set simulation step begin information
1118  myLCDLabel->setText("-------------");
1119  }
1120  }
1121  getApp()->endWaitCursor();
1122  // start if wished
1124  onCmdStart(0, 0, 0);
1125  }
1126  update();
1127 }
1128 
1129 
1130 void
1132  updateChildren();
1134  if (myAmGaming) {
1136  }
1137  update();
1138 }
1139 
1140 
1141 void
1143  GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);
1145 }
1146 
1147 
1148 void
1150  GUIEvent_SimulationEnded* ec = static_cast<GUIEvent_SimulationEnded*>(e);
1151  onCmdStop(0, 0, 0);
1152  if (GUIGlobals::gQuitOnEnd) {
1153  closeAllWindows();
1154  getApp()->exit(ec->getReason() == MSNet::SIMSTATE_ERROR_IN_SIM);
1155  } else {
1156  // build the text
1157  const std::string text = "Simulation ended at time: " + time2string(ec->getTimeStep()) +
1158  ".\nReason: " + MSNet::getStateMessage(ec->getReason());
1159  FXMessageBox::warning(this, MBOX_OK, "Simulation ended", "%s", text.c_str());
1160  }
1161 }
1162 
1163 
1164 void
1166  MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
1169  if (myJamSounds.getOverallProb() > 0) {
1170  // play honking sound if some vehicle is waiting too long
1171  for (; it != end; ++it) {
1172  // XXX use impatience instead of waiting time ?
1173  if (it->second->getWaitingTime() > TIME2STEPS(myJamSoundTime)) {
1174  const std::string cmd = myJamSounds.get(&myGamingRNG);
1175  if (cmd != "") {
1176  // yay! fun with dangerous commands... Never use this over the internet
1178  // one sound per simulation step is enough
1179  break;
1180  }
1181  }
1182  }
1183  }
1184  // updated peformance indicators
1185 
1186  for (it = vc.loadedVehBegin(); it != end; ++it) {
1187  const MSVehicle* veh = dynamic_cast<MSVehicle*>(it->second);
1188  assert(veh != 0);
1189  const SUMOReal vmax = MIN2(veh->getVehicleType().getMaxSpeed(), veh->getEdge()->getSpeedLimit());
1190  if (veh->isOnRoad() && veh->getSpeed() < SUMO_const_haltingSpeed) {
1192  }
1193  myTimeLoss += TS * TIME2STEPS(vmax - veh->getSpeed()) / vmax; // may be negative with speedFactor > 1
1196  }
1197 
1198 }
1199 
1200 
1201 void
1202 GUIApplicationWindow::load(const std::string& file, bool isNet, bool isReload) {
1203  getApp()->beginWaitCursor();
1204  myAmLoading = true;
1205  closeAllWindows();
1206  if (isReload) {
1207  myLoadThread->start();
1208  setStatusBarText("Reloading.");
1209  } else {
1210  gSchemeStorage.saveViewport(0, 0, -1); // recenter view
1211  myLoadThread->load(file, isNet);
1212  setStatusBarText("Loading '" + file + "'.");
1213  }
1214  update();
1215 }
1216 
1217 
1220  if (!myRunThread->simulationAvailable()) {
1221  myStatusbar->getStatusLine()->setText("No simulation loaded!");
1222  return 0;
1223  }
1224  std::string caption = "View #" + toString(myViewNumber++);
1225  FXuint opts = MDI_TRACKING;
1226  GUISUMOViewParent* w = new GUISUMOViewParent(myMDIClient, myMDIMenu, FXString(caption.c_str()),
1227  this, GUIIconSubSys::getIcon(ICON_APP), opts, 10, 10, 300, 200);
1229  w->create();
1230  if (myMDIClient->numChildren() == 1) {
1231  w->maximize();
1232  } else {
1233  myMDIClient->vertical(true);
1234  }
1235  myMDIClient->setActiveChild(w);
1236  return v;
1237 }
1238 
1239 
1240 FXGLCanvas*
1242  if (myMDIClient->numChildren() == 0) {
1243  return 0;
1244  }
1245  GUISUMOViewParent* share_tmp1 =
1246  static_cast<GUISUMOViewParent*>(myMDIClient->childAtIndex(0));
1247  return share_tmp1->getBuildGLCanvas();
1248 }
1249 
1250 
1251 void
1253  myTrackerLock.lock();
1254  myLCDLabel->setText("-------------");
1255  // remove trackers and other external windows
1256  size_t i;
1257  for (i = 0; i < mySubWindows.size(); ++i) {
1258  mySubWindows[i]->destroy();
1259  }
1260  for (i = 0; i < myTrackerWindows.size(); ++i) {
1261  myTrackerWindows[i]->destroy();
1262  }
1263  // delete the simulation
1265  // reset the caption
1266  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
1267  // delete other children
1268  while (myTrackerWindows.size() != 0) {
1269  delete myTrackerWindows[0];
1270  }
1271  while (mySubWindows.size() != 0) {
1272  delete mySubWindows[0];
1273  }
1274  mySubWindows.clear();
1275  // clear selected items
1276  gSelected.clear();
1277  // add a separator to the log
1280  // remove coordinate information
1281  myGeoCoordinate->setText("N/A");
1282  myCartesianCoordinate->setText("N/A");
1283  //
1285  update();
1286 }
1287 
1288 
1289 FXCursor*
1291  return getApp()->getDefaultCursor(DEF_ARROW_CURSOR);
1292 }
1293 
1294 
1295 SUMOTime
1298 }
1299 
1300 
1301 void
1303  load("", false);
1304 }
1305 
1306 
1307 void
1308 GUIApplicationWindow::setStatusBarText(const std::string& text) {
1309  myStatusbar->getStatusLine()->setText(text.c_str());
1310  myStatusbar->getStatusLine()->setNormalText(text.c_str());
1311 }
1312 
1313 
1314 void
1316  time -= DELTA_T; // synchronize displayed time with netstate output
1317  if (myAmGaming) {
1318  // show time counting backwards
1319  time = myRunThread->getSimEndTime() - time;
1320  }
1321  SUMOReal fracSeconds = STEPS2TIME(time);
1322  const bool hideFraction = myAmGaming || fmod(TS, 1.) == 0.;
1323  const int BuffSize = 100;
1324  char buffer[BuffSize];
1325  if (myShowTimeAsHMS) {
1326  const int hours = (int)fracSeconds / 3600;
1327  const int minutes = ((int)fracSeconds % 3600) / 60;
1328  fracSeconds = fracSeconds - 3600 * hours - 60 * minutes;
1329  const std::string format = (hideFraction ?
1330  "%02d-%02d-%02.0f" : "%02d-%02d-%06.3f");
1331  snprintf(buffer, BuffSize, format.c_str(), hours, minutes, fracSeconds);
1332  } else {
1333  const std::string format = (hideFraction ?
1334  "%13.0f" : "%13.3f");
1335  snprintf(buffer, BuffSize, format.c_str(), fracSeconds);
1336  }
1337  myLCDLabel->setText(buffer);
1338 }
1339 
1340 /****************************************************************************/
1341