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  // forward requests to the active view
133  FXMAPFUNC(SEL_COMMAND, MID_LOCATEJUNCTION, GUIApplicationWindow::onCmdLocate),
134  FXMAPFUNC(SEL_COMMAND, MID_LOCATEEDGE, GUIApplicationWindow::onCmdLocate),
135  FXMAPFUNC(SEL_COMMAND, MID_LOCATEVEHICLE, GUIApplicationWindow::onCmdLocate),
136  FXMAPFUNC(SEL_COMMAND, MID_LOCATETLS, GUIApplicationWindow::onCmdLocate),
137  FXMAPFUNC(SEL_COMMAND, MID_LOCATEADD, GUIApplicationWindow::onCmdLocate),
138  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOI, GUIApplicationWindow::onCmdLocate),
139  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOLY, GUIApplicationWindow::onCmdLocate),
147 
148  FXMAPFUNC(SEL_CLIPBOARD_REQUEST, 0, GUIApplicationWindow::onClipboardRequest),
149 
154 };
155 
156 // Object implementation
157 FXIMPLEMENT(GUIApplicationWindow, FXMainWindow, GUIApplicationWindowMap, ARRAYNUMBER(GUIApplicationWindowMap))
158 
159 // ===========================================================================
160 // member method definitions
161 // ===========================================================================
163  const std::string& configPattern)
164  : GUIMainWindow(a),
165  myLoadThread(0), myRunThread(0),
166  myAmLoading(false),
167  myAlternateSimDelay(0),
168  myRecentNets(a, "nets"), myConfigPattern(configPattern),
169  hadDependentBuild(false),
170  myShowTimeAsHMS(false) {
172 }
173 
174 
175 void
177  // do this not twice
178  if (hadDependentBuild) {
179  return;
180  }
181  hadDependentBuild = true;
182 
183  setTarget(this);
184  setSelector(MID_WINDOW);
185 
186  // build menu bar
187  myMenuBarDrag = new FXToolBarShell(this, FRAME_NORMAL);
188  myMenuBar = new FXMenuBar(myTopDock, myMenuBarDrag,
189  LAYOUT_SIDE_TOP | LAYOUT_FILL_X | FRAME_RAISED);
190  new FXToolBarGrip(myMenuBar, myMenuBar, FXMenuBar::ID_TOOLBARGRIP,
191  TOOLBARGRIP_DOUBLE);
192  buildToolBars();
193  // build the thread - io
198 
199  // build the status bar
200  myStatusbar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X | FRAME_RAISED);
201  {
202  myGeoFrame =
203  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
204  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
205  myGeoCoordinate = new FXLabel(myGeoFrame, "N/A", 0, LAYOUT_CENTER_Y);
207  new FXHorizontalFrame(myStatusbar, LAYOUT_FIX_WIDTH | LAYOUT_FILL_Y | LAYOUT_RIGHT | FRAME_SUNKEN,
208  0, 0, 20, 0, 0, 0, 0, 0, 0, 0);
209  myCartesianCoordinate = new FXLabel(myCartesianFrame, "N/A", 0, LAYOUT_CENTER_Y);
210  }
211 
212  // make the window a mdi-window
213  myMainSplitter = new FXSplitter(this,
214  SPLITTER_REVERSED | SPLITTER_VERTICAL | LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | FRAME_RAISED | FRAME_THICK);
215  myMDIClient = new FXMDIClient(myMainSplitter,
216  LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK);
217  myMDIMenu = new FXMDIMenu(this, myMDIClient);
218  new FXMDIWindowButton(myMenuBar, myMDIMenu, myMDIClient,
219  FXMDIClient::ID_MDI_MENUWINDOW, LAYOUT_LEFT);
220  new FXMDIDeleteButton(myMenuBar, myMDIClient,
221  FXMDIClient::ID_MDI_MENUCLOSE, FRAME_RAISED | LAYOUT_RIGHT);
222  new FXMDIRestoreButton(myMenuBar, myMDIClient,
223  FXMDIClient::ID_MDI_MENURESTORE, FRAME_RAISED | LAYOUT_RIGHT);
224  new FXMDIMinimizeButton(myMenuBar, myMDIClient,
225  FXMDIClient::ID_MDI_MENUMINIMIZE, FRAME_RAISED | LAYOUT_RIGHT);
226 
227  // build the message window
229  // fill menu and tool bar
230  fillMenuBar();
231  if (game) {
232  onCmdGaming(0, 0, 0);
233  myMenuBar->hide();
234  myToolBar1->hide();
235  myToolBar2->hide();
236  myToolBar4->hide();
237  myToolBar5->hide();
238  myMessageWindow->hide();
239  }
240  // build additional threads
241  myLoadThread = new GUILoadThread(getApp(), this, myEvents, myLoadThreadEvent);
242  myRunThread = new GUIRunThread(getApp(), this, *mySimDelayTarget, myEvents,
244  // set the status bar
245  myStatusbar->getStatusLine()->setText("Ready.");
246  // set the caption
247  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
248 
249  // start the simulation-thread (it will loop until the application ends deciding by itself whether to perform a step or not)
250  myRunThread->start();
252 }
253 
254 
255 void
257  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 0) {
258  setX(getApp()->reg().readIntEntry("SETTINGS", "x", 150));
259  setY(getApp()->reg().readIntEntry("SETTINGS", "y", 150));
260  setWidth(getApp()->reg().readIntEntry("SETTINGS", "width", 600));
261  setHeight(getApp()->reg().readIntEntry("SETTINGS", "height", 400));
262  }
263  gCurrentFolder = getApp()->reg().readStringEntry("SETTINGS", "basedir", "");
264  FXMainWindow::create();
265  myMenuBarDrag->create();
266  myToolBarDrag1->create();
267  myToolBarDrag2->create();
268  myFileMenu->create();
269  myEditMenu->create();
270  mySettingsMenu->create();
271  myLocatorMenu->create();
272  myControlMenu->create();
273  myWindowsMenu->create();
274  myHelpMenu->create();
275 
276  FXint width = getApp()->getNormalFont()->getTextWidth("8", 1) * 24;
277  myCartesianFrame->setWidth(width);
278  myGeoFrame->setWidth(width);
279 
280  show(PLACEMENT_SCREEN);
281  if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 1) {
282  maximize();
283  }
284  myShowTimeAsHMS = (getApp()->reg().readIntEntry("gui", "timeasHMS", 0) == 1);
285  myAlternateSimDelay = getApp()->reg().readIntEntry("gui", "alternateSimDelay", 100);
286 }
287 
288 
291  myRunThread->join();
292  closeAllWindows();
293  //
295  delete myGLVisual;
296  // delete some non-parented windows
297  delete myToolBarDrag1;
298  //
299  delete myRunThread;
300  delete myFileMenu;
301  delete myEditMenu;
302  delete mySettingsMenu;
303  delete myLocatorMenu;
304  delete myControlMenu;
305  delete myWindowsMenu;
306  delete myHelpMenu;
307 
308  delete myLoadThread;
309 
310  while (!myEvents.empty()) {
311  // get the next event
312  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
313  myEvents.pop();
314  delete e;
315  }
316 }
317 
318 
319 void
321  FXMainWindow::detach();
322  myMenuBarDrag->detach();
323  myToolBarDrag1->detach();
324 }
325 
326 
327 void
329  // build file menu
330  myFileMenu = new FXMenuPane(this);
331  new FXMenuTitle(myMenuBar, "&File", NULL, myFileMenu);
333  "&Open Simulation...\tCtl-O\tOpen a simulation (Configuration file).",
336  "Open &Network...\tCtl-N\tOpen a network.",
339  "&Reload\tCtl-R\tReloads the simulation / the network.",
341  new FXMenuSeparator(myFileMenu);
343  "&Close\tCtl-W\tClose the simulation.",
345  // Recent files
346  FXMenuSeparator* sep1 = new FXMenuSeparator(myFileMenu);
347  sep1->setTarget(&myRecentConfigs);
348  sep1->setSelector(FXRecentFiles::ID_ANYFILES);
349  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_1);
350  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_2);
351  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_3);
352  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_4);
353  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_5);
354  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_6);
355  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_7);
356  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_8);
357  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_9);
358  new FXMenuCommand(myFileMenu, "", 0, &myRecentConfigs, FXRecentFiles::ID_FILE_10);
359  new FXMenuCommand(myFileMenu, "C&lear Recent Configurations", NULL, &myRecentConfigs, FXRecentFiles::ID_CLEAR);
360  myRecentConfigs.setTarget(this);
361  myRecentConfigs.setSelector(MID_RECENTFILE);
362  FXMenuSeparator* sep2 = new FXMenuSeparator(myFileMenu);
363  sep2->setTarget(&myRecentNets);
364  sep2->setSelector(FXRecentFiles::ID_ANYFILES);
365  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_1);
366  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_2);
367  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_3);
368  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_4);
369  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_5);
370  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_6);
371  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_7);
372  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_8);
373  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_9);
374  new FXMenuCommand(myFileMenu, "", 0, &myRecentNets, FXRecentFiles::ID_FILE_10);
375  new FXMenuCommand(myFileMenu, "Cl&ear Recent Networks", NULL, &myRecentNets, FXRecentFiles::ID_CLEAR);
376  myRecentNets.setTarget(this);
377  myRecentNets.setSelector(MID_RECENTFILE);
378  new FXMenuSeparator(myFileMenu);
380  "&Quit\tCtl-Q\tQuit the Application.",
381  0, this, MID_QUIT, 0);
382 
383  // build edit menu
384  myEditMenu = new FXMenuPane(this);
385  new FXMenuTitle(myMenuBar, "&Edit", NULL, myEditMenu);
387  "Edit Selected...\tCtl-E\tOpens a Dialog for editing the List of Selected Items.",
389  new FXMenuSeparator(myEditMenu);
391  "Edit Breakpoints...\tCtl-B\tOpens a Dialog for editing breakpoints.",
392  0, this, MID_EDIT_BREAKPOINTS);
393 
394  // build settings menu
395  mySettingsMenu = new FXMenuPane(this);
396  new FXMenuTitle(myMenuBar, "&Settings", NULL, mySettingsMenu);
398  "Application Settings...\t\tOpen a Dialog for Application Settings editing.",
399  NULL, this, MID_APPSETTINGS);
400  new FXMenuCheck(mySettingsMenu,
401  "Gaming Mode\t\tToggle gaming mode on/off.",
402  this, MID_GAMING);
403  // build Locate menu
404  myLocatorMenu = new FXMenuPane(this);
405  new FXMenuTitle(myMenuBar, "&Locate", NULL, myLocatorMenu);
407  "Locate &Junctions\t\tOpen a Dialog for Locating a Junction.",
408  NULL, this, MID_LOCATEJUNCTION);
410  "Locate &Edges\t\tOpen a Dialog for Locating an Edge.",
411  NULL, this, MID_LOCATEEDGE);
412  if (!MSGlobals::gUseMesoSim) { // there are no gui-vehicles in mesosim
414  "Locate &Vehicles\t\tOpen a Dialog for Locating a Vehicle.",
415  NULL, this, MID_LOCATEVEHICLE);
416  }
418  "Locate &TLS\t\tOpen a Dialog for Locating a Traffic Light.",
419  NULL, this, MID_LOCATETLS);
421  "Locate &Additional\t\tOpen a Dialog for Locating an Additional Structure.",
422  NULL, this, MID_LOCATEADD);
424  "Locate &POI\t\tOpen a Dialog for Locating a Point of Intereset.",
425  NULL, this, MID_LOCATEPOI);
427  "Locate P&olygon\t\tOpen a Dialog for Locating a Polygon.",
428  NULL, this, MID_LOCATETLS);
429  new FXMenuSeparator(myLocatorMenu);
430  new FXMenuCheck(myLocatorMenu,
431  "Show Internal Structures\t\tShow internal junctions and streets in locator Dialog.",
432  this, MID_LISTINTERNAL);
433  // build control menu
434  myControlMenu = new FXMenuPane(this);
435  new FXMenuTitle(myMenuBar, "Simulation", NULL, myControlMenu);
437  "Run\tCtl-A\tStart running the simulation.",
438  NULL, this, MID_START);
440  "Stop\tCtl-S\tStop running the simulation.",
441  NULL, this, MID_STOP);
443  "Step\tCtl-D\tPerform one simulation step.",
444  NULL, this, MID_STEP);
445 
446  // build windows menu
447  myWindowsMenu = new FXMenuPane(this);
448  new FXMenuTitle(myMenuBar, "&Windows", NULL, myWindowsMenu);
449  new FXMenuCheck(myWindowsMenu,
450  "Show Status Line\t\tToggle the Status Bar on/off.",
451  myStatusbar, FXWindow::ID_TOGGLESHOWN);
452  new FXMenuCheck(myWindowsMenu,
453  "Show Message Window\t\tToggle the Message Window on/off.",
454  myMessageWindow, FXWindow::ID_TOGGLESHOWN);
455  new FXMenuCheck(myWindowsMenu,
456  "Show Simulation Time\t\tToggle the Simulation Time on/off.",
457  myToolBar3, FXWindow::ID_TOGGLESHOWN);
458  new FXMenuCheck(myWindowsMenu,
459  "Show Simulation Delay\t\tToggle the Simulation Delay Entry on/off.",
460  myToolBar4, FXWindow::ID_TOGGLESHOWN);
462  new FXMenuSeparator(myWindowsMenu);
463  new FXMenuCommand(myWindowsMenu, "Tile &Horizontally",
465  myMDIClient, FXMDIClient::ID_MDI_TILEHORIZONTAL);
466  new FXMenuCommand(myWindowsMenu, "Tile &Vertically",
468  myMDIClient, FXMDIClient::ID_MDI_TILEVERTICAL);
469  new FXMenuCommand(myWindowsMenu, "Cascade",
471  myMDIClient, FXMDIClient::ID_MDI_CASCADE);
472  new FXMenuCommand(myWindowsMenu, "&Close", NULL,
473  myMDIClient, FXMDIClient::ID_MDI_CLOSE);
474  sep1 = new FXMenuSeparator(myWindowsMenu);
475  sep1->setTarget(myMDIClient);
476  sep1->setSelector(FXMDIClient::ID_MDI_ANY);
477  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_1);
478  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_2);
479  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_3);
480  new FXMenuCommand(myWindowsMenu, "", 0, myMDIClient, FXMDIClient::ID_MDI_4);
481  new FXMenuCommand(myWindowsMenu, "&Others...", 0, myMDIClient, FXMDIClient::ID_MDI_OVER_5);
482  new FXMenuSeparator(myWindowsMenu);
484  "Clear Message Window\t\tClear the message window.",
485  0, this, MID_CLEARMESSAGEWINDOW);
486 
487  // build help menu
488  myHelpMenu = new FXMenuPane(this);
489  new FXMenuTitle(myMenuBar, "&Help", NULL, myHelpMenu);
491  this, MID_ABOUT);
492 }
493 
494 
495 void
497  // build tool bars
498  {
499  // file and simulation tool bar
500  myToolBarDrag1 = new FXToolBarShell(this, FRAME_NORMAL);
501  myToolBar1 = new FXToolBar(myTopDock, myToolBarDrag1,
502  LAYOUT_DOCK_NEXT | LAYOUT_SIDE_TOP | FRAME_RAISED);
503  new FXToolBarGrip(myToolBar1, myToolBar1, FXToolBar::ID_TOOLBARGRIP,
504  TOOLBARGRIP_DOUBLE);
505  // build file tools
506  new FXButton(myToolBar1, "\t\tOpen a simulation (Configuration file).",
508  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
509  new FXButton(myToolBar1, "\t\tOpen a network.",
511  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
512  new FXButton(myToolBar1, "\t\tReloads the simulation / the network.",
514  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
515  }
516  {
517  // build simulation tools
518  myToolBarDrag2 = new FXToolBarShell(this, FRAME_NORMAL);
519  myToolBar2 = new FXToolBar(myTopDock, myToolBarDrag2,
520  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
521  new FXToolBarGrip(myToolBar2, myToolBar2, FXToolBar::ID_TOOLBARGRIP,
522  TOOLBARGRIP_DOUBLE);
523  new FXButton(myToolBar2, "\t\tStart the loaded simulation.",
525  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
526  new FXButton(myToolBar2, "\t\tStop the running simulation.",
528  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
529  new FXButton(myToolBar2, "\t\tPerform a single simulation step.",
531  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
532  }
533  {
534  // Simulation Step Display
535  myToolBarDrag3 = new FXToolBarShell(this, FRAME_NORMAL);
536  myToolBar3 = new FXToolBar(myTopDock, myToolBarDrag3,
537  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
538  new FXToolBarGrip(myToolBar3, myToolBar3, FXToolBar::ID_TOOLBARGRIP,
539  TOOLBARGRIP_DOUBLE);
540  new FXButton(myToolBar3, "Time:\t\tToggle between seconds and hour:minute:seconds display", 0, this, MID_TIME_TOOGLE,
541  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
542  myLCDLabel = new FXEX::FXLCDLabel(myToolBar3, 13, 0, 0, JUSTIFY_RIGHT);
546  myLCDLabel->setGroove(2);
547  myLCDLabel->setText("-------------");
548  }
549  {
550  // Simulation Delay
551  myToolBarDrag4 = new FXToolBarShell(this, FRAME_NORMAL);
552  myToolBar4 = new FXToolBar(myTopDock, myToolBarDrag4,
553  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED | LAYOUT_FILL_Y);
554  new FXToolBarGrip(myToolBar4, myToolBar4, FXToolBar::ID_TOOLBARGRIP,
555  TOOLBARGRIP_DOUBLE);
556  new FXButton(myToolBar4, "Delay (ms):\t\tToggle between alternative delay values", 0, this, MID_DELAY_TOOGLE,
557  BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
560  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK | LAYOUT_FILL_Y);
562  mySimDelayTarget->setIncrements(1, 10, 10);
563  mySimDelayTarget->setRange(0, 1000);
565  }
566  {
567  // Views
568  myToolBarDrag5 = new FXToolBarShell(this, FRAME_NORMAL);
569  myToolBar5 = new FXToolBar(myTopDock, myToolBarDrag5,
570  LAYOUT_DOCK_SAME | LAYOUT_SIDE_TOP | FRAME_RAISED);
571  new FXToolBarGrip(myToolBar5, myToolBar5, FXToolBar::ID_TOOLBARGRIP,
572  TOOLBARGRIP_DOUBLE);
573  // build view tools
574  new FXButton(myToolBar5, "\t\tOpen a new microscopic view.",
576  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
577 #ifdef HAVE_OSG
578  new FXButton(myToolBar5, "\t\tOpen a new 3D view.",
580  ICON_ABOVE_TEXT | BUTTON_TOOLBAR | FRAME_RAISED | LAYOUT_TOP | LAYOUT_LEFT);
581 #endif
582  }
583 }
584 
585 
586 long
588  getApp()->reg().writeIntEntry("SETTINGS", "x", getX());
589  getApp()->reg().writeIntEntry("SETTINGS", "y", getY());
590  getApp()->reg().writeIntEntry("SETTINGS", "width", getWidth());
591  getApp()->reg().writeIntEntry("SETTINGS", "height", getHeight());
592  getApp()->reg().writeStringEntry("SETTINGS", "basedir", gCurrentFolder.text());
593  getApp()->reg().writeIntEntry("SETTINGS", "maximized", isMaximized() ? 1 : 0);
594  getApp()->reg().writeIntEntry("gui", "timeasHMS", myShowTimeAsHMS ? 1 : 0);
595  getApp()->reg().writeIntEntry("gui", "alternateSimDelay", myAlternateSimDelay);
596  getApp()->exit(0);
597  return 1;
598 }
599 
600 
601 long
603  GUIDialog_GLChosenEditor* chooser =
605  chooser->create();
606  chooser->show();
607  return 1;
608 }
609 
610 
611 long
613  GUIDialog_Breakpoints* chooser = new GUIDialog_Breakpoints(this);
614  chooser->create();
615  chooser->show();
616  return 1;
617 }
618 
619 
620 long
622  // get the new file name
623  FXFileDialog opendialog(this, "Open Simulation Configuration");
624  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
625  opendialog.setSelectMode(SELECTFILE_EXISTING);
626  opendialog.setPatternList(myConfigPattern.c_str());
627  if (gCurrentFolder.length() != 0) {
628  opendialog.setDirectory(gCurrentFolder);
629  }
630  if (opendialog.execute()) {
631  gCurrentFolder = opendialog.getDirectory();
632  std::string file = opendialog.getFilename().text();
633  load(file, false);
634  myRecentConfigs.appendFile(file.c_str());
635  }
636  return 1;
637 }
638 
639 
640 long
642  // get the new file name
643  FXFileDialog opendialog(this, "Open Network");
644  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
645  opendialog.setSelectMode(SELECTFILE_EXISTING);
646  opendialog.setPatternList("SUMO nets (*.net.xml)\nAll files (*)");
647  if (gCurrentFolder.length() != 0) {
648  opendialog.setDirectory(gCurrentFolder);
649  }
650  if (opendialog.execute()) {
651  gCurrentFolder = opendialog.getDirectory();
652  std::string file = opendialog.getFilename().text();
653  load(file, true);
654  myRecentNets.appendFile(file.c_str());
655  }
656  return 1;
657 }
658 
659 
660 long
662  load("", false, true);
663  return 1;
664 }
665 
666 
667 long
668 GUIApplicationWindow::onCmdOpenRecent(FXObject* sender, FXSelector, void* data) {
669  if (myAmLoading) {
670  myStatusbar->getStatusLine()->setText("Already loading!");
671  return 1;
672  }
673  std::string file((const char*)data);
674  load(file, sender == &myRecentNets);
675  return 1;
676 }
677 
678 
679 long
681  closeAllWindows();
682  return 1;
683 }
684 
685 
686 long
687 GUIApplicationWindow::onUpdOpen(FXObject* sender, FXSelector, void* ptr) {
688  sender->handle(this,
689  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
690  ptr);
691  return 1;
692 }
693 
694 
695 long
696 GUIApplicationWindow::onUpdReload(FXObject* sender, FXSelector, void* ptr) {
697  sender->handle(this,
699  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
700  ptr);
701  return 1;
702 }
703 
704 
705 long
706 GUIApplicationWindow::onUpdOpenRecent(FXObject* sender, FXSelector, void* ptr) {
707  sender->handle(this,
708  myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
709  ptr);
710  return 1;
711 }
712 
713 
714 long
715 GUIApplicationWindow::onUpdAddView(FXObject* sender, FXSelector, void* ptr) {
716  sender->handle(this,
718  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
719  ptr);
720  return 1;
721 }
722 
723 
724 long
726  // check whether a net was loaded successfully
728  myStatusbar->getStatusLine()->setText("No simulation loaded!");
729  return 1;
730  }
731  // check whether it was started before and paused;
732  if (!myWasStarted) {
733  myRunThread->begin();
734  myWasStarted = true;
735  }
736  myRunThread->resume();
737  return 1;
738 }
739 
740 
741 long
743  myRunThread->stop();
744  return 1;
745 }
746 
747 
748 long
750  // check whether a net was loaded successfully
752  myStatusbar->getStatusLine()->setText("No simulation loaded!");
753  return 1;
754  }
755  // check whether it was started before and paused;
756  if (!myWasStarted) {
757  myRunThread->begin();
758  myWasStarted = true;
759  }
761  return 1;
762 }
763 
764 
765 long
770  }
771  return 1;
772 }
773 
774 
775 long
777  const SUMOTime tmp = myAlternateSimDelay;
780  return 1;
781 }
782 
783 
784 long
787  return 1;
788 }
789 
790 
791 long
792 GUIApplicationWindow::onUpdStart(FXObject* sender, FXSelector, void* ptr) {
793  sender->handle(this,
795  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
796  ptr);
797  return 1;
798 }
799 
800 
801 long
802 GUIApplicationWindow::onUpdStop(FXObject* sender, FXSelector, void* ptr) {
803  sender->handle(this,
805  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
806  ptr);
807  return 1;
808 }
809 
810 
811 long
812 GUIApplicationWindow::onUpdStep(FXObject* sender, FXSelector, void* ptr) {
813  sender->handle(this,
815  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
816  ptr);
817  return 1;
818 }
819 
820 
821 long
822 GUIApplicationWindow::onUpdNeedsSimulation(FXObject* sender, FXSelector, void* ptr) {
823  sender->handle(this,
825  ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
826  ptr);
827  return 1;
828 }
829 
830 
831 long
832 GUIApplicationWindow::onCmdLocate(FXObject*, FXSelector sel, void*) {
833  if (myMDIClient->numChildren() > 0) {
834  GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
835  if (w != 0) {
836  w->onCmdLocate(0, sel, 0);
837  }
838  }
839  return 1;
840 }
841 
842 long
845  d->create();
846  d->show(PLACEMENT_OWNER);
847  return 1;
848 }
849 
850 
851 long
854  if (myAmGaming) {
855  mySimDelayTarget->setValue(1000);
856  }
857  return 1;
858 }
859 
860 
861 long
864  return 1;
865 }
866 
867 
868 long
871  return 1;
872 }
873 
874 
875 #ifdef HAVE_OSG
876 long
877 GUIApplicationWindow::onCmdNewOSG(FXObject*, FXSelector, void*) {
879  return 1;
880 }
881 #endif
882 
883 
884 long
886  GUIDialog_AboutSUMO* about =
887  new GUIDialog_AboutSUMO(this, "About SUMO", 0, 0);
888  about->create();
889  about->show(PLACEMENT_OWNER);
890  return 1;
891 }
892 
893 
894 long GUIApplicationWindow::onClipboardRequest(FXObject* /* sender */, FXSelector /* sel */, void* ptr) {
895  FXEvent* event = (FXEvent*)ptr;
896  FXString string = GUIUserIO::clipped.c_str();
897  setDNDData(FROM_CLIPBOARD, event->target, string);
898  return 1;
899 }
900 
901 
902 long
904  eventOccured();
905  return 1;
906 }
907 
908 
909 long
911  eventOccured();
912  return 1;
913 }
914 
915 
916 void
918  while (!myEvents.empty()) {
919  // get the next event
920  GUIEvent* e = static_cast<GUIEvent*>(myEvents.top());
921  myEvents.pop();
922  // process
923  switch (e->getOwnType()) {
926  break;
928  if (myRunThread->simulationAvailable()) { // avoid race-condition related crash if reload was pressed
930  }
931  break;
934  case EVENT_ERROR_OCCURED:
936  break;
939  break;
940  default:
941  break;
942  }
943  delete e;
944  }
945  myToolBar2->forceRefresh();
946  myToolBar3->forceRefresh();
947 }
948 
949 
950 void
952  myAmLoading = false;
954  if (ec->myNet != 0) {
955 #ifndef NO_TRACI
956  std::map<int, TraCIServer::CmdExecutor> execs;
959  try {
961  } catch (ProcessError& e) {
963  WRITE_ERROR(e.what());
964  delete ec->myNet;
965  ec->myNet = 0;
966  }
967 #endif
968  }
969 
970  // check whether the loading was successfull
971  if (ec->myNet == 0) {
972  // report failure
973  setStatusBarText("Loading of '" + ec->myFile + "' failed!");
975  closeAllWindows();
976  getApp()->exit(1);
977  }
978  } else {
979  // initialise simulation thread
980  if (!myRunThread->init(ec->myNet, ec->myBegin, ec->myEnd)) {
982  closeAllWindows();
983  getApp()->exit(1);
984  }
985  } else {
986  // report success
987  setStatusBarText("'" + ec->myFile + "' loaded.");
988  myWasStarted = false;
989  // initialise views
990  myViewNumber = 0;
992  if (ec->mySettingsFiles.size() > 0) {
993  // open a view for each file and apply settings
994  for (std::vector<std::string>::const_iterator it = ec->mySettingsFiles.begin(); it != ec->mySettingsFiles.end(); ++it) {
995  GUISettingsHandler settings(*it);
996  GUISUMOViewParent::ViewType vt = defaultType;
997  if (settings.getViewType() == "osg" || settings.getViewType() == "3d") {
999  }
1000  if (settings.getViewType() == "opengl" || settings.getViewType() == "2d") {
1002  }
1003  GUISUMOAbstractView* view = openNewView(vt);
1004  if (view == 0) {
1005  break;
1006  }
1007  std::string settingsName = settings.addSettings(view);
1008  view->addDecals(settings.getDecals());
1009  settings.setViewport(view);
1010  settings.setSnapshots(view);
1011  if (settings.getDelay() > 0) {
1012  mySimDelayTarget->setValue(settings.getDelay());
1013  }
1014  if (settings.getBreakpoints().size() > 0) {
1016  }
1017  }
1018  } else {
1019  openNewView(defaultType);
1020  }
1021 
1022  if (isGaming()) {
1023  setTitle("SUMO Traffic Light Game");
1024  } else {
1025  // set simulation name on the caption
1026  std::string caption = "SUMO " + std::string(VERSION_STRING);
1027  setTitle(MFXUtils::getTitleText(caption.c_str(), ec->myFile.c_str()));
1028  }
1029  // set simulation step begin information
1031  }
1032  }
1033  getApp()->endWaitCursor();
1034  // start if wished
1036  onCmdStart(0, 0, 0);
1037  }
1038  update();
1039 }
1040 
1041 
1042 void
1044  updateChildren();
1046  update();
1047 }
1048 
1049 
1050 void
1052  GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);
1054 }
1055 
1056 
1057 void
1059  GUIEvent_SimulationEnded* ec = static_cast<GUIEvent_SimulationEnded*>(e);
1060  onCmdStop(0, 0, 0);
1061  if (GUIGlobals::gQuitOnEnd) {
1062  closeAllWindows();
1063  getApp()->exit(ec->getReason() == MSNet::SIMSTATE_ERROR_IN_SIM);
1064  } else {
1065  // build the text
1066  const std::string text = "Simulation ended at time: " + time2string(ec->getTimeStep()) +
1067  ".\nReason: " + MSNet::getStateMessage(ec->getReason());
1068  FXMessageBox::warning(this, MBOX_OK, "Simulation ended", "%s", text.c_str());
1069  }
1070 }
1071 
1072 
1073 
1074 void
1075 GUIApplicationWindow::load(const std::string& file, bool isNet, bool isReload) {
1076  getApp()->beginWaitCursor();
1077  myAmLoading = true;
1078  closeAllWindows();
1079  if (isReload) {
1080  myLoadThread->start();
1081  setStatusBarText("Reloading.");
1082  } else {
1083  gSchemeStorage.saveViewport(0, 0, -1); // recenter view
1084  myLoadThread->load(file, isNet);
1085  setStatusBarText("Loading '" + file + "'.");
1086  }
1087  update();
1088 }
1089 
1090 
1093  if (!myRunThread->simulationAvailable()) {
1094  myStatusbar->getStatusLine()->setText("No simulation loaded!");
1095  return 0;
1096  }
1097  std::string caption = "View #" + toString(myViewNumber++);
1098  FXuint opts = MDI_TRACKING;
1099  GUISUMOViewParent* w = new GUISUMOViewParent(myMDIClient, myMDIMenu, FXString(caption.c_str()),
1100  this, GUIIconSubSys::getIcon(ICON_APP), opts, 10, 10, 300, 200);
1102  w->create();
1103  if (myMDIClient->numChildren() == 1) {
1104  w->maximize();
1105  } else {
1106  myMDIClient->vertical(true);
1107  }
1108  myMDIClient->setActiveChild(w);
1109  return v;
1110 }
1111 
1112 
1113 FXGLCanvas*
1115  if (myMDIClient->numChildren() == 0) {
1116  return 0;
1117  }
1118  GUISUMOViewParent* share_tmp1 =
1119  static_cast<GUISUMOViewParent*>(myMDIClient->childAtIndex(0));
1120  return share_tmp1->getBuildGLCanvas();
1121 }
1122 
1123 
1124 void
1126  myTrackerLock.lock();
1127  myLCDLabel->setText("-------------");
1128  // remove trackers and other external windows
1129  size_t i;
1130  for (i = 0; i < mySubWindows.size(); ++i) {
1131  mySubWindows[i]->destroy();
1132  }
1133  for (i = 0; i < myTrackerWindows.size(); ++i) {
1134  myTrackerWindows[i]->destroy();
1135  }
1136  // delete the simulation
1138  // reset the caption
1139  setTitle(MFXUtils::getTitleText(("SUMO " + std::string(VERSION_STRING)).c_str()));
1140  // delete other children
1141  while (myTrackerWindows.size() != 0) {
1142  delete myTrackerWindows[0];
1143  }
1144  while (mySubWindows.size() != 0) {
1145  delete mySubWindows[0];
1146  }
1147  mySubWindows.clear();
1148  // clear selected items
1149  gSelected.clear();
1150  // add a separator to the log
1153  // remove coordinate information
1154  myGeoCoordinate->setText("N/A");
1155  myCartesianCoordinate->setText("N/A");
1156  //
1158  update();
1159 }
1160 
1161 
1162 FXCursor*
1164  return getApp()->getDefaultCursor(DEF_ARROW_CURSOR);
1165 }
1166 
1167 
1168 SUMOTime
1171 }
1172 
1173 
1174 void
1176  load("", false);
1177 }
1178 
1179 
1180 void
1182  myStatusbar->getStatusLine()->setText(text.c_str());
1183  myStatusbar->getStatusLine()->setNormalText(text.c_str());
1184 }
1185 
1186 
1187 void
1189  SUMOReal fracSeconds = STEPS2TIME(time);
1190  const bool hideFraction = myAmGaming || fmod(TS, 1.) == 0.;
1191  const int BuffSize = 100;
1192  char buffer[BuffSize];
1193  if (myShowTimeAsHMS) {
1194  const int hours = (int)fracSeconds / 3600;
1195  const int minutes = ((int)fracSeconds % 3600) / 60;
1196  fracSeconds = fracSeconds - 3600 * hours - 60 * minutes;
1197  const std::string format = (hideFraction ?
1198  "%02d-%02d-%02.0f" : "%02d-%02d-%06.3f");
1199  snprintf(buffer, BuffSize, format.c_str(), hours, minutes, fracSeconds);
1200  } else {
1201  const std::string format = (hideFraction ?
1202  "%13.0f" : "%13.3f");
1203  snprintf(buffer, BuffSize, format.c_str(), fracSeconds);
1204  }
1205  myLCDLabel->setText(buffer);
1206 }
1207 
1208 /****************************************************************************/
1209