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