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-2013 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 
44 #include "GUISUMOViewParent.h"
45 #include "GUILoadThread.h"
46 #include "GUIRunThread.h"
47 #include "GUIApplicationWindow.h"
50 
51 #include <utils/common/ToString.h>
56 
72 #include "GUIGlobals.h"
76 
77 #ifndef NO_TRACI
79 #include "TraCIServerAPI_GUI.h"
80 #endif
81 
82 #ifdef CHECK_MEMORY_LEAKS
83 #include <foreign/nvwa/debug_new.h>
84 #endif
85 
86 
87 // ===========================================================================
88 // FOX-declarations
89 // ===========================================================================
90 FXDEFMAP(GUIApplicationWindow) GUIApplicationWindowMap[] = {
91  FXMAPFUNC(SEL_COMMAND, MID_QUIT, GUIApplicationWindow::onCmdQuit),
92  FXMAPFUNC(SEL_SIGNAL, MID_QUIT, GUIApplicationWindow::onCmdQuit),
93  FXMAPFUNC(SEL_CLOSE, MID_WINDOW, GUIApplicationWindow::onCmdQuit),
94 
98  FXMAPFUNC(SEL_COMMAND, MID_RELOAD, GUIApplicationWindow::onCmdReload),
99  FXMAPFUNC(SEL_COMMAND, MID_CLOSE, GUIApplicationWindow::onCmdClose),
100  FXMAPFUNC(SEL_COMMAND, MID_EDITCHOSEN, GUIApplicationWindow::onCmdEditChosen),
102 
104  FXMAPFUNC(SEL_COMMAND, MID_GAMING, GUIApplicationWindow::onCmdGaming),
106  FXMAPFUNC(SEL_COMMAND, MID_ABOUT, GUIApplicationWindow::onCmdAbout),
107  FXMAPFUNC(SEL_COMMAND, MID_NEW_MICROVIEW, GUIApplicationWindow::onCmdNewView),
108 #ifdef HAVE_OSG
109  FXMAPFUNC(SEL_COMMAND, MID_NEW_OSGVIEW, GUIApplicationWindow::onCmdNewOSG),
110 #endif
111  FXMAPFUNC(SEL_COMMAND, MID_START, GUIApplicationWindow::onCmdStart),
112  FXMAPFUNC(SEL_COMMAND, MID_STOP, GUIApplicationWindow::onCmdStop),
113  FXMAPFUNC(SEL_COMMAND, MID_STEP, GUIApplicationWindow::onCmdStep),
117 
118  FXMAPFUNC(SEL_UPDATE, MID_OPEN_CONFIG, GUIApplicationWindow::onUpdOpen),
119  FXMAPFUNC(SEL_UPDATE, MID_OPEN_NETWORK, GUIApplicationWindow::onUpdOpen),
120  FXMAPFUNC(SEL_UPDATE, MID_RELOAD, GUIApplicationWindow::onUpdReload),
123 #ifdef HAVE_OSG
124  FXMAPFUNC(SEL_COMMAND, MID_NEW_OSGVIEW, GUIApplicationWindow::onUpdAddView),
125 #endif
126  FXMAPFUNC(SEL_UPDATE, MID_START, GUIApplicationWindow::onUpdStart),
127  FXMAPFUNC(SEL_UPDATE, MID_STOP, GUIApplicationWindow::onUpdStop),
128  FXMAPFUNC(SEL_UPDATE, MID_STEP, GUIApplicationWindow::onUpdStep),
131 
132  FXMAPFUNC(SEL_CLIPBOARD_REQUEST, 0, GUIApplicationWindow::onClipboardRequest),
133 
138 };
139 
140 // Object implementation
141 FXIMPLEMENT(GUIApplicationWindow, FXMainWindow, GUIApplicationWindowMap, ARRAYNUMBER(GUIApplicationWindowMap))
142 
143 // ===========================================================================
144 // member method definitions
145 // ===========================================================================
147  const std::string& configPattern)
148  : GUIMainWindow(a),
149  myLoadThread(0), myRunThread(0),
150  myAmLoading(false),
151  myAlternateSimDelay(0),
152  myRecentNets(a, "nets"), myConfigPattern(configPattern),
153  hadDependentBuild(false),
154  myShowTimeAsHMS(false) {
156 }
157 
158 
159 void
161  // do this not twice
162  if (hadDependentBuild) {
163  return;
164  }
165  hadDependentBuild = true;
166 
167  setTarget(this);
168  setSelector(MID_WINDOW);
169 
170  // build menu bar
171  myMenuBarDrag = new FXToolBarShell(this, FRAME_NORMAL);
172  myMenuBar = new FXMenuBar(myTopDock, myMenuBarDrag,
173  LAYOUT_SIDE_TOP | LAYOUT_FILL_X | FRAME_RAISED);
174  new FXToolBarGrip(myMenuBar, myMenuBar, FXMenuBar::ID_TOOLBARGRIP,
175  TOOLBARGRIP_DOUBLE);
176  buildToolBars();
177  // build the thread - io
182 
183  // build the status bar
184  myStatusbar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X | FRAME_RAISED);
185  {
186  myGeoFrame =
187  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
188  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
189  myGeoCoordinate = new FXLabel(myGeoFrame, "N/A", 0, LAYOUT_CENTER_Y);
191  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
192  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
193  myCartesianCoordinate = new FXLabel(myCartesianFrame, "N/A", 0, LAYOUT_CENTER_Y);
194  }
195 
196  // make the window a mdi-window
197  myMainSplitter = new FXSplitter(this,
198  SPLITTER_REVERSED | SPLITTER_VERTICAL | LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | FRAME_RAISED | FRAME_THICK);
199  myMDIClient = new FXMDIClient(myMainSplitter,
200  LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK);
201  myMDIMenu = new FXMDIMenu(this, myMDIClient);
202  new FXMDIWindowButton(myMenuBar, myMDIMenu, myMDIClient,
203  FXMDIClient::ID_MDI_MENUWINDOW, LAYOUT_LEFT);
204  new FXMDIDeleteButton(myMenuBar, myMDIClient,
205  FXMDIClient::ID_MDI_MENUCLOSE, FRAME_RAISED | LAYOUT_RIGHT);
206  new FXMDIRestoreButton(myMenuBar, myMDIClient,
207  FXMDIClient::ID_MDI_MENURESTORE, FRAME_RAISED | LAYOUT_RIGHT);
208  new FXMDIMinimizeButton(myMenuBar, myMDIClient,
209  FXMDIClient::ID_MDI_MENUMINIMIZE, FRAME_RAISED | LAYOUT_RIGHT);
210 
211  // build the message window
213  // fill menu and tool bar
214  fillMenuBar();
215  if (game) {
216  onCmdGaming(0, 0, 0);
217  myMenuBar->hide();
218  myToolBar1->hide();
219  myToolBar2->hide();
220  myToolBar4->hide();
221  myToolBar5->hide();
222  myMessageWindow->hide();
223  }
224  // build additional threads
225  myLoadThread = new GUILoadThread(getApp(), this, myEvents, myLoadThreadEvent);
226  myRunThread = new GUIRunThread(getApp(), this, *mySimDelayTarget, myEvents,
228  // set the status bar
229  myStatusbar->getStatusLine()->setText("Ready.");
230  // set the caption
231  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
232 
233  // start the simulation-thread (it will loop until the application ends deciding by itself whether to perform a step or not)
234  myRunThread->start();
236 }
237 
238 
239 void
241  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 0) {
242  setX(getApp()->reg().readIntEntry("SETTINGS", "x", 150));
243  setY(getApp()->reg().readIntEntry("SETTINGS", "y", 150));
244  setWidth(getApp()->reg().readIntEntry("SETTINGS", "width", 600));
245  setHeight(getApp()->reg().readIntEntry("SETTINGS", "height", 400));
246  }
247  gCurrentFolder = getApp()->reg().readStringEntry("SETTINGS", "basedir", "");
248  FXMainWindow::create();
249  myMenuBarDrag->create();
250  myToolBarDrag1->create();
251  myToolBarDrag2->create();
252  myFileMenu->create();
253  myEditMenu->create();
254  mySettingsMenu->create();
255  myWindowsMenu->create();
256  myHelpMenu->create();
257 
258  FXint width = getApp()->getNormalFont()->getTextWidth("8", 1) * 24;
259  myCartesianFrame->setWidth(width);
260  myGeoFrame->setWidth(width);
261 
262  show(PLACEMENT_SCREEN);
263  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 1) {
264  maximize();
265  }
266  myShowTimeAsHMS = (getApp()->reg().readIntEntry("gui", "timeasHMS", 0) == 1);
267  myAlternateSimDelay = getApp()->reg().readIntEntry("gui", "alternateSimDelay", 100);
268 }
269 
270 
273  myRunThread->join();
274  closeAllWindows();
275  //
277  delete myGLVisual;
278  // delete some non-parented windows
279  delete myToolBarDrag1;
280  //
281  delete myRunThread;
282  delete myFileMenu;
283  delete myEditMenu;
284  delete mySettingsMenu;
285  delete myWindowsMenu;
286  delete myHelpMenu;
287 
288  delete myLoadThread;
289 
290  while (!myEvents.empty()) {
291  // get the next event
292  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
293  myEvents.pop();
294  delete e;
295  }
296 }
297 
298 
299 void
301  FXMainWindow::detach();
302  myMenuBarDrag->detach();
303  myToolBarDrag1->detach();
304 }
305 
306 
307 void
309  // build file menu
310  myFileMenu = new FXMenuPane(this);
311  new FXMenuTitle(myMenuBar, "&File", NULL, myFileMenu);
313  "&Open Simulation...\tCtl-O\tOpen a simulation (Configuration file).",
316  "Open &Network...\tCtl-N\tOpen a network.",
319  "&Reload\tCtl-R\tReloads the simulation / the network.",
321  new FXMenuSeparator(myFileMenu);
323  "&Close\tCtl-W\tClose the simulation.",
325  // Recent files
326  FXMenuSeparator* sep1 = new FXMenuSeparator(myFileMenu);
327  sep1->setTarget(&myRecentConfigs);
328  sep1->setSelector(FXRecentFiles::ID_ANYFILES);
329  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_1);
330  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_2);
331  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_3);
332  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_4);
333  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_5);
334  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_6);
335  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_7);
336  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_8);
337  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_9);
338  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_10);
339  new FXMenuCommand(myFileMenu, "C&lear Recent Configurations", NULL, &myRecentConfigs, FXRecentFiles::ID_CLEAR);
340  myRecentConfigs.setTarget(this);
341  myRecentConfigs.setSelector(MID_RECENTFILE);
342  FXMenuSeparator* sep2 = new FXMenuSeparator(myFileMenu);
343  sep2->setTarget(&myRecentNets);
344  sep2->setSelector(FXRecentFiles::ID_ANYFILES);
345  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_1);
346  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_2);
347  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_3);
348  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_4);
349  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_5);
350  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_6);
351  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_7);
352  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_8);
353  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_9);
354  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_10);
355  new FXMenuCommand(myFileMenu, "Cl&ear Recent Networks", NULL, &myRecentNets, FXRecentFiles::ID_CLEAR);
356  myRecentNets.setTarget(this);
357  myRecentNets.setSelector(MID_RECENTFILE);
358  new FXMenuSeparator(myFileMenu);
360  "&Quit\tCtl-Q\tQuit the Application.",
361  0, this, MID_QUIT, 0);
362 
363  // build edit menu
364  myEditMenu = new FXMenuPane(this);
365  new FXMenuTitle(myMenuBar, "&Edit", NULL, myEditMenu);
367  "Edit Chosen...\t\tOpens a Dialog for editing the List of chosen Items.",
369  new FXMenuSeparator(myEditMenu);
371  "Edit Breakpoints...\t\tOpens a Dialog for editing breakpoints.",
372  0, this, MID_EDIT_BREAKPOINTS);
373 
374  // build settings menu
375  mySettingsMenu = new FXMenuPane(this);
376  new FXMenuTitle(myMenuBar, "&Settings", NULL, mySettingsMenu);
378  "Application Settings...\t\tOpen a Dialog for Application Settings editing.",
379  NULL, this, MID_APPSETTINGS);
380  new FXMenuCheck(mySettingsMenu,
381  "Gaming Mode\t\tToggle gaming mode on/off.",
382  this, MID_GAMING);
383  new FXMenuCheck(mySettingsMenu,
384  "Locate Internal Structures\t\tList internal junctions and streets in the object locator.",
385  this, MID_LISTINTERNAL);
386 
387  // build windows menu
388  myWindowsMenu = new FXMenuPane(this);
389  new FXMenuTitle(myMenuBar, "&Windows", NULL, myWindowsMenu);
390  new FXMenuCheck(myWindowsMenu,
391  "Show Status Line\t\tToggle this Status Bar on/off.",
392  myStatusbar, FXWindow::ID_TOGGLESHOWN);
393  new FXMenuCheck(myWindowsMenu,
394  "Show Message Window\t\tToggle the Message Window on/off.",
395  myMessageWindow, FXWindow::ID_TOGGLESHOWN);
396  new FXMenuCheck(myWindowsMenu,
397  "Show Simulation Time\t\tToggle the Simulation Time on/off.",
398  myToolBar3, FXWindow::ID_TOGGLESHOWN);
399  new FXMenuCheck(myWindowsMenu,
400  "Show Simulation Delay\t\tToggle the Simulation Delay Entry on/off.",
401  myToolBar4, FXWindow::ID_TOGGLESHOWN);
403  new FXMenuSeparator(myWindowsMenu);
404  new FXMenuCommand(myWindowsMenu, "Tile &Horizontally",
406  myMDIClient, FXMDIClient::ID_MDI_TILEHORIZONTAL);
407  new FXMenuCommand(myWindowsMenu, "Tile &Vertically",
409  myMDIClient, FXMDIClient::ID_MDI_TILEVERTICAL);
410  new FXMenuCommand(myWindowsMenu, "C&ascade",
412  myMDIClient, FXMDIClient::ID_MDI_CASCADE);
413  new FXMenuCommand(myWindowsMenu, "&Close", NULL,
414  myMDIClient, FXMDIClient::ID_MDI_CLOSE);
415  sep1 = new FXMenuSeparator(myWindowsMenu);
416  sep1->setTarget(myMDIClient);
417  sep1->setSelector(FXMDIClient::ID_MDI_ANY);
418  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_1);
419  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_2);
420  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_3);
421  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_4);
422  new FXMenuCommand(myWindowsMenu, "&Others...", 0, myMDIClient, FXMDIClient::ID_MDI_OVER_5);
423  new FXMenuSeparator(myWindowsMenu);
425  "Clear Message Window\t\tClear the message window.",
426  0, this, MID_CLEARMESSAGEWINDOW);
427 
428  // build help menu
429  myHelpMenu = new FXMenuPane(this);
430  new FXMenuTitle(myMenuBar, "&Help", NULL, myHelpMenu);
432  this, MID_ABOUT);
433 }
434 
435 
436 void
438  // build tool bars
439  {
440  // file and simulation tool bar
441  myToolBarDrag1 = new FXToolBarShell(this, FRAME_NORMAL);
442  myToolBar1 = new FXToolBar(myTopDock, myToolBarDrag1,
443  LAYOUT_DOCK_NEXT | LAYOUT_SIDE_TOP | FRAME_RAISED);
444  new FXToolBarGrip(myToolBar1, myToolBar1, FXToolBar::ID_TOOLBARGRIP,
445  TOOLBARGRIP_DOUBLE);
446  // build file tools
447  new FXButton(myToolBar1, "\t\tOpen a simulation (Configuration file).",
449  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
450  new FXButton(myToolBar1, "\t\tOpen a network.",
452  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
453  new FXButton(myToolBar1, "\t\tReloads the simulation / the network.",
455  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
456  }
457  {
458  // build simulation tools
459  myToolBarDrag2 = new FXToolBarShell(this, FRAME_NORMAL);
460  myToolBar2 = new FXToolBar(myTopDock, myToolBarDrag2,
461  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
462  new FXToolBarGrip(myToolBar2, myToolBar2, FXToolBar::ID_TOOLBARGRIP,
463  TOOLBARGRIP_DOUBLE);
464  new FXButton(myToolBar2, "\t\tStart the loaded simulation.",
466  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
467  new FXButton(myToolBar2, "\t\tStop the running simulation.",
469  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
470  new FXButton(myToolBar2, "\t\tPerform a single simulation step.",
472  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
473  }
474  {
475  // Simulation Step Display
476  myToolBarDrag3 = new FXToolBarShell(this, FRAME_NORMAL);
477  myToolBar3 = new FXToolBar(myTopDock, myToolBarDrag3,
478  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
479  new FXToolBarGrip(myToolBar3, myToolBar3, FXToolBar::ID_TOOLBARGRIP,
480  TOOLBARGRIP_DOUBLE);
481  new FXButton(myToolBar3, "Time:\t\tToggle between seconds and hour:minute:seconds display", 0, this, MID_TIME_TOOGLE,
482  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
483  myLCDLabel = new FXEX::FXLCDLabel(myToolBar3, 13, 0, 0, JUSTIFY_RIGHT);
487  myLCDLabel->setGroove(2);
488  myLCDLabel->setText("-------------");
489  }
490  {
491  // Simulation Delay
492  myToolBarDrag4 = new FXToolBarShell(this, FRAME_NORMAL);
493  myToolBar4 = new FXToolBar(myTopDock, myToolBarDrag4,
494  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED | LAYOUT_FILL_Y);
495  new FXToolBarGrip(myToolBar4, myToolBar4, FXToolBar::ID_TOOLBARGRIP,
496  TOOLBARGRIP_DOUBLE);
497  new FXButton(myToolBar4, "Delay (ms):\t\tToggle between alternative delay values", 0, this, MID_DELAY_TOOGLE,
498  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
501  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK | LAYOUT_FILL_Y);
503  mySimDelayTarget->setIncrements(1, 10, 10);
504  mySimDelayTarget->setRange(0, 1000);
506  }
507  {
508  // Views
509  myToolBarDrag5 = new FXToolBarShell(this, FRAME_NORMAL);
510  myToolBar5 = new FXToolBar(myTopDock, myToolBarDrag5,
511  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
512  new FXToolBarGrip(myToolBar5, myToolBar5, FXToolBar::ID_TOOLBARGRIP,
513  TOOLBARGRIP_DOUBLE);
514  // build view tools
515  new FXButton(myToolBar5, "\t\tOpen a new microscopic view.",
517  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
518 #ifdef HAVE_OSG
519  new FXButton(myToolBar5, "\t\tOpen a new 3D view.",
521  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
522 #endif
523  }
524 }
525 
526 
527 long
529  getApp()->reg().writeIntEntry("SETTINGS", "x", getX());
530  getApp()->reg().writeIntEntry("SETTINGS", "y", getY());
531  getApp()->reg().writeIntEntry("SETTINGS", "width", getWidth());
532  getApp()->reg().writeIntEntry("SETTINGS", "height", getHeight());
533  getApp()->reg().writeStringEntry("SETTINGS", "basedir", gCurrentFolder.text());
534  getApp()->reg().writeIntEntry("SETTINGS", "maximized", isMaximized() ? 1 : 0);
535  getApp()->reg().writeIntEntry("gui", "timeasHMS", myShowTimeAsHMS ? 1 : 0);
536  getApp()->reg().writeIntEntry("gui", "alternateSimDelay", myAlternateSimDelay);
537  getApp()->exit(0);
538  return 1;
539 }
540 
541 
542 long
544  GUIDialog_GLChosenEditor* chooser =
546  chooser->create();
547  chooser->show();
548  return 1;
549 }
550 
551 
552 long
554  GUIDialog_Breakpoints* chooser = new GUIDialog_Breakpoints(this);
555  chooser->create();
556  chooser->show();
557  return 1;
558 }
559 
560 
561 long
563  // get the new file name
564  FXFileDialog opendialog(this, "Open Simulation Configuration");
565  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
566  opendialog.setSelectMode(SELECTFILE_EXISTING);
567  opendialog.setPatternList(myConfigPattern.c_str());
568  if (gCurrentFolder.length() != 0) {
569  opendialog.setDirectory(gCurrentFolder);
570  }
571  if (opendialog.execute()) {
572  gCurrentFolder = opendialog.getDirectory();
573  std::string file = opendialog.getFilename().text();
574  load(file, false);
575  myRecentConfigs.appendFile(file.c_str());
576  }
577  return 1;
578 }
579 
580 
581 long
583  // get the new file name
584  FXFileDialog opendialog(this, "Open Network");
585  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
586  opendialog.setSelectMode(SELECTFILE_EXISTING);
587  opendialog.setPatternList("SUMO nets (*.net.xml)\nAll files (*)");
588  if (gCurrentFolder.length() != 0) {
589  opendialog.setDirectory(gCurrentFolder);
590  }
591  if (opendialog.execute()) {
592  gCurrentFolder = opendialog.getDirectory();
593  std::string file = opendialog.getFilename().text();
594  load(file, true);
595  myRecentNets.appendFile(file.c_str());
596  }
597  return 1;
598 }
599 
600 
601 long
603  load("", false, true);
604  return 1;
605 }
606 
607 
608 long
609 GUIApplicationWindow::onCmdOpenRecent(FXObject* sender, FXSelector, void* data) {
610  if (myAmLoading) {
611  myStatusbar->getStatusLine()->setText("Already loading!");
612  return 1;
613  }
614  std::string file((const char*)data);
615  load(file, sender == &myRecentNets);
616  return 1;
617 }
618 
619 
620 long
622  closeAllWindows();
623  return 1;
624 }
625 
626 
627 long
628 GUIApplicationWindow::onUpdOpen(FXObject* sender, FXSelector, void* ptr) {
629  sender->handle(this,
630  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
631  ptr);
632  return 1;
633 }
634 
635 
636 long
637 GUIApplicationWindow::onUpdReload(FXObject* sender, FXSelector, void* ptr) {
638  sender->handle(this,
640  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
641  ptr);
642  return 1;
643 }
644 
645 
646 long
647 GUIApplicationWindow::onUpdOpenRecent(FXObject* sender, FXSelector, void* ptr) {
648  sender->handle(this,
649  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
650  ptr);
651  return 1;
652 }
653 
654 
655 long
656 GUIApplicationWindow::onUpdAddView(FXObject* sender, FXSelector, void* ptr) {
657  sender->handle(this,
659  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
660  ptr);
661  return 1;
662 }
663 
664 
665 long
667  // check whether a net was loaded successfully
669  myStatusbar->getStatusLine()->setText("No simulation loaded!");
670  return 1;
671  }
672  // check whether it was started before and paused;
673  if (!myWasStarted) {
674  myRunThread->begin();
675  myWasStarted = true;
676  }
677  myRunThread->resume();
678  return 1;
679 }
680 
681 
682 long
684  myRunThread->stop();
685  return 1;
686 }
687 
688 
689 long
691  // check whether a net was loaded successfully
693  myStatusbar->getStatusLine()->setText("No simulation loaded!");
694  return 1;
695  }
696  // check whether it was started before and paused;
697  if (!myWasStarted) {
698  myRunThread->begin();
699  myWasStarted = true;
700  }
702  return 1;
703 }
704 
705 
706 long
711  }
712  return 1;
713 }
714 
715 
716 long
718  const SUMOTime tmp = myAlternateSimDelay;
721  return 1;
722 }
723 
724 
725 long
728  return 1;
729 }
730 
731 
732 long
733 GUIApplicationWindow::onUpdStart(FXObject* sender, FXSelector, void* ptr) {
734  sender->handle(this,
736  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
737  ptr);
738  return 1;
739 }
740 
741 
742 long
743 GUIApplicationWindow::onUpdStop(FXObject* sender, FXSelector, void* ptr) {
744  sender->handle(this,
746  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
747  ptr);
748  return 1;
749 }
750 
751 
752 long
753 GUIApplicationWindow::onUpdStep(FXObject* sender, FXSelector, void* ptr) {
754  sender->handle(this,
756  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
757  ptr);
758  return 1;
759 }
760 
761 
762 long
763 GUIApplicationWindow::onUpdEditChosen(FXObject* sender, FXSelector, void* ptr) {
764  sender->handle(this,
766  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
767  ptr);
768  return 1;
769 }
770 
771 
772 long
773 GUIApplicationWindow::onUpdEditBreakpoints(FXObject* sender, FXSelector, void* ptr) {
774  sender->handle(this,
776  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
777  ptr);
778  return 1;
779 }
780 
781 
782 long
785  d->create();
786  d->show(PLACEMENT_OWNER);
787  return 1;
788 }
789 
790 
791 long
794  if (myAmGaming) {
795  mySimDelayTarget->setValue(1000);
796  }
797  return 1;
798 }
799 
800 
801 long
804  return 1;
805 }
806 
807 
808 long
811  return 1;
812 }
813 
814 
815 #ifdef HAVE_OSG
816 long
817 GUIApplicationWindow::onCmdNewOSG(FXObject*, FXSelector, void*) {
819  return 1;
820 }
821 #endif
822 
823 
824 long
826  GUIDialog_AboutSUMO* about =
827  new GUIDialog_AboutSUMO(this, "About SUMO", 0, 0);
828  about->create();
829  about->show(PLACEMENT_OWNER);
830  return 1;
831 }
832 
833 
834 long GUIApplicationWindow::onClipboardRequest(FXObject* /* sender */, FXSelector /* sel */, void* ptr) {
835  FXEvent* event = (FXEvent*)ptr;
836  FXString string = GUIUserIO::clipped.c_str();
837  setDNDData(FROM_CLIPBOARD, event->target, string);
838  return 1;
839 }
840 
841 
842 long
844  eventOccured();
845  return 1;
846 }
847 
848 
849 long
851  eventOccured();
852  return 1;
853 }
854 
855 
856 void
858  while (!myEvents.empty()) {
859  // get the next event
860  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
861  myEvents.pop();
862  // process
863  switch (e->getOwnType()) {
866  break;
868  if (myRunThread->simulationAvailable()) { // avoid race-condition related crash if reload was pressed
870  }
871  break;
874  case EVENT_ERROR_OCCURED:
876  break;
879  break;
880  default:
881  break;
882  }
883  delete e;
884  }
885  myToolBar2->forceRefresh();
886  myToolBar3->forceRefresh();
887 }
888 
889 
890 void
892  myAmLoading = false;
894  if (ec->myNet != 0) {
895 #ifndef NO_TRACI
896  std::map<int, traci::TraCIServer::CmdExecutor> execs;
899  try {
901  } catch (ProcessError& e) {
903  WRITE_ERROR(e.what());
904  delete ec->myNet;
905  ec->myNet = 0;
906  }
907 #endif
908  }
909 
910  // check whether the loading was successfull
911  if (ec->myNet == 0) {
912  // report failure
913  setStatusBarText("Loading of '" + ec->myFile + "' failed!");
915  closeAllWindows();
916  getApp()->exit(1);
917  }
918  } else {
919  // initialise simulation thread
920  if(!myRunThread->init(ec->myNet, ec->myBegin, ec->myEnd)) {
922  closeAllWindows();
923  getApp()->exit(1);
924  }
925  } else {
926  // report success
927  setStatusBarText("'" + ec->myFile + "' loaded.");
928  myWasStarted = false;
929  // initialise views
930  myViewNumber = 0;
932  if (ec->mySettingsFiles.size() > 0) {
933  // open a view for each file and apply settings
934  for (std::vector<std::string>::const_iterator it = ec->mySettingsFiles.begin(); it != ec->mySettingsFiles.end(); ++it) {
935  GUISettingsHandler settings(*it);
936  GUISUMOViewParent::ViewType vt = defaultType;
937  if (settings.getViewType() == "osg" || settings.getViewType() == "3d") {
939  }
940  if (settings.getViewType() == "opengl" || settings.getViewType() == "2d") {
942  }
943  GUISUMOAbstractView* view = openNewView(vt);
944  if (view == 0) {
945  break;
946  }
947  std::string settingsName = settings.addSettings(view);
948  view->addDecals(settings.getDecals());
949  settings.setViewport(view);
950  settings.setSnapshots(view);
951  if (settings.getDelay() > 0) {
952  mySimDelayTarget->setValue(settings.getDelay());
953  }
954  if (settings.getBreakpoints().size() > 0) {
956  }
957  }
958  } else {
959  openNewView(defaultType);
960  }
961 
962  if (isGaming()) {
963  setTitle("SUMO Traffic Light Game");
964  } else {
965  // set simulation name on the caption
966  std::string caption = "SUMO " + std::string(VERSION_STRING);
967  setTitle(MFXUtils::getTitleText(caption.c_str(), ec->myFile.c_str()));
968  }
969  // set simulation step begin information
971  }
972  }
973  getApp()->endWaitCursor();
974  // start if wished
976  onCmdStart(0, 0, 0);
977  }
978  update();
979 }
980 
981 
982 void
984  updateChildren();
986  update();
987 }
988 
989 
990 void
992  GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);
994 }
995 
996 
997 void
999  GUIEvent_SimulationEnded* ec = static_cast<GUIEvent_SimulationEnded*>(e);
1000  onCmdStop(0, 0, 0);
1001  if (GUIGlobals::gQuitOnEnd) {
1002  closeAllWindows();
1003  getApp()->exit(ec->getReason() == MSNet::SIMSTATE_ERROR_IN_SIM);
1004  } else {
1005  // build the text
1006  const std::string text = "Simulation ended at time: " + time2string(ec->getTimeStep()) +
1007  ".\nReason: " + MSNet::getStateMessage(ec->getReason());
1008  FXMessageBox::warning(this, MBOX_OK, "Simulation ended", "%s", text.c_str());
1009  }
1010 }
1011 
1012 
1013 
1014 void
1015 GUIApplicationWindow::load(const std::string& file, bool isNet, bool isReload) {
1016  getApp()->beginWaitCursor();
1017  myAmLoading = true;
1018  closeAllWindows();
1019  if (isReload) {
1020  myLoadThread->start();
1021  setStatusBarText("Reloading.");
1022  } else {
1023  gSchemeStorage.saveViewport(0, 0, -1); // recenter view
1024  myLoadThread->load(file, isNet);
1025  setStatusBarText("Loading '" + file + "'.");
1026  }
1027  update();
1028 }
1029 
1030 
1033  if (!myRunThread->simulationAvailable()) {
1034  myStatusbar->getStatusLine()->setText("No simulation loaded!");
1035  return 0;
1036  }
1037  std::string caption = "View #" + toString(myViewNumber++);
1038  FXuint opts = MDI_TRACKING;
1039  GUISUMOViewParent* w = new GUISUMOViewParent(myMDIClient, myMDIMenu, FXString(caption.c_str()),
1040  this, GUIIconSubSys::getIcon(ICON_APP), opts, 10, 10, 300, 200);
1042  w->create();
1043  if (myMDIClient->numChildren() == 1) {
1044  w->maximize();
1045  } else {
1046  myMDIClient->vertical(true);
1047  }
1048  myMDIClient->setActiveChild(w);
1049  return v;
1050 }
1051 
1052 
1053 FXGLCanvas*
1055  if (myMDIClient->numChildren() == 0) {
1056  return 0;
1057  }
1058  GUISUMOViewParent* share_tmp1 =
1059  static_cast<GUISUMOViewParent*>(myMDIClient->childAtIndex(0));
1060  return share_tmp1->getBuildGLCanvas();
1061 }
1062 
1063 
1064 void
1066  myTrackerLock.lock();
1067  myLCDLabel->setText("-------------");
1068  // remove trackers and other external windows
1069  size_t i;
1070  for (i = 0; i < mySubWindows.size(); ++i) {
1071  mySubWindows[i]->destroy();
1072  }
1073  for (i = 0; i < myTrackerWindows.size(); ++i) {
1074  myTrackerWindows[i]->destroy();
1075  }
1076  // delete the simulation
1078  // reset the caption
1079  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
1080  // delete other children
1081  while (myTrackerWindows.size() != 0) {
1082  delete myTrackerWindows[0];
1083  }
1084  while (mySubWindows.size() != 0) {
1085  delete mySubWindows[0];
1086  }
1087  mySubWindows.clear();
1088  // clear selected items
1089  gSelected.clear();
1090  // add a separator to the log
1093  // remove coordinate information
1094  myGeoCoordinate->setText("N/A");
1095  myCartesianCoordinate->setText("N/A");
1096  //
1098  update();
1099 }
1100 
1101 
1102 FXCursor*
1104  return getApp()->getDefaultCursor(DEF_ARROW_CURSOR);
1105 }
1106 
1107 
1108 SUMOTime
1111 }
1112 
1113 
1114 void
1116  load("", false);
1117 }
1118 
1119 
1120 void
1121 GUIApplicationWindow::setStatusBarText(const std::string& text) {
1122  myStatusbar->getStatusLine()->setText(text.c_str());
1123  myStatusbar->getStatusLine()->setNormalText(text.c_str());
1124 }
1125 
1126 
1127 void
1129  SUMOReal fracSeconds = STEPS2TIME(time);
1130  const bool hideFraction = myAmGaming || fmod(TS, 1.) == 0.;
1131  const int BuffSize = 100;
1132  char buffer[BuffSize];
1133  if (myShowTimeAsHMS) {
1134  const int hours = (int)fracSeconds / 3600;
1135  const int minutes = ((int)fracSeconds % 3600) / 60;
1136  fracSeconds = fracSeconds - 3600 * hours - 60 * minutes;
1137  const std::string format = (hideFraction ?
1138  "%02d-%02d-%02.0f" : "%02d-%02d-%06.3f");
1139  snprintf(buffer, BuffSize, format.c_str(), hours, minutes, fracSeconds);
1140  } else {
1141  const std::string format = (hideFraction ?
1142  "%13.0f" : "%13.3f");
1143  snprintf(buffer, BuffSize, format.c_str(), fracSeconds);
1144  }
1145  myLCDLabel->setText(buffer);
1146 }
1147 
1148 /****************************************************************************/
1149