Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/gui/globjects/GUIGlObject.cpp
169684 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file GUIGlObject.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Laura Bieker
19
/// @date Sept 2002
20
///
21
// Base class for all objects that may be displayed within the openGL-gui
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <string>
26
#include <stack>
27
#include <utils/common/MsgHandler.h>
28
#include <utils/common/ToString.h>
29
#include <utils/geom/GeoConvHelper.h>
30
#include <utils/gui/windows/GUISUMOAbstractView.h>
31
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
32
#include <utils/gui/div/GUIParameterTableWindow.h>
33
#include <utils/foxtools/MFXMenuHeader.h>
34
#include <utils/gui/images/GUIIconSubSys.h>
35
#include <utils/gui/windows/GUIAppEnum.h>
36
#include <utils/gui/windows/GUIMainWindow.h>
37
#include <utils/gui/div/GUIGlobalSelection.h>
38
#include <utils/gui/div/GLHelper.h>
39
#include <utils/gui/div/GLObjectValuePassConnector.h>
40
#include <utils/gui/div/GUIDesigns.h>
41
#include <utils/geom/GeomHelper.h>
42
#include <utils/gui/div/GUIGlobalViewObjectsHandler.h>
43
#include <utils/options/OptionsCont.h>
44
45
#include "GUIGlObject.h"
46
#include "GUIGlObjectStorage.h"
47
48
// ===========================================================================
49
// static members
50
// ===========================================================================
51
52
StringBijection<GUIGlObjectType>::Entry GUIGlObject::GUIGlObjectTypeNamesInitializer[] = {
53
{"network", GLO_NETWORK},
54
//
55
{"networkElement", GLO_NETWORKELEMENT},
56
{"edge", GLO_EDGE},
57
{"lane", GLO_LANE},
58
{"junction", GLO_JUNCTION},
59
{"connection", GLO_CONNECTION},
60
{"crossing", GLO_CROSSING},
61
{"walkingArea", GLO_WALKINGAREA},
62
{"tlLogic", GLO_TLLOGIC},
63
{"edgeType", GLO_EDGETYPE},
64
{"laneType", GLO_LANETYPE},
65
//
66
{"parentChildLine", GLO_PARENTCHILDLINE},
67
//
68
{"additional", GLO_ADDITIONALELEMENT},
69
{"stoppingPlace", GLO_STOPPING_PLACE},
70
{"busStop", GLO_BUS_STOP},
71
{"trainStop", GLO_TRAIN_STOP},
72
{"access", GLO_ACCESS},
73
{"taz", GLO_TAZ},
74
{"containerStop", GLO_CONTAINER_STOP},
75
{"chargingStation", GLO_CHARGING_STATION},
76
{"parkingArea", GLO_PARKING_AREA},
77
{"stoppingPlaceLast", GLO_STOPPING_PLACE_LAST},
78
{"parkingSpace", GLO_PARKING_SPACE},
79
{"e1Detector", GLO_E1DETECTOR},
80
{"e1DetectorME", GLO_E1DETECTOR_ME},
81
{"e1DetectorInstant", GLO_E1DETECTOR_INSTANT},
82
{"e2Detector", GLO_E2DETECTOR},
83
{"e3Detector", GLO_E3DETECTOR},
84
{"entryExitDetector", GLO_DET_ENTRYEXIT},
85
{"entryDetector", GLO_DET_ENTRY},
86
{"exitDetector", GLO_DET_EXIT},
87
{"rerouter", GLO_REROUTER},
88
{"rerouterInterval", GLO_REROUTER_INTERVAL},
89
{"closingreroute", GLO_REROUTER_CLOSINGREROUTE},
90
{"closingLaneReroute", GLO_REROUTER_CLOSINGLANEREROUTE},
91
{"parkingAreaReroute", GLO_REROUTER_PARKINGAREAREROUTE},
92
{"destProbReroute", GLO_REROUTER_DESTPROBREROUTE},
93
{"routeProbReroute", GLO_REROUTER_ROUTEPROBREROUTE},
94
{"rerouterEdge", GLO_REROUTER_EDGE},
95
{"variableSpeedSign", GLO_VSS},
96
{"variableSpeedSignStep", GLO_VSS_STEP},
97
{"calibrator", GLO_CALIBRATOR},
98
{"calibratorFlow", GLO_CALIBRATOR_FLOW},
99
{"routeProbe", GLO_ROUTEPROBE},
100
{"vaporizer", GLO_VAPORIZER},
101
{"wire", GLO_WIRE},
102
{"overheadWireSegment", GLO_OVERHEAD_WIRE_SEGMENT},
103
{"tractionsubstation", GLO_TRACTIONSUBSTATION},
104
{"additionalLast", GLO_ADDITIONALELEMENT_LAST},
105
//
106
{"laneArrows", GLO_LANEARROWS},
107
//
108
{"shape", GLO_SHAPE},
109
{"polygon", GLO_POLYGON},
110
{"poi", GLO_POI},
111
{"jupedsim.walkable_area", GLO_JPS_WALKABLEAREA},
112
{"jupedsim.obstacle", GLO_JPS_OBSTACLE},
113
{"shapeLast", GLO_SHAPE_LAST},
114
//
115
{"routeElement", GLO_ROUTEELEMENT},
116
{"vType", GLO_VTYPE},
117
{"vTypeRef", GLO_VTYPE_REF},
118
{"vTypeDistribution", GLO_VTYPE_DISTRIBUTION},
119
//
120
{"route", GLO_ROUTE},
121
{"routeEmbedded", GLO_ROUTE_EMBEDDED},
122
{"routeRef", GLO_ROUTE_REF},
123
{"routeDistribution", GLO_ROUTE_DISTRIBUTION},
124
//
125
{"ride", GLO_RIDE},
126
{"walk", GLO_WALK},
127
{"personTrip", GLO_PERSONTRIP},
128
{"transport", GLO_TRANSPORT},
129
{"tranship", GLO_TRANSHIP},
130
//
131
{"stop", GLO_STOP},
132
{"stopPlan", GLO_STOP_PLAN},
133
//
134
{"vehicle", GLO_VEHICLE},
135
{"trip", GLO_TRIP},
136
{"flow", GLO_FLOW},
137
{"routeFlow", GLO_ROUTEFLOW},
138
//
139
{"container", GLO_CONTAINER},
140
{"containerFlow", GLO_CONTAINERFLOW},
141
//
142
{"person", GLO_PERSON},
143
{"personFlow", GLO_PERSONFLOW},
144
//
145
{"edgeData", GLO_EDGEDATA},
146
{"edgeRelData", GLO_EDGERELDATA},
147
{"TAZRelData", GLO_TAZRELDATA},
148
{"meanData", GLO_MEANDATA},
149
{"dataSet", GLO_DATASET},
150
{"dataInterval", GLO_DATAINTERVAL},
151
//
152
{"lockIcon", GLO_LOCKICON},
153
{"textName", GLO_TEXTNAME},
154
{"frontElement", GLO_FRONTELEMENT},
155
{"geometryPoint", GLO_GEOMETRYPOINT},
156
{"dottedContour", GLO_DOTTEDCONTOUR},
157
{"vehicleLabels", GLO_VEHICLELABELS},
158
{"temporalShape", GLO_TEMPORALSHAPE},
159
{"rectangleSelection", GLO_RECTANGLESELECTION},
160
{"testElement", GLO_TESTELEMENT},
161
//
162
{"undefined", GLO_MAX}
163
};
164
165
166
StringBijection<GUIGlObjectType> GUIGlObject::TypeNames(GUIGlObjectTypeNamesInitializer, GLO_MAX);
167
const GUIGlID GUIGlObject::INVALID_ID = 0;
168
const double GUIGlObject::INVALID_PRIORITY(-std::numeric_limits<double>::max());
169
170
171
// ===========================================================================
172
// method definitions
173
// ===========================================================================
174
#ifdef _MSC_VER
175
#pragma warning(push)
176
#pragma warning(disable: 4355) // mask warning about "this" in initializers
177
#endif
178
GUIGlObject::GUIGlObject(GUIGlObjectType type, const std::string& microsimID, FXIcon* icon) :
179
myGlID(GUIGlObjectStorage::gIDStorage.registerObject(this)),
180
myGLObjectType(type),
181
myMicrosimID(microsimID),
182
myIcon(icon) {
183
// make sure that reserved GLO_ADDITIONALELEMENT isn't used
184
assert(myGLObjectType != GLO_ADDITIONALELEMENT);
185
myFullName = createFullName();
186
GUIGlObjectStorage::gIDStorage.changeName(this, myFullName);
187
}
188
#ifdef _MSC_VER
189
#pragma warning(pop)
190
#endif
191
192
193
GUIGlObject::~GUIGlObject() {
194
// remove all paramWindow related with this object
195
for (const auto& paramWindow : myParamWindows) {
196
paramWindow->removeObject(this);
197
}
198
// remove object from GLObjectValuePassConnector and GUIGlObjectStorage
199
GLObjectValuePassConnector<double>::removeObject(*this);
200
GUIGlObjectStorage::gIDStorage.remove(getGlID());
201
}
202
203
204
std::string
205
GUIGlObject::getParentName() const {
206
return StringUtils::emptyString;
207
}
208
209
210
FXIcon*
211
GUIGlObject::getGLIcon() const {
212
return myIcon;
213
}
214
215
216
GUIParameterTableWindow*
217
GUIGlObject::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) {
218
UNUSED_PARAMETER(&app);
219
UNUSED_PARAMETER(&parent);
220
return nullptr;
221
}
222
223
224
bool
225
GUIGlObject::isGLObjectLocked() const {
226
// by default unlocked
227
return false;
228
}
229
230
231
void
232
GUIGlObject::markAsFrontElement() {
233
// by default nothing to do
234
}
235
236
237
void
238
GUIGlObject::deleteGLObject() {
239
// by default nothing to do
240
}
241
242
243
void
244
GUIGlObject::selectGLObject() {
245
// by default nothing to do
246
}
247
248
249
void
250
GUIGlObject::updateGLObject() {
251
// by default nothing to update
252
}
253
254
255
const std::string
256
GUIGlObject::getOptionalName() const {
257
return "";
258
}
259
260
261
void
262
GUIGlObject::setMicrosimID(const std::string& newID) {
263
myMicrosimID = newID;
264
GUIGlObjectStorage::gIDStorage.changeName(this, createFullName());
265
myFullName = createFullName();
266
}
267
268
269
void
270
GUIGlObject::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
271
UNUSED_PARAMETER(&s);
272
UNUSED_PARAMETER(parent);
273
}
274
275
#ifdef HAVE_OSG
276
277
osg::Node*
278
GUIGlObject::getNode() const {
279
return myOSGNode;
280
}
281
282
283
void
284
GUIGlObject::setNode(osg::Node* node) {
285
myOSGNode = node;
286
}
287
288
#endif
289
290
void
291
GUIGlObject::buildPopUpMenuCommonOptions(GUIGLObjectPopupMenu* ret, GUIMainWindow& app, GUISUMOAbstractView* parent,
292
const SumoXMLTag tag, const bool selected, bool addSeparator) {
293
// build header
294
buildPopupHeader(ret, app);
295
// build menu command for center button and copy cursor position to clipboard
296
buildCenterPopupEntry(ret);
297
// build menu commands for names
298
GUIDesigns::buildFXMenuCommand(ret, TLF("Copy % name to clipboard", toString(tag)), nullptr, ret, MID_COPY_NAME);
299
GUIDesigns::buildFXMenuCommand(ret, TLF("Copy % typed name to clipboard", toString(tag)), nullptr, ret, MID_COPY_TYPED_NAME);
300
new FXMenuSeparator(ret);
301
if (selected) {
302
GUIDesigns::buildFXMenuCommand(ret, TL("Remove from Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_MINUS), parent, MID_REMOVESELECT);
303
} else {
304
GUIDesigns::buildFXMenuCommand(ret, TL("Add to Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_PLUS), parent, MID_ADDSELECT);
305
}
306
new FXMenuSeparator(ret);
307
buildShowParamsPopupEntry(ret, true);
308
buildPositionCopyEntry(ret, app, addSeparator);
309
}
310
311
312
void
313
GUIGlObject::buildPopupHeader(GUIGLObjectPopupMenu* ret, GUIMainWindow& app, bool addSeparator) {
314
new MFXMenuHeader(ret, app.getBoldFont(), getFullName().c_str(), myIcon, nullptr, 0);
315
if (OptionsCont::getOptions().getBool("gui-testing")) {
316
GUIDesigns::buildFXMenuCommand(ret, TL("Copy test coordinates to clipboard"), nullptr, ret, MID_COPY_TEST_COORDINATES);
317
}
318
if (addSeparator) {
319
new FXMenuSeparator(ret);
320
}
321
}
322
323
324
void
325
GUIGlObject::buildCenterPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
326
GUIDesigns::buildFXMenuCommand(ret, TL("Center"), GUIIconSubSys::getIcon(GUIIcon::RECENTERVIEW), ret, MID_CENTER);
327
if (addSeparator) {
328
new FXMenuSeparator(ret);
329
}
330
}
331
332
333
void
334
GUIGlObject::buildNameCopyPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
335
GUIDesigns::buildFXMenuCommand(ret, TL("Copy name to clipboard"), nullptr, ret, MID_COPY_NAME);
336
GUIDesigns::buildFXMenuCommand(ret, TL("Copy typed name to clipboard"), nullptr, ret, MID_COPY_TYPED_NAME);
337
if (addSeparator) {
338
new FXMenuSeparator(ret);
339
}
340
}
341
342
343
void
344
GUIGlObject::buildSelectionPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
345
if (gSelected.isSelected(getType(), getGlID())) {
346
GUIDesigns::buildFXMenuCommand(ret, TL("Remove From Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_MINUS), ret, MID_REMOVESELECT);
347
} else {
348
GUIDesigns::buildFXMenuCommand(ret, TL("Add to Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_PLUS), ret, MID_ADDSELECT);
349
}
350
if (addSeparator) {
351
new FXMenuSeparator(ret);
352
}
353
}
354
355
356
void
357
GUIGlObject::buildShowParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
358
GUIDesigns::buildFXMenuCommand(ret, TL("Show Parameter"), GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWPARS);
359
if (addSeparator) {
360
new FXMenuSeparator(ret);
361
}
362
}
363
364
365
void
366
GUIGlObject::buildShowTypeParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
367
GUIDesigns::buildFXMenuCommand(ret, TL("Show Type Parameter"), GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWTYPEPARS);
368
if (addSeparator) {
369
new FXMenuSeparator(ret);
370
}
371
}
372
373
374
void
375
GUIGlObject::buildPositionCopyEntry(GUIGLObjectPopupMenu* ret, const GUIMainWindow& app, bool addSeparator) const {
376
GUIDesigns::buildFXMenuCommand(ret, TL("Copy cursor position to clipboard"), nullptr, ret, MID_COPY_CURSOR_POSITION);
377
if (GeoConvHelper::getFinal().usingGeoProjection()) {
378
GUIDesigns::buildFXMenuCommand(ret, TL("Copy cursor geo-position to clipboard"), nullptr, ret, MID_COPY_CURSOR_GEOPOSITION);
379
// create menu pane for edge operations
380
FXMenuPane* showCursorGeoPositionPane = new FXMenuPane(ret);
381
ret->insertMenuPaneChild(showCursorGeoPositionPane);
382
new FXMenuCascade(ret, TL("Show cursor geo-position in "), nullptr, showCursorGeoPositionPane);
383
for (const auto& mapper : app.getOnlineMaps()) {
384
if (mapper.first == "GeoHack") {
385
GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::GEOHACK), ret, MID_SHOW_GEOPOSITION_ONLINE);
386
} else if (mapper.first == "Google Maps") {
387
GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::GOOGLEMAPS), ret, MID_SHOW_GEOPOSITION_ONLINE);
388
} else if (mapper.first == "OSM") {
389
GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::OSM), ret, MID_SHOW_GEOPOSITION_ONLINE);
390
} else {
391
GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, nullptr, ret, MID_SHOW_GEOPOSITION_ONLINE);
392
}
393
}
394
}
395
if (addSeparator) {
396
new FXMenuSeparator(ret);
397
}
398
}
399
400
401
void
402
GUIGlObject::buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
403
GUIDesigns::buildFXMenuCommand(ret, TL("Open Manipulator..."), GUIIconSubSys::getIcon(GUIIcon::MANIP), ret, MID_MANIP);
404
if (addSeparator) {
405
new FXMenuSeparator(ret);
406
}
407
}
408
409
410
void
411
GUIGlObject::addParameterTable(GUIParameterTableWindow* t) {
412
myParamWindows.insert(t);
413
}
414
415
416
void
417
GUIGlObject::removeParameterTable(GUIParameterTableWindow* t) {
418
std::set<GUIParameterTableWindow*>::iterator i = myParamWindows.find(t);
419
if (i != myParamWindows.end()) {
420
myParamWindows.erase(i);
421
}
422
}
423
424
425
void
426
GUIGlObject::buildShapePopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
427
assert(ret);
428
// build header (<tag>:<ID>
429
buildPopupHeader(ret, app, false);
430
// build center
431
buildCenterPopupEntry(ret);
432
// build copy name
433
buildNameCopyPopupEntry(ret);
434
// build select/unselect
435
buildSelectionPopupEntry(ret);
436
// build show parameters
437
buildShowParamsPopupEntry(ret, false);
438
// build copy cursor position to clipboard
439
buildPositionCopyEntry(ret, app);
440
// only show type if isn't empty
441
if (type != "") {
442
GUIDesigns::buildFXMenuCommand(ret, TLF("type: %", type).c_str(), nullptr, nullptr, 0);
443
new FXMenuSeparator(ret);
444
}
445
}
446
447
448
void
449
GUIGlObject::buildAdditionalsPopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
450
assert(ret);
451
// build header (<tag>:<ID>
452
buildPopupHeader(ret, app, false);
453
// build center
454
buildCenterPopupEntry(ret);
455
// build copy name
456
buildNameCopyPopupEntry(ret);
457
// build select/unselect
458
buildSelectionPopupEntry(ret);
459
// build show parameters
460
buildShowParamsPopupEntry(ret, false);
461
// build copy cursor position to clipboard
462
buildPositionCopyEntry(ret, app);
463
// only show type if isn't empty
464
if (type != "") {
465
GUIDesigns::buildFXMenuCommand(ret, TLF("type: %", type).c_str(), nullptr, nullptr, 0);
466
new FXMenuSeparator(ret);
467
}
468
}
469
470
471
std::string
472
GUIGlObject::createFullName() const {
473
return TypeNames.getString(myGLObjectType) + ":" + getMicrosimID();
474
}
475
476
477
void
478
GUIGlObject::drawName(const Position& pos, const double scale, const GUIVisualizationTextSettings& settings, const double angle, bool forceShow) const {
479
if (settings.show(this) || forceShow) {
480
GLHelper::drawTextSettings(settings, getMicrosimID(), pos, scale, angle);
481
}
482
}
483
484
485
/****************************************************************************/
486
487