Eclipse SUMO - Simulation of Urban MObility
GUISUMOViewParent.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
22 // A single child window which contains a view of the simulation area
23 /****************************************************************************/
24 #include <config.h>
25 
26 #include <string>
27 #include <vector>
28 #include <fxkeys.h>
30 #include <utils/geom/Position.h>
31 #include <utils/geom/Boundary.h>
45 #include <guisim/GUIVehicle.h>
46 #include <guisim/GUIPerson.h>
47 #include <guisim/GUIEdge.h>
48 #include <guisim/GUILane.h>
49 #include <guisim/GUINet.h>
52 #include <microsim/MSJunction.h>
53 #include <microsim/MSGlobals.h>
54 
55 #include "GUIGlobals.h"
56 #include "GUIViewTraffic.h"
57 #include "GUIApplicationWindow.h"
58 #include "GUISUMOViewParent.h"
59 
61 
62 #include <osgview/GUIOSGView.h>
63 
64 #define SPEEDFACTOR_SCALE 100.0
65 
66 // ===========================================================================
67 // FOX callback mapping
68 // ===========================================================================
69 FXDEFMAP(GUISUMOViewParent) GUISUMOViewParentMap[] = {
71  // FXMAPFUNC(SEL_COMMAND, MID_ALLOWROTATION, GUISUMOViewParent::onCmdAllowRotation),
72  FXMAPFUNC(SEL_COMMAND, MID_LOCATEJUNCTION, GUISUMOViewParent::onCmdLocate),
73  FXMAPFUNC(SEL_COMMAND, MID_LOCATEEDGE, GUISUMOViewParent::onCmdLocate),
74  FXMAPFUNC(SEL_COMMAND, MID_LOCATEVEHICLE, GUISUMOViewParent::onCmdLocate),
75  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPERSON, GUISUMOViewParent::onCmdLocate),
76  FXMAPFUNC(SEL_COMMAND, MID_LOCATECONTAINER, GUISUMOViewParent::onCmdLocate),
77  FXMAPFUNC(SEL_COMMAND, MID_LOCATETLS, GUISUMOViewParent::onCmdLocate),
78  FXMAPFUNC(SEL_COMMAND, MID_LOCATEADD, GUISUMOViewParent::onCmdLocate),
79  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOI, GUISUMOViewParent::onCmdLocate),
80  FXMAPFUNC(SEL_COMMAND, MID_LOCATEPOLY, GUISUMOViewParent::onCmdLocate),
83  FXMAPFUNC(SEL_COMMAND, MID_SIMSTEP, GUISUMOViewParent::onSimStep),
84 
85 };
86 
87 // Object implementation
88 FXIMPLEMENT(GUISUMOViewParent, GUIGlChildWindow, GUISUMOViewParentMap, ARRAYNUMBER(GUISUMOViewParentMap))
89 
90 
91 // ===========================================================================
92 // member method definitions
93 // ===========================================================================
94 GUISUMOViewParent::GUISUMOViewParent(FXMDIClient* p, FXMDIMenu* mdimenu,
95  const FXString& name,
96  GUIMainWindow* parentWindow,
97  FXIcon* ic, FXuint opts,
98  FXint x, FXint y, FXint w, FXint h) :
99  GUIGlChildWindow(p, parentWindow, mdimenu, name, nullptr, ic, opts, x, y, w, h) {
100  buildSpeedControlToolbar();
101  myParent->addGLChild(this);
102 }
103 
104 
107  switch (type) {
108  default:
109  case VIEW_2D_OPENGL:
110  myView = new GUIViewTraffic(myContentFrame, *myParent, this, net, myParent->getGLVisual(), share);
111  break;
112 #ifdef HAVE_OSG
113  case VIEW_3D_OSG:
114  myView = new GUIOSGView(myContentFrame, *myParent, this, net, myParent->getGLVisual(), share);
115  break;
116 #endif
117  }
118  myView->buildViewToolBars(this);
119  if (myParent->isGaming()) {
121  }
122  return myView;
123 }
124 
125 
127  myParent->removeGLChild(this);
128 }
129 
130 
131 void
133  if (value) {
135  } else {
137  }
138 }
139 
140 
141 void
143  myGLObjChooser[GLObjChooser->getMessageId()] = nullptr;
144 }
145 
146 
147 long
148 GUISUMOViewParent::onCmdMakeSnapshot(FXObject* sender, FXSelector, void*) {
149  MFXCheckableButton* button = dynamic_cast<MFXCheckableButton*>(sender);
150  // check if cast was sucesfully
151  if (button) {
152  if (button->amChecked()) {
153  myView->endSnapshot();
154  button->setChecked(false);
155  return 1;
156  }
157  // get the new file name
158  FXFileDialog opendialog(this, "Save Snapshot");
159  opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::CAMERA));
160  opendialog.setSelectMode(SELECTFILE_ANY);
161 #ifdef HAVE_FFMPEG
162  opendialog.setPatternList("All Image and Video Files (*.gif,*.bmp,*.xpm,*.pcx,*.ico,*.rgb,*.xbm,*.tga,*.png,*.jpg,*.jpeg,*.tif,*.tiff,*.ps,*.eps,*.pdf,*.svg,*.tex,*.pgf,*.h264,*.hevc,*.mp4)\n"
163  "All Video Files (*.h264,*.hevc,*.mp4)\n"
164 #else
165  opendialog.setPatternList("All Image Files (*.gif,*.bmp,*.xpm,*.pcx,*.ico,*.rgb,*.xbm,*.tga,*.png,*.jpg,*.jpeg,*.tif,*.tiff,*.ps,*.eps,*.pdf,*.svg,*.tex,*.pgf)\n"
166 #endif
167  "GIF Image (*.gif)\nBMP Image (*.bmp)\nXPM Image (*.xpm)\nPCX Image (*.pcx)\nICO Image (*.ico)\n"
168  "RGB Image (*.rgb)\nXBM Image (*.xbm)\nTARGA Image (*.tga)\nPNG Image (*.png)\n"
169  "JPEG Image (*.jpg,*.jpeg)\nTIFF Image (*.tif,*.tiff)\n"
170  "Postscript (*.ps)\nEncapsulated Postscript (*.eps)\nPortable Document Format (*.pdf)\n"
171  "Scalable Vector Graphics (*.svg)\nLATEX text strings (*.tex)\nPortable LaTeX Graphics (*.pgf)\n"
172  "All Files (*)");
173  if (gCurrentFolder.length() != 0) {
174  opendialog.setDirectory(gCurrentFolder);
175  }
176  if (!opendialog.execute() || !MFXUtils::userPermitsOverwritingWhenFileExists(this, opendialog.getFilename())) {
177  return 1;
178  }
179  gCurrentFolder = opendialog.getDirectory();
180  std::string file = opendialog.getFilename().text();
181  if (file.find(".") == std::string::npos) {
182  file.append(".png");
183  WRITE_MESSAGE("No file extension was specified - saving Snapshot as PNG.");
184  }
185  std::string error = myView->makeSnapshot(file);
186  if (error == "video") {
187  button->setChecked(!button->amChecked());
188  } else if (error != "") {
189  FXMessageBox::error(this, MBOX_OK, "Saving failed.", "%s", error.c_str());
190  }
191  }
192  return 1;
193 }
194 
195 
196 std::vector<GUIGlID>
197 GUISUMOViewParent::getObjectIDs(int messageId) const {
198  switch (messageId) {
199  case MID_LOCATEJUNCTION:
200  return static_cast<GUINet*>(GUINet::getInstance())->getJunctionIDs(myParent->listInternal());
201  case MID_LOCATEEDGE:
203  case MID_LOCATEVEHICLE: {
204  std::vector<GUIGlID> vehicles;
206  static_cast<GUIMEVehicleControl*>(static_cast<GUINet*>(MSNet::getInstance())->getGUIMEVehicleControl())->insertVehicleIDs(vehicles);
207  } else {
208  static_cast<GUIVehicleControl&>(MSNet::getInstance()->getVehicleControl()).insertVehicleIDs(
209  vehicles, myParent->listParking(), myParent->listTeleporting());
210  }
211  return vehicles;
212  }
213  case MID_LOCATEPERSON: {
214  std::vector<GUIGlID> persons;
215  static_cast<GUITransportableControl&>(MSNet::getInstance()->getPersonControl()).insertIDs(persons);
216  return persons;
217  }
218  case MID_LOCATECONTAINER: {
219  // get containers
220  std::vector<GUIGlID> containers;
221  static_cast<GUITransportableControl&>(MSNet::getInstance()->getContainerControl()).insertIDs(containers);
222  return containers;
223  }
224  case MID_LOCATETLS:
225  return static_cast<GUINet*>(GUINet::getInstance())->getTLSIDs();
226  case MID_LOCATEADD:
228  case MID_LOCATEPOI:
229  return static_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPOIIds();
230  case MID_LOCATEPOLY:
231  return static_cast<GUIShapeContainer&>(GUINet::getInstance()->getShapeContainer()).getPolygonIDs();
232  default:
233  throw ProcessError("Unknown Message ID in onCmdLocate");
234  }
235 }
236 
237 
238 long
239 GUISUMOViewParent::onCmdLocate(FXObject*, FXSelector sel, void*) {
240  int messageId = FXSELID(sel);
241  if (myGLObjChooser.count(messageId) == 0 || myGLObjChooser[messageId] == nullptr) {
242  FXIcon* icon = nullptr;
243  std::string titleString = "";
244  switch (messageId) {
245  case MID_LOCATEJUNCTION:
247  titleString = "Junction Chooser";
248  break;
249  case MID_LOCATEEDGE:
251  titleString = "Edge Chooser";
252  break;
253  case MID_LOCATEVEHICLE:
255  titleString = "Vehicle Chooser";
256  break;
257  case MID_LOCATEPERSON:
259  titleString = "Person Chooser";
260  break;
261  case MID_LOCATECONTAINER:
263  titleString = "Container Chooser";
264  break;
265  case MID_LOCATETLS:
267  titleString = "Traffic Lights Chooser";
268  break;
269  case MID_LOCATEADD:
271  titleString = "Additional Objects Chooser";
272  break;
273  case MID_LOCATEPOI:
275  titleString = "POI Chooser";
276  break;
277  case MID_LOCATEPOLY:
279  titleString = "Polygon Chooser";
280  break;
281  default:
282  throw ProcessError("Unknown Message ID in onCmdLocate");
283  }
284 
285  myGLObjChooser[messageId] = new GUIDialog_GLObjChooser(this, messageId, icon, titleString.c_str(), getObjectIDs(messageId), GUIGlObjectStorage::gIDStorage);
286 
287  } else {
288  myGLObjChooser[messageId]->restore();
289  myGLObjChooser[messageId]->setFocus();
290  }
291  myLocatorPopup->popdown();
292  myLocatorButton->killFocus();
293  myLocatorPopup->update();
294  return 1;
295 }
296 
297 
298 long
299 GUISUMOViewParent::onSimStep(FXObject*, FXSelector, void*) {
300  myView->update();
302  return 1;
303 }
304 
305 
306 bool
308  GUIGlObjectType type = o->getType();
309  if (gSelected.isSelected(type, o->getGlID())) {
310  return true;
311  } else if (type == GLO_EDGE) {
312  GUIEdge* edge = dynamic_cast<GUIEdge*>(o);
313  if (edge == nullptr) {
314  // hmph, just some security stuff
315  return false;
316  }
317  const std::vector<MSLane*>& lanes = edge->getLanes();
318  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
319  GUILane* l = dynamic_cast<GUILane*>(*j);
320  if (l != nullptr && gSelected.isSelected(GLO_LANE, l->getGlID())) {
321  return true;
322  }
323  }
324  return false;
325  } else {
326  return false;
327  }
328 }
329 
330 
331 long
332 GUISUMOViewParent::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
333  myView->onKeyPress(o, sel, ptr);
334  return 0;
335 }
336 
337 
338 long
339 GUISUMOViewParent::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
340  myView->onKeyRelease(o, sel, ptr);
341  return 0;
342 }
343 
344 
345 void
348  new FXVerticalSeparator(toolbar, GUIDesignVerticalSeparator);
349 
350  //myToolBarDragSpeed = new FXToolBarShell(this, GUIDesignToolBar);
351  //myToolBarSpeed = new FXToolBar(toolbar, myToolBarDragSpeed, GUIDesignToolBarRaisedSameTop);
352  //mySpeedFactorSlider = new FXSlider(myToolBarSpeed, this, MID_SPEEDFACTOR, LAYOUT_FIX_WIDTH | SLIDER_ARROW_UP | SLIDER_TICKS_TOP, 0, 0, 300, 10, 0, 0, 5, 0);
353  mySpeedFactorSlider = new FXSlider(toolbar, this, MID_SPEEDFACTOR, LAYOUT_FIX_WIDTH | SLIDER_ARROW_UP | SLIDER_TICKS_TOP, 0, 0, 200, 10, 0, 0, 5, 0);
354  mySpeedFactorSlider->setRange(0, 200);
355  mySpeedFactorSlider->setHeadSize(10);
356  mySpeedFactorSlider->setIncrement(1);
357  mySpeedFactorSlider->setTickDelta(100);
358  mySpeedFactorSlider->setValue(100);
359  mySpeedFactorSlider->setHelpText("Control speedFactor of tracked object");
360  //mySpeedFactorSlider->hide();
361 }
362 
363 long
364 GUISUMOViewParent::onCmdSpeedFactor(FXObject*, FXSelector, void*) {
365  if (myView != nullptr && myView->getTrackedID() != GUIGlObject::INVALID_ID) {
367  if (o != nullptr) {
368  const double speedFactor = mySpeedFactorSlider->getValue() / SPEEDFACTOR_SCALE;
369  if (o->getType() == GLO_VEHICLE) {
370  MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(o);
371  veh->setChosenSpeedFactor(speedFactor);
372  } else if (o->getType() == GLO_PERSON) {
373  //MSPerson* person = dynamic_cast<MSPerson*>(o);
374  //person->setChosenSpeedFactor(speedFactor);
375  }
376  mySpeedFactorSlider->setTipText(toString(speedFactor).c_str());
377  }
378 
379  }
380  return 1;
381 }
382 
383 long
384 GUISUMOViewParent::onUpdSpeedFactor(FXObject* sender, FXSelector, void* ptr) {
385  bool disable = myView == nullptr || myView->getTrackedID() == GUIGlObject::INVALID_ID;
386  sender->handle(this, FXSEL(SEL_COMMAND, disable ? ID_DISABLE : ID_ENABLE), ptr);
387  if (disable) {
388  mySpeedFactorSlider->hide();
389  } else {
391  if (o != nullptr) {
392  if (o->getType() == GLO_VEHICLE) {
393  MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(o);
395  } else if (o->getType() == GLO_PERSON) {
396  MSPerson* person = dynamic_cast<MSPerson*>(o);
397  mySpeedFactorSlider->setValue((int)(person->getChosenSpeedFactor() * SPEEDFACTOR_SCALE));
398  }
399  mySpeedFactorSlider->show();
400  } else {
401  myView->stopTrack();
402  mySpeedFactorSlider->hide();
403  }
404  }
405  return 1;
406 }
407 
408 
409 /****************************************************************************/
@ MID_MAKESNAPSHOT
Make snapshot - button.
Definition: GUIAppEnum.h:373
@ MID_LOCATEPERSON
Locate person - button.
Definition: GUIAppEnum.h:359
@ MID_LOCATEJUNCTION
Locate junction - button.
Definition: GUIAppEnum.h:349
@ MID_LOCATEPOLY
Locate polygons - button.
Definition: GUIAppEnum.h:369
@ MID_SPEEDFACTOR
scale vehicle speed
Definition: GUIAppEnum.h:383
@ MID_LOCATEADD
Locate addtional structure - button.
Definition: GUIAppEnum.h:365
@ MID_LOCATEPOI
Locate poi - button.
Definition: GUIAppEnum.h:367
@ MID_SIMSTEP
A Simulation step was performed.
Definition: GUIAppEnum.h:495
@ MID_LOCATEEDGE
Locate edge - button.
Definition: GUIAppEnum.h:351
@ MID_LOCATEVEHICLE
Locate vehicle - button.
Definition: GUIAppEnum.h:353
@ MID_LOCATETLS
Locate TLS - button.
Definition: GUIAppEnum.h:363
@ MID_LOCATECONTAINER
Locate container - button.
Definition: GUIAppEnum.h:361
#define GUIDesignVerticalSeparator
vertical separator
Definition: GUIDesigns.h:398
GUIGlObjectType
@ GLO_LANE
a lane
@ GLO_ADDITIONALELEMENT
reserved GLO type to pack all additionals elements
@ GLO_EDGE
an edge
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
GUISelectedStorage gSelected
A global holder of selected objects.
FXString gCurrentFolder
The folder used as last.
@ LOCATEVEHICLE
@ LOCATEPERSON
@ LOCATECONTAINER
@ LOCATEJUNCTION
#define SPEEDFACTOR_SCALE
FXDEFMAP(GUISUMOViewParent) GUISUMOViewParentMap[]
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A road/street connecting two junctions (gui-version)
Definition: GUIEdge.h:50
static std::vector< GUIGlID > getIDs(bool includeInternal)
Definition: GUIEdge.cpp:103
GUISUMOAbstractView * myView
The view.
FXMenuButton * myLocatorButton
The locator button.
FXVerticalFrame * myContentFrame
The contents frame.
FXPopup * myLocatorPopup
The locator menu.
GUIMainWindow * myParent
The parent window.
FXToolBar * myStaticNavigationToolBar
The static navigation tool bar.
FXMenuBar * myGripNavigationToolbar
The grip navigation tool bar.
static std::vector< GUIGlID > getIDList(GUIGlObjectType typeFilter)
Returns the list of gl-ids of all additional objects that match the given type.
static const GUIGlID INVALID_ID
Definition: GUIGlObject.h:67
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
Representation of a lane in the micro simulation (gui-version)
Definition: GUILane.h:59
The class responsible for building and deletion of vehicles (gui-version)
bool isGaming() const
return whether the gui is in gaming mode
bool listTeleporting() const
return whether to list teleporting vehicles
bool listParking() const
return whether to list parking vehicles
bool listInternal() const
return whether to list internal structures
FXGLVisual * getGLVisual() const
get GL Visual
void removeGLChild(GUIGlChildWindow *child)
removes the given child window from the list (GUIGlChildWindow)
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:81
std::string makeSnapshot(const std::string &destFile, const int w=-1, const int h=-1)
Takes a snapshots and writes it into the given file.
virtual void checkSnapshots()
Checks whether it is time for a snapshot.
virtual void endSnapshot()
Ends a video snapshot.
virtual void buildViewToolBars(GUIGlChildWindow *)
builds the view toolbars
virtual long onKeyPress(FXObject *o, FXSelector sel, void *data)
keyboard functions
virtual void stopTrack()
stop track
virtual long onKeyRelease(FXObject *o, FXSelector sel, void *data)
virtual GUIGlID getTrackedID() const
get tracked id
A single child window which contains a view of the simulation area.
std::map< int, GUIDialog_ChooserAbstract * > myGLObjChooser
map for existing dialogs
bool isSelected(GUIGlObject *o) const
true if the object is selected (may include extra logic besides calling gSelected)
ViewType
Available view types.
@ VIEW_3D_OSG
plain 3D OSG view (
@ VIEW_2D_OPENGL
plain 2D openGL view (
long onCmdSpeedFactor(FXObject *, FXSelector, void *)
speedFactor-callback
void eraseGLObjChooser(GUIDialog_GLObjChooser *GLObjChooser)
erase GLObjChooser
virtual GUISUMOAbstractView * init(FXGLCanvas *share, GUINet &net, ViewType type)
"Initialises" this window by building the contents
long onCmdLocate(FXObject *, FXSelector, void *)
locator-callback
void buildSpeedControlToolbar()
fox need this
long onUpdSpeedFactor(FXObject *, FXSelector, void *)
long onKeyRelease(FXObject *o, FXSelector sel, void *data)
long onCmdMakeSnapshot(FXObject *sender, FXSelector, void *)
Called if the user wants to make a snapshot (screenshot)
long onSimStep(FXObject *sender, FXSelector, void *)
Called on a simulation step.
FXSlider * mySpeedFactorSlider
slider for speedfactor
void setToolBarVisibility(const bool value)
about toggled gaming status
long onKeyPress(FXObject *o, FXSelector sel, void *data)
handle keys
~GUISUMOViewParent()
Destructor.
std::vector< GUIGlID > getObjectIDs(int messageId) const
get all objects of the given type
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
Storage for geometrical objects extended by mutexes.
GUI-version of the transportable control for building gui persons and containers.
The class responsible for building and deletion of vehicles (gui-version)
bool amChecked() const
check if this MFXCheckableButton is checked
void setChecked(bool val)
check or uncheck this MFXCheckableButton
static FXbool userPermitsOverwritingWhenFileExists(FXWindow *const parent, const FXString &file)
Returns true if either the file given by its name does not exist or the user allows overwriting it.
Definition: MFXUtils.cpp:39
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:51
void setChosenSpeedFactor(const double factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
double getChosenSpeedFactor() const
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
static bool gUseMesoSim
Definition: MSGlobals.h:94
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:1068
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:376
ShapeContainer & getShapeContainer()
Returns the shapes container.
Definition: MSNet.h:499
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1059
double getChosenSpeedFactor() const