Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 :
44 : #include "GUIGlObject.h"
45 : #include "GUIGlObjectStorage.h"
46 :
47 : // ===========================================================================
48 : // static members
49 : // ===========================================================================
50 :
51 : StringBijection<GUIGlObjectType>::Entry GUIGlObject::GUIGlObjectTypeNamesInitializer[] = {
52 : {"network", GLO_NETWORK},
53 : //
54 : {"networkElement", GLO_NETWORKELEMENT},
55 : {"edge", GLO_EDGE},
56 : {"lane", GLO_LANE},
57 : {"junction", GLO_JUNCTION},
58 : {"connection", GLO_CONNECTION},
59 : {"crossing", GLO_CROSSING},
60 : {"walkingArea", GLO_WALKINGAREA},
61 : {"tlLogic", GLO_TLLOGIC},
62 : {"edgeType", GLO_EDGETYPE},
63 : {"laneType", GLO_LANETYPE},
64 : //
65 : {"parentChildLine", GLO_PARENTCHILDLINE},
66 : //
67 : {"additional", GLO_ADDITIONALELEMENT},
68 : {"busStop", GLO_BUS_STOP},
69 : {"access", GLO_ACCESS},
70 : {"taz", GLO_TAZ},
71 : {"containerStop", GLO_CONTAINER_STOP},
72 : {"chargingStation", GLO_CHARGING_STATION},
73 : {"overheadWireSegment", GLO_OVERHEAD_WIRE_SEGMENT},
74 : {"parkingArea", GLO_PARKING_AREA},
75 : {"parkingSpace", GLO_PARKING_SPACE},
76 : {"e1Detector", GLO_E1DETECTOR},
77 : {"e1DetectorME", GLO_E1DETECTOR_ME},
78 : {"e1DetectorInstant", GLO_E1DETECTOR_INSTANT},
79 : {"e2Detector", GLO_E2DETECTOR},
80 : {"e3Detector", GLO_E3DETECTOR},
81 : {"entryDetector", GLO_DET_ENTRY},
82 : {"exitDetector", GLO_DET_EXIT},
83 : {"rerouter", GLO_REROUTER},
84 : {"rerouterInterval", GLO_REROUTER_INTERVAL},
85 : {"closingreroute", GLO_REROUTER_CLOSINGREROUTE},
86 : {"closingLaneReroute", GLO_REROUTER_CLOSINGLANEREROUTE},
87 : {"parkingAreaReroute", GLO_REROUTER_PARKINGAREAREROUTE},
88 : {"destProbReroute", GLO_REROUTER_DESTPROBREROUTE},
89 : {"routeProbReroute", GLO_REROUTER_ROUTEPROBREROUTE},
90 : {"rerouterEdge", GLO_REROUTER_EDGE},
91 : {"variableSpeedSign", GLO_VSS},
92 : {"variableSpeedSignStep", GLO_VSS_STEP},
93 : {"calibrator", GLO_CALIBRATOR},
94 : {"routeProbe", GLO_ROUTEPROBE},
95 : {"vaporizer", GLO_VAPORIZER},
96 : {"wire", GLO_WIRE},
97 : {"tractionsubstation", GLO_TRACTIONSUBSTATION},
98 : //
99 : {"laneArrows", GLO_LANEARROWS},
100 : //
101 : {"shape", GLO_SHAPE},
102 : {"polygon", GLO_POLYGON},
103 : {"poi", GLO_POI},
104 : //
105 : {"jupedsim.walkable_area", GLO_JPS_WALKABLEAREA},
106 : {"jupedsim.obstacle", GLO_JPS_OBSTACLE},
107 : //
108 : {"routeElement", GLO_ROUTEELEMENT},
109 : {"vType", GLO_VTYPE},
110 : //
111 : {"route", GLO_ROUTE},
112 : //
113 : {"ride", GLO_RIDE},
114 : {"walk", GLO_WALK},
115 : {"personTrip", GLO_PERSONTRIP},
116 : {"transport", GLO_TRANSPORT},
117 : {"tranship", GLO_TRANSHIP},
118 : //
119 : {"stop", GLO_STOP},
120 : {"stopPlan", GLO_STOP_PLAN},
121 : //
122 : {"vehicle", GLO_VEHICLE},
123 : {"trip", GLO_TRIP},
124 : {"flow", GLO_FLOW},
125 : {"routeFlow", GLO_ROUTEFLOW},
126 : //
127 : {"container", GLO_CONTAINER},
128 : {"containerFlow", GLO_CONTAINERFLOW},
129 : //
130 : {"person", GLO_PERSON},
131 : {"personFlow", GLO_PERSONFLOW},
132 : //
133 : {"edgeData", GLO_EDGEDATA},
134 : {"edgeRelData", GLO_EDGERELDATA},
135 : {"TAZRelData", GLO_TAZRELDATA},
136 : //
137 : {"lockIcon", GLO_LOCKICON},
138 : {"textName", GLO_TEXTNAME},
139 : {"frontElement", GLO_FRONTELEMENT},
140 : {"geometryPoint", GLO_GEOMETRYPOINT},
141 : {"dottedContour", GLO_DOTTEDCONTOUR},
142 : {"temporalShape", GLO_TEMPORALSHAPE},
143 : {"rectangleSelection", GLO_RECTANGLESELECTION},
144 : {"testElement", GLO_TESTELEMENT},
145 : //
146 : {"undefined", GLO_MAX}
147 : };
148 :
149 :
150 : StringBijection<GUIGlObjectType> GUIGlObject::TypeNames(GUIGlObjectTypeNamesInitializer, GLO_MAX);
151 : const GUIGlID GUIGlObject::INVALID_ID = 0;
152 : const double GUIGlObject::INVALID_PRIORITY(-std::numeric_limits<double>::max());
153 :
154 : // ===========================================================================
155 : // method definitions
156 : // ===========================================================================
157 :
158 1447564 : GUIGlObject::GUIGlObject(GUIGlObjectType type, const std::string& microsimID, FXIcon* icon) :
159 2895128 : myGlID(GUIGlObjectStorage::gIDStorage.registerObject(this)),
160 1447564 : myGLObjectType(type),
161 1447564 : myMicrosimID(microsimID),
162 2895128 : myIcon(icon) {
163 : // make sure that reserved GLO_ADDITIONALELEMENT isn't used
164 : assert(myGLObjectType != GLO_ADDITIONALELEMENT);
165 1447564 : myFullName = createFullName();
166 1447564 : GUIGlObjectStorage::gIDStorage.changeName(this, myFullName);
167 1447564 : }
168 :
169 :
170 1445987 : GUIGlObject::~GUIGlObject() {
171 : // remove all paramWindow related with this object
172 1445987 : for (const auto& paramWindow : myParamWindows) {
173 0 : paramWindow->removeObject(this);
174 : }
175 : // remove object from GLObjectValuePassConnector and GUIGlObjectStorage
176 1445987 : GLObjectValuePassConnector<double>::removeObject(*this);
177 1445987 : GUIGlObjectStorage::gIDStorage.remove(getGlID());
178 1445987 : }
179 :
180 :
181 : std::string
182 0 : GUIGlObject::getParentName() const {
183 0 : return StringUtils::emptyString;
184 : }
185 :
186 :
187 : FXIcon*
188 0 : GUIGlObject::getGLIcon() const {
189 0 : return myIcon;
190 : }
191 :
192 :
193 : GUIParameterTableWindow*
194 0 : GUIGlObject::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) {
195 : UNUSED_PARAMETER(&app);
196 : UNUSED_PARAMETER(&parent);
197 0 : return nullptr;
198 : }
199 :
200 :
201 : bool
202 0 : GUIGlObject::isGLObjectLocked() const {
203 : // by default unlocked
204 0 : return false;
205 : }
206 :
207 :
208 : void
209 0 : GUIGlObject::markAsFrontElement() {
210 : // by default nothing to do
211 0 : }
212 :
213 :
214 : void
215 0 : GUIGlObject::deleteGLObject() {
216 : // by default nothing to do
217 0 : }
218 :
219 :
220 : void
221 0 : GUIGlObject::selectGLObject() {
222 : // by default nothing to do
223 0 : }
224 :
225 :
226 : void
227 0 : GUIGlObject::updateGLObject() {
228 : // by default nothing to update
229 0 : }
230 :
231 :
232 : const std::string
233 0 : GUIGlObject::getOptionalName() const {
234 0 : return "";
235 : }
236 :
237 :
238 : void
239 0 : GUIGlObject::setMicrosimID(const std::string& newID) {
240 0 : myMicrosimID = newID;
241 0 : GUIGlObjectStorage::gIDStorage.changeName(this, createFullName());
242 0 : myFullName = createFullName();
243 0 : }
244 :
245 :
246 : void
247 0 : GUIGlObject::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
248 : UNUSED_PARAMETER(&s);
249 : UNUSED_PARAMETER(parent);
250 0 : }
251 :
252 : #ifdef HAVE_OSG
253 :
254 : osg::Node*
255 0 : GUIGlObject::getNode() const {
256 0 : return myOSGNode;
257 : }
258 :
259 :
260 : void
261 36515 : GUIGlObject::setNode(osg::Node* node) {
262 36515 : myOSGNode = node;
263 36515 : }
264 :
265 : #endif
266 :
267 : void
268 0 : GUIGlObject::buildPopupHeader(GUIGLObjectPopupMenu* ret, GUIMainWindow& app, bool addSeparator) {
269 0 : new MFXMenuHeader(ret, app.getBoldFont(), getFullName().c_str(), myIcon, nullptr, 0);
270 0 : if (addSeparator) {
271 0 : new FXMenuSeparator(ret);
272 : }
273 0 : }
274 :
275 :
276 : void
277 0 : GUIGlObject::buildCenterPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
278 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Center"), GUIIconSubSys::getIcon(GUIIcon::RECENTERVIEW), ret, MID_CENTER);
279 0 : if (addSeparator) {
280 0 : new FXMenuSeparator(ret);
281 : }
282 0 : }
283 :
284 :
285 : void
286 0 : GUIGlObject::buildNameCopyPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
287 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Copy name to clipboard"), nullptr, ret, MID_COPY_NAME);
288 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Copy typed name to clipboard"), nullptr, ret, MID_COPY_TYPED_NAME);
289 0 : if (addSeparator) {
290 0 : new FXMenuSeparator(ret);
291 : }
292 0 : }
293 :
294 :
295 : void
296 0 : GUIGlObject::buildSelectionPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
297 0 : if (gSelected.isSelected(getType(), getGlID())) {
298 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Remove From Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_MINUS), ret, MID_REMOVESELECT);
299 : } else {
300 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Add to Selected"), GUIIconSubSys::getIcon(GUIIcon::FLAG_PLUS), ret, MID_ADDSELECT);
301 : }
302 0 : if (addSeparator) {
303 0 : new FXMenuSeparator(ret);
304 : }
305 0 : }
306 :
307 :
308 : void
309 0 : GUIGlObject::buildShowParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
310 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Show Parameter"), GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWPARS);
311 0 : if (addSeparator) {
312 0 : new FXMenuSeparator(ret);
313 : }
314 0 : }
315 :
316 :
317 : void
318 0 : GUIGlObject::buildShowTypeParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
319 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Show Type Parameter"), GUIIconSubSys::getIcon(GUIIcon::APP_TABLE), ret, MID_SHOWTYPEPARS);
320 0 : if (addSeparator) {
321 0 : new FXMenuSeparator(ret);
322 : }
323 0 : }
324 :
325 :
326 : void
327 0 : GUIGlObject::buildPositionCopyEntry(GUIGLObjectPopupMenu* ret, const GUIMainWindow& app) const {
328 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Copy cursor position to clipboard"), nullptr, ret, MID_COPY_CURSOR_POSITION);
329 0 : if (GeoConvHelper::getFinal().usingGeoProjection()) {
330 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Copy cursor geo-position to clipboard"), nullptr, ret, MID_COPY_CURSOR_GEOPOSITION);
331 : // create menu pane for edge operations
332 0 : FXMenuPane* showCursorGeoPositionPane = new FXMenuPane(ret);
333 0 : ret->insertMenuPaneChild(showCursorGeoPositionPane);
334 0 : new FXMenuCascade(ret, TL("Show cursor geo-position in "), nullptr, showCursorGeoPositionPane);
335 0 : for (const auto& mapper : app.getOnlineMaps()) {
336 0 : if (mapper.first == "GeoHack") {
337 0 : GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::GEOHACK), ret, MID_SHOW_GEOPOSITION_ONLINE);
338 0 : } else if (mapper.first == "Google Maps") {
339 0 : GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::GOOGLEMAPS), ret, MID_SHOW_GEOPOSITION_ONLINE);
340 0 : } else if (mapper.first == "OSM") {
341 0 : GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, GUIIconSubSys::getIcon(GUIIcon::OSM), ret, MID_SHOW_GEOPOSITION_ONLINE);
342 : } else {
343 0 : GUIDesigns::buildFXMenuCommand(showCursorGeoPositionPane, mapper.first, nullptr, ret, MID_SHOW_GEOPOSITION_ONLINE);
344 : }
345 : }
346 : }
347 0 : }
348 :
349 :
350 : void
351 0 : GUIGlObject::buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
352 0 : GUIDesigns::buildFXMenuCommand(ret, TL("Open Manipulator..."), GUIIconSubSys::getIcon(GUIIcon::MANIP), ret, MID_MANIP);
353 0 : if (addSeparator) {
354 0 : new FXMenuSeparator(ret);
355 : }
356 0 : }
357 :
358 :
359 : void
360 0 : GUIGlObject::addParameterTable(GUIParameterTableWindow* t) {
361 : myParamWindows.insert(t);
362 0 : }
363 :
364 :
365 : void
366 0 : GUIGlObject::removeParameterTable(GUIParameterTableWindow* t) {
367 : std::set<GUIParameterTableWindow*>::iterator i = myParamWindows.find(t);
368 0 : if (i != myParamWindows.end()) {
369 : myParamWindows.erase(i);
370 : }
371 0 : }
372 :
373 :
374 : void
375 0 : GUIGlObject::buildShapePopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
376 : assert(ret);
377 : // build header (<tag>:<ID>
378 0 : buildPopupHeader(ret, app, false);
379 : // build center
380 0 : buildCenterPopupEntry(ret);
381 : // build copy name
382 0 : buildNameCopyPopupEntry(ret);
383 : // build select/unselect
384 0 : buildSelectionPopupEntry(ret);
385 : // build show parameters
386 0 : buildShowParamsPopupEntry(ret, false);
387 : // build copy cursor position to clipboard
388 0 : buildPositionCopyEntry(ret, app);
389 : // only show type if isn't empty
390 0 : if (type != "") {
391 0 : GUIDesigns::buildFXMenuCommand(ret, TLF("type: %", type).c_str(), nullptr, nullptr, 0);
392 0 : new FXMenuSeparator(ret);
393 : }
394 0 : }
395 :
396 :
397 : void
398 0 : GUIGlObject::buildAdditionalsPopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
399 : assert(ret);
400 : // build header (<tag>:<ID>
401 0 : buildPopupHeader(ret, app, false);
402 : // build center
403 0 : buildCenterPopupEntry(ret);
404 : // build copy name
405 0 : buildNameCopyPopupEntry(ret);
406 : // build select/unselect
407 0 : buildSelectionPopupEntry(ret);
408 : // build show parameters
409 0 : buildShowParamsPopupEntry(ret, false);
410 : // build copy cursor position to clipboard
411 0 : buildPositionCopyEntry(ret, app);
412 : // only show type if isn't empty
413 0 : if (type != "") {
414 0 : GUIDesigns::buildFXMenuCommand(ret, TLF("type: %", type).c_str(), nullptr, nullptr, 0);
415 0 : new FXMenuSeparator(ret);
416 : }
417 0 : }
418 :
419 :
420 : std::string
421 1447564 : GUIGlObject::createFullName() const {
422 2895128 : return TypeNames.getString(myGLObjectType) + ":" + getMicrosimID();
423 : }
424 :
425 :
426 : void
427 16119225 : GUIGlObject::drawName(const Position& pos, const double scale, const GUIVisualizationTextSettings& settings, const double angle, bool forceShow) const {
428 16119225 : if (settings.show(this) || forceShow) {
429 0 : GLHelper::drawTextSettings(settings, getMicrosimID(), pos, scale, angle);
430 : }
431 16119225 : }
432 :
433 :
434 : /****************************************************************************/
|