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