Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/frames/GNEDemandSelector.cpp
193905 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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 GNEDemandSelector.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Mar 2022
17
///
18
// Frame for select demand elements
19
/****************************************************************************/
20
21
#include <netedit/frames/common/GNEInspectorFrame.h>
22
#include <netedit/GNEApplicationWindow.h>
23
#include <netedit/GNENet.h>
24
#include <netedit/GNETagPropertiesDatabase.h>
25
#include <netedit/GNEViewNet.h>
26
#include <netedit/GNEViewParent.h>
27
#include <utils/gui/div/GUIDesigns.h>
28
#include <utils/gui/windows/GUIAppEnum.h>
29
30
#include "GNEDemandSelector.h"
31
32
// ===========================================================================
33
// FOX callback mapping
34
// ===========================================================================
35
36
FXDEFMAP(GNEDemandElementSelector) DemandElementSelectorMap[] = {
37
FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_TYPE, GNEDemandElementSelector::onCmdSelectDemandElement),
38
};
39
40
// Object implementation
41
FXIMPLEMENT(GNEDemandElementSelector, GNEGroupBoxModule, DemandElementSelectorMap, ARRAYNUMBER(DemandElementSelectorMap))
42
43
44
// ===========================================================================
45
// method definitions
46
// ===========================================================================
47
48
GNEDemandElementSelector::GNEDemandElementSelector(GNEFrame* frameParent, SumoXMLTag demandElementTag, const GNETagProperties::Type tagType) :
49
GNEGroupBoxModule(frameParent, TLF("Parent %", toString(demandElementTag)).c_str()),
50
myFrameParent(frameParent),
51
myCurrentDemandElement(nullptr),
52
myDemandElementTags({demandElementTag}),
53
myTagType(tagType),
54
mySelectingMultipleElements(false) {
55
// Create MFXComboBoxIcon
56
myDemandElementsComboBox = new MFXComboBoxIcon(getCollapsableFrame(), frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
57
true, GUIDesignComboBoxVisibleItems, this, MID_GNE_SET_TYPE, GUIDesignComboBox);
58
// refresh demand element MatchBox
59
refreshDemandElementSelector();
60
// shown after creation
61
show();
62
}
63
64
65
GNEDemandElementSelector::GNEDemandElementSelector(GNEFrame* frameParent, const std::vector<GNETagProperties::Type> tagTypes,
66
const std::vector<SumoXMLTag> exceptions) :
67
GNEGroupBoxModule(frameParent, TL("Parent element")),
68
myFrameParent(frameParent),
69
myCurrentDemandElement(nullptr),
70
myTagType(GNETagProperties::Type::OTHER),
71
mySelectingMultipleElements(false) {
72
// fill myDemandElementTags
73
for (const auto& tagType : tagTypes) {
74
const auto tagPropertiesByType = frameParent->getViewNet()->getNet()->getTagPropertiesDatabase()->getTagPropertiesByType(tagType);
75
for (const auto tagProperty : tagPropertiesByType) {
76
if (std::find(exceptions.begin(), exceptions.end(), tagProperty->getTag()) == exceptions.end()) {
77
myDemandElementTags.push_back(tagProperty->getTag());
78
}
79
}
80
}
81
// Create MFXComboBoxIcon
82
myDemandElementsComboBox = new MFXComboBoxIcon(getCollapsableFrame(), frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
83
true, GUIDesignComboBoxVisibleItems, this, MID_GNE_SET_TYPE, GUIDesignComboBox);
84
// refresh demand element MatchBox
85
refreshDemandElementSelector();
86
// shown after creation
87
show();
88
}
89
90
91
GNEDemandElementSelector::~GNEDemandElementSelector() {}
92
93
94
GNEDemandElement*
95
GNEDemandElementSelector::getCurrentDemandElement() const {
96
return myCurrentDemandElement;
97
}
98
99
100
const std::vector<SumoXMLTag>&
101
GNEDemandElementSelector::getAllowedTags() const {
102
return myDemandElementTags;
103
}
104
105
106
void
107
GNEDemandElementSelector::setDemandElement(GNEDemandElement* demandElement) {
108
mySelectingMultipleElements = false;
109
// Set new current demand element
110
myCurrentDemandElement = demandElement;
111
if (demandElement != nullptr) {
112
// check that demandElement tag correspond to a tag of myDemandElementTags
113
if (std::find(myDemandElementTags.begin(), myDemandElementTags.end(), demandElement->getTagProperty()->getTag()) != myDemandElementTags.end()) {
114
// update text of myDemandElementsComboBox
115
myDemandElementsComboBox->setCurrentItem(demandElement->getID().c_str());
116
}
117
}
118
// call demandElementSelected function
119
myFrameParent->demandElementSelected();
120
}
121
122
123
void
124
GNEDemandElementSelector::setDemandElements(const std::vector<GNEDemandElement*>& demandElements) {
125
mySelectingMultipleElements = true;
126
myCurrentDemandElement = nullptr;
127
myDemandElementsComboBox->clearItems();
128
for (const auto& demandElement : demandElements) {
129
myDemandElementsComboBox->appendIconItem(demandElement->getID().c_str(), demandElement->getACIcon());
130
}
131
}
132
133
134
void
135
GNEDemandElementSelector::showDemandElementSelector() {
136
// first refresh modul
137
refreshDemandElementSelector();
138
// if current selected item isn't valid, set DEFAULT_VTYPE_ID or DEFAULT_PEDTYPE_ID
139
if (myCurrentDemandElement) {
140
myDemandElementsComboBox->setCurrentItem(myCurrentDemandElement->getID().c_str());
141
} else if (myDemandElementTags.size() == 1) {
142
if (myDemandElementTags.at(0) == SUMO_TAG_VTYPE) {
143
const auto defaultVType = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, DEFAULT_VTYPE_ID);
144
myDemandElementsComboBox->setCurrentItem(defaultVType->getID().c_str());
145
}
146
}
147
onCmdSelectDemandElement(nullptr, 0, nullptr);
148
show();
149
}
150
151
152
void
153
GNEDemandElementSelector::hideDemandElementSelector() {
154
hide();
155
}
156
157
158
bool
159
GNEDemandElementSelector::isDemandElementSelectorShown() const {
160
return shown();
161
}
162
163
164
void
165
GNEDemandElementSelector::refreshDemandElementSelector() {
166
// get demand elemenst container
167
const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
168
// clear demand elements comboBox
169
myDemandElementsComboBox->clearItems();
170
// fill myTypeMatchBox with list of demand elements
171
for (const auto& demandElementTag : myDemandElementTags) {
172
// special case for VTypes
173
if (demandElementTag == SUMO_TAG_VTYPE) {
174
// add default types in the first positions depending of frame parent
175
if (myTagType & GNETagProperties::Type::PERSON) {
176
// first pedestrian
177
myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));
178
myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));
179
myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));
180
myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));
181
myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));
182
myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));
183
} else if (myTagType & GNETagProperties::Type::CONTAINER) {
184
// first container
185
myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));
186
myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));
187
myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));
188
myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));
189
myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));
190
myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));
191
} else {
192
// first default vType
193
myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));
194
myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));
195
myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));
196
myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));
197
myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));
198
myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));
199
}
200
// add rest of vTypes
201
for (const auto& vType : ACs->getDemandElements().at(demandElementTag)) {
202
// avoid insert duplicated default vType
203
if (DEFAULT_VTYPES.count(vType.second->getID()) == 0) {
204
myDemandElementsComboBox->appendIconItem(vType.second->getID().c_str(), vType.second->getACIcon());
205
}
206
}
207
} else {
208
// insert all elements sorted by ID
209
std::map<std::string, GNEDemandElement*> sortedElements;
210
for (const auto& demandElement : ACs->getDemandElements().at(demandElementTag)) {
211
sortedElements[demandElement.second->getID()] = demandElement.second;
212
}
213
for (const auto& demandElement : sortedElements) {
214
myDemandElementsComboBox->appendIconItem(demandElement.first.c_str(), demandElement.second->getACIcon(),
215
demandElement.second->getTagProperty()->getBackGroundColor());
216
}
217
}
218
}
219
// update myCurrentDemandElement
220
if (myDemandElementsComboBox->getNumItems() == 0) {
221
myCurrentDemandElement = nullptr;
222
} else if (myCurrentDemandElement) {
223
for (int i = 0; i < myDemandElementsComboBox->getNumItems(); i++) {
224
if (myDemandElementsComboBox->getItemText(i) == myCurrentDemandElement->getID()) {
225
myDemandElementsComboBox->setCurrentItem(i, FALSE);
226
}
227
}
228
} else {
229
for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {
230
myCurrentDemandElement = ACs->retrieveDemandElement(*i, myDemandElementsComboBox->getItemText(0), false);
231
}
232
if (myCurrentDemandElement == nullptr) {
233
// update myCurrentDemandElement with the first allowed element
234
for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {
235
if (ACs->getDemandElements().at(*i).size() > 0) {
236
myCurrentDemandElement = ACs->getDemandElements().at(*i).begin()->second;
237
}
238
}
239
}
240
}
241
}
242
243
244
GNEDemandElement*
245
GNEDemandElementSelector::getPreviousPlanElement() const {
246
if (myCurrentDemandElement == nullptr) {
247
return nullptr;
248
}
249
if (!myCurrentDemandElement->getTagProperty()->isPerson() &&
250
!myCurrentDemandElement->getTagProperty()->isContainer()) {
251
return nullptr;
252
}
253
if (myCurrentDemandElement->getChildDemandElements().empty()) {
254
return nullptr;
255
}
256
return myCurrentDemandElement->getChildDemandElements().back();
257
}
258
259
260
long
261
GNEDemandElementSelector::onCmdSelectDemandElement(FXObject*, FXSelector, void*) {
262
// Check if value of myTypeMatchBox correspond to a demand element
263
for (const auto& demandElementTag : myDemandElementTags) {
264
for (const auto& demandElement : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(demandElementTag)) {
265
if (demandElement.second->getID() == myDemandElementsComboBox->getText().text()) {
266
// set color of myTypeMatchBox to black (valid)
267
myDemandElementsComboBox->setTextColor(GUIDesignTextColorBlack);
268
myDemandElementsComboBox->killFocus();
269
// Set new current demand element
270
myCurrentDemandElement = demandElement.second;
271
// call demandElementSelected function
272
myFrameParent->demandElementSelected();
273
return 1;
274
}
275
}
276
}
277
// if demand element selected is invalid, set demand element as null
278
myCurrentDemandElement = nullptr;
279
// call demandElementSelected function
280
myFrameParent->demandElementSelected();
281
// change color of myDemandElementsComboBox to red (invalid)
282
myDemandElementsComboBox->setTextColor(GUIDesignTextColorRed);
283
return 1;
284
}
285
286
/****************************************************************************/
287
288