1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file GUIGlObject.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Michael Behrisch
14 /// @author Laura Bieker
15 /// @date Sept 2002
16 /// @version $Id$
17 ///
18 // Base class for all objects that may be displayed within the openGL-gui
19 /****************************************************************************/
20
21
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26
27 #include <string>
28 #include <stack>
29 #include <utils/common/ToString.h>
30 #include <utils/geom/GeoConvHelper.h>
31 #include <utils/gui/windows/GUISUMOAbstractView.h>
32 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
33 #include <utils/gui/div/GUIParameterTableWindow.h>
34 #include <utils/foxtools/MFXMenuHeader.h>
35 #include <utils/gui/images/GUIIconSubSys.h>
36 #include <utils/gui/windows/GUIAppEnum.h>
37 #include <utils/gui/windows/GUIMainWindow.h>
38 #include <utils/gui/div/GUIGlobalSelection.h>
39 #include <utils/gui/div/GLHelper.h>
40 #include <utils/gui/div/GLObjectValuePassConnector.h>
41 #include "GUIGlObject.h"
42 #include "GUIGlObjectStorage.h"
43
44 // ===========================================================================
45 // static members
46 // ===========================================================================
47
48 StringBijection<GUIGlObjectType>::Entry GUIGlObject::GUIGlObjectTypeNamesInitializer[] = {
49 {"network", GLO_NETWORK},
50 {"netElement", GLO_NETELEMENT},
51 {"edge", GLO_EDGE},
52 {"lane", GLO_LANE},
53 {"junction", GLO_JUNCTION},
54 {"crossing", GLO_CROSSING},
55 {"connection", GLO_CONNECTION},
56 {"tlLogic", GLO_TLLOGIC},
57 {"additional", GLO_ADDITIONAL},
58 {"busStop", GLO_BUS_STOP},
59 {"access", GLO_ACCESS},
60 {"taz", GLO_TAZ},
61 {"containerStop", GLO_CONTAINER_STOP},
62 {"chargingStation", GLO_CHARGING_STATION},
63 {"parkingArea", GLO_PARKING_AREA},
64 {"parkingSpace", GLO_PARKING_SPACE},
65 {"e1Detector", GLO_E1DETECTOR},
66 {"e1DetectorME", GLO_E1DETECTOR_ME},
67 {"e1DetectorInstant", GLO_E1DETECTOR_INSTANT},
68 {"e2Detector", GLO_E2DETECTOR},
69 {"e3Detector", GLO_E3DETECTOR},
70 {"entryDetector", GLO_DET_ENTRY},
71 {"exitDetector", GLO_DET_EXIT},
72 {"rerouter", GLO_REROUTER},
73 {"rerouterEdge", GLO_REROUTER_EDGE},
74 {"variableSpeedSign", GLO_VSS},
75 {"calibrator", GLO_CALIBRATOR},
76 {"routeProbe", GLO_ROUTEPROBE},
77 {"vaporizer", GLO_VAPORIZER},
78 {"shape", GLO_SHAPE},
79 {"polygon", GLO_POLYGON},
80 {"poi", GLO_POI},
81 {"routeElement", GLO_ROUTEELEMENT},
82 {"route", GLO_ROUTE},
83 {"vehicle", GLO_VEHICLE},
84 {"vType", GLO_VTYPE},
85 {"flow", GLO_FLOW},
86 {"trip", GLO_TRIP},
87 {"person", GLO_PERSON},
88 {"container", GLO_CONTAINER},
89 {"stop", GLO_STOP},
90 {"undefined", GLO_MAX}
91 };
92
93
94 StringBijection<GUIGlObjectType> GUIGlObject::TypeNames(GUIGlObjectTypeNamesInitializer, GLO_MAX);
95 const GUIGlID GUIGlObject::INVALID_ID = 0;
96
97 // ===========================================================================
98 // method definitionsas
99 // ===========================================================================
100
GUIGlObject(GUIGlObjectType type,const std::string & microsimID)101 GUIGlObject::GUIGlObject(GUIGlObjectType type, const std::string& microsimID) :
102 myGLObjectType(type),
103 myMicrosimID(microsimID) {
104 // make sure that reserved GLO_ADDITIONAL isn't used
105 assert(myGLObjectType != GLO_ADDITIONAL);
106 myFullName = createFullName();
107 myGlID = GUIGlObjectStorage::gIDStorage.registerObject(this, myFullName);
108 }
109
110
~GUIGlObject()111 GUIGlObject::~GUIGlObject() {
112 for (auto i : myParamWindows) {
113 i->removeObject(this);
114 }
115 GLObjectValuePassConnector<double>::removeObject(*this);
116 GUIGlObjectStorage::gIDStorage.remove(getGlID());
117 }
118
119
120 const std::string&
getFullName() const121 GUIGlObject::getFullName() const {
122 return myFullName;
123 }
124
125
126 std::string
getParentName() const127 GUIGlObject::getParentName() const {
128 return StringUtils::emptyString;
129 }
130
131
132 GUIGlID
getGlID() const133 GUIGlObject::getGlID() const {
134 return myGlID;
135 }
136
137
138 GUIParameterTableWindow*
getTypeParameterWindow(GUIMainWindow & app,GUISUMOAbstractView & parent)139 GUIGlObject::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) {
140 UNUSED_PARAMETER(&app);
141 UNUSED_PARAMETER(&parent);
142 return nullptr;
143 }
144
145
146 const std::string&
getMicrosimID() const147 GUIGlObject::getMicrosimID() const {
148 return myMicrosimID;
149 }
150
151 const std::string
getOptionalName() const152 GUIGlObject::getOptionalName() const {
153 return "";
154 }
155
156 void
setMicrosimID(const std::string & newID)157 GUIGlObject::setMicrosimID(const std::string& newID) {
158 myMicrosimID = newID;
159 myFullName = createFullName();
160 }
161
162
163 GUIGlObjectType
getType() const164 GUIGlObject::getType() const {
165 return myGLObjectType;
166 }
167
168
169 void
drawGLAdditional(GUISUMOAbstractView * const parent,const GUIVisualizationSettings & s) const170 GUIGlObject::drawGLAdditional(GUISUMOAbstractView* const parent, const GUIVisualizationSettings& s) const {
171 UNUSED_PARAMETER(&s);
172 UNUSED_PARAMETER(parent);
173 }
174
175 #ifdef HAVE_OSG
176
177 osg::Node*
getNode() const178 GUIGlObject::getNode() const {
179 return myOSGNode;
180 }
181
182
183 void
setNode(osg::Node * node)184 GUIGlObject::setNode(osg::Node* node) {
185 myOSGNode = node;
186 }
187
188 #endif
189
190 void
buildPopupHeader(GUIGLObjectPopupMenu * ret,GUIMainWindow & app,bool addSeparator)191 GUIGlObject::buildPopupHeader(GUIGLObjectPopupMenu* ret, GUIMainWindow& app, bool addSeparator) {
192 new MFXMenuHeader(ret, app.getBoldFont(), getFullName().c_str(), nullptr, nullptr, 0);
193 if (addSeparator) {
194 new FXMenuSeparator(ret);
195 }
196 }
197
198
199 void
buildCenterPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)200 GUIGlObject::buildCenterPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
201 new FXMenuCommand(ret, "Center", GUIIconSubSys::getIcon(ICON_RECENTERVIEW), ret, MID_CENTER);
202 if (addSeparator) {
203 new FXMenuSeparator(ret);
204 }
205 }
206
207
208 void
buildNameCopyPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)209 GUIGlObject::buildNameCopyPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
210 new FXMenuCommand(ret, "Copy name to clipboard", nullptr, ret, MID_COPY_NAME);
211 new FXMenuCommand(ret, "Copy typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
212 if (addSeparator) {
213 new FXMenuSeparator(ret);
214 }
215 }
216
217
218 void
buildSelectionPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)219 GUIGlObject::buildSelectionPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
220 if (gSelected.isSelected(getType(), getGlID())) {
221 new FXMenuCommand(ret, "Remove From Selected", GUIIconSubSys::getIcon(ICON_FLAG_MINUS), ret, MID_REMOVESELECT);
222 } else {
223 new FXMenuCommand(ret, "Add To Selected", GUIIconSubSys::getIcon(ICON_FLAG_PLUS), ret, MID_ADDSELECT);
224 }
225 if (addSeparator) {
226 new FXMenuSeparator(ret);
227 }
228 }
229
230
231 void
buildShowParamsPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)232 GUIGlObject::buildShowParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
233 new FXMenuCommand(ret, "Show Parameter", GUIIconSubSys::getIcon(ICON_APP_TABLE), ret, MID_SHOWPARS);
234 if (addSeparator) {
235 new FXMenuSeparator(ret);
236 }
237 }
238
239
240 void
buildShowTypeParamsPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)241 GUIGlObject::buildShowTypeParamsPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
242 new FXMenuCommand(ret, "Show Type Parameter", GUIIconSubSys::getIcon(ICON_APP_TABLE), ret, MID_SHOWTYPEPARS);
243 if (addSeparator) {
244 new FXMenuSeparator(ret);
245 }
246 }
247
248
249 void
buildPositionCopyEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)250 GUIGlObject::buildPositionCopyEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
251 new FXMenuCommand(ret, "Copy cursor position to clipboard", nullptr, ret, MID_COPY_CURSOR_POSITION);
252 if (GeoConvHelper::getFinal().usingGeoProjection()) {
253 new FXMenuCommand(ret, "Copy cursor geo-position to clipboard", nullptr, ret, MID_COPY_CURSOR_GEOPOSITION);
254 }
255 if (addSeparator) {
256 new FXMenuSeparator(ret);
257 }
258 }
259
260
261 void
buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu * ret,bool addSeparator)262 GUIGlObject::buildShowManipulatorPopupEntry(GUIGLObjectPopupMenu* ret, bool addSeparator) {
263 new FXMenuCommand(ret, "Open Manipulator...", GUIIconSubSys::getIcon(ICON_MANIP), ret, MID_MANIP);
264 if (addSeparator) {
265 new FXMenuSeparator(ret);
266 }
267 }
268
269
270 void
addParameterTable(GUIParameterTableWindow * t)271 GUIGlObject::addParameterTable(GUIParameterTableWindow* t) {
272 myParamWindows.insert(t);
273 }
274
275
276 void
removeParameterTable(GUIParameterTableWindow * t)277 GUIGlObject::removeParameterTable(GUIParameterTableWindow* t) {
278 std::set<GUIParameterTableWindow*>::iterator i = myParamWindows.find(t);
279 if (i != myParamWindows.end()) {
280 myParamWindows.erase(i);
281 }
282 }
283
284
285 void
buildShapePopupOptions(GUIMainWindow & app,GUIGLObjectPopupMenu * ret,const std::string & type)286 GUIGlObject::buildShapePopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
287 assert(ret);
288 // build header (<tag>:<ID>
289 buildPopupHeader(ret, app, false);
290 // build center
291 buildCenterPopupEntry(ret);
292 // build copy name
293 buildNameCopyPopupEntry(ret);
294 // build select/unselect
295 buildSelectionPopupEntry(ret);
296 // build show parameters
297 buildShowParamsPopupEntry(ret, false);
298 // build copy cursor position to clipboard
299 buildPositionCopyEntry(ret, false);
300 // only show type if isn't empty
301 if (type != "") {
302 new FXMenuCommand(ret, ("type: " + type + "").c_str(), nullptr, nullptr, 0);
303 new FXMenuSeparator(ret);
304 }
305 }
306
307
308 void
buildAdditionalsPopupOptions(GUIMainWindow & app,GUIGLObjectPopupMenu * ret,const std::string & type)309 GUIGlObject::buildAdditionalsPopupOptions(GUIMainWindow& app, GUIGLObjectPopupMenu* ret, const std::string& type) {
310 assert(ret);
311 // build header (<tag>:<ID>
312 buildPopupHeader(ret, app, false);
313 // build center
314 buildCenterPopupEntry(ret);
315 // build copy name
316 buildNameCopyPopupEntry(ret);
317 // build select/unselect
318 buildSelectionPopupEntry(ret);
319 // build show parameters
320 buildShowParamsPopupEntry(ret, false);
321 // build copy cursor position to clipboard
322 buildPositionCopyEntry(ret, false);
323 // only show type if isn't empty
324 if (type != "") {
325 new FXMenuCommand(ret, ("type: " + type + "").c_str(), nullptr, nullptr, 0);
326 new FXMenuSeparator(ret);
327 }
328 }
329
330
331 std::string
createFullName() const332 GUIGlObject::createFullName() const {
333 return TypeNames.getString(myGLObjectType) + ":" + getMicrosimID();
334 }
335
336
337 void
drawName(const Position & pos,const double scale,const GUIVisualizationTextSettings & settings,const double angle) const338 GUIGlObject::drawName(const Position& pos, const double scale, const GUIVisualizationTextSettings& settings, const double angle) const {
339 if (settings.show) {
340 GLHelper::drawTextSettings(settings, getMicrosimID(), pos, scale, angle);
341 }
342 }
343
344 /****************************************************************************/
345
346