Path: blob/main/src/netedit/frames/GNEDemandSelector.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEDemandSelector.cpp14/// @author Pablo Alvarez Lopez15/// @date Mar 202216///17// Frame for select demand elements18/****************************************************************************/1920#include <netedit/frames/common/GNEInspectorFrame.h>21#include <netedit/GNEApplicationWindow.h>22#include <netedit/GNENet.h>23#include <netedit/GNETagPropertiesDatabase.h>24#include <netedit/GNEViewNet.h>25#include <netedit/GNEViewParent.h>26#include <utils/gui/div/GUIDesigns.h>27#include <utils/gui/windows/GUIAppEnum.h>2829#include "GNEDemandSelector.h"3031// ===========================================================================32// FOX callback mapping33// ===========================================================================3435FXDEFMAP(GNEDemandElementSelector) DemandElementSelectorMap[] = {36FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_TYPE, GNEDemandElementSelector::onCmdSelectDemandElement),37};3839// Object implementation40FXIMPLEMENT(GNEDemandElementSelector, MFXGroupBoxModule, DemandElementSelectorMap, ARRAYNUMBER(DemandElementSelectorMap))414243// ===========================================================================44// method definitions45// ===========================================================================4647GNEDemandElementSelector::GNEDemandElementSelector(GNEFrame* frameParent, SumoXMLTag demandElementTag, const GNETagProperties::Type tagType) :48MFXGroupBoxModule(frameParent, (TL("Parent ") + toString(demandElementTag)).c_str()),49myFrameParent(frameParent),50myCurrentDemandElement(nullptr),51myDemandElementTags({demandElementTag}),52myTagType(tagType),53mySelectingMultipleElements(false) {54// Create MFXComboBoxIcon55myDemandElementsComboBox = new MFXComboBoxIcon(getCollapsableFrame(), frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),56true, GUIDesignComboBoxVisibleItems, this, MID_GNE_SET_TYPE, GUIDesignComboBox);57// refresh demand element MatchBox58refreshDemandElementSelector();59// shown after creation60show();61}626364GNEDemandElementSelector::GNEDemandElementSelector(GNEFrame* frameParent, const std::vector<GNETagProperties::Type>& tagTypes) :65MFXGroupBoxModule(frameParent, TL("Parent element")),66myFrameParent(frameParent),67myCurrentDemandElement(nullptr),68myTagType(GNETagProperties::Type::OTHER),69mySelectingMultipleElements(false) {70// fill myDemandElementTags71for (const auto& tagType : tagTypes) {72const auto tagPropertiesByType = frameParent->getViewNet()->getNet()->getTagPropertiesDatabase()->getTagPropertiesByType(tagType);73for (const auto tagProperty : tagPropertiesByType) {74myDemandElementTags.push_back(tagProperty->getTag());75}76}77// Create MFXComboBoxIcon78myDemandElementsComboBox = new MFXComboBoxIcon(getCollapsableFrame(), frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),79true, GUIDesignComboBoxVisibleItems, this, MID_GNE_SET_TYPE, GUIDesignComboBox);80// refresh demand element MatchBox81refreshDemandElementSelector();82// shown after creation83show();84}858687GNEDemandElementSelector::~GNEDemandElementSelector() {}888990GNEDemandElement*91GNEDemandElementSelector::getCurrentDemandElement() const {92return myCurrentDemandElement;93}949596const std::vector<SumoXMLTag>&97GNEDemandElementSelector::getAllowedTags() const {98return myDemandElementTags;99}100101102void103GNEDemandElementSelector::setDemandElement(GNEDemandElement* demandElement) {104mySelectingMultipleElements = false;105// Set new current demand element106myCurrentDemandElement = demandElement;107if (demandElement != nullptr) {108// check that demandElement tag correspond to a tag of myDemandElementTags109if (std::find(myDemandElementTags.begin(), myDemandElementTags.end(), demandElement->getTagProperty()->getTag()) != myDemandElementTags.end()) {110// update text of myDemandElementsComboBox111myDemandElementsComboBox->setCurrentItem(demandElement->getID().c_str());112}113}114// call demandElementSelected function115myFrameParent->demandElementSelected();116}117118119void120GNEDemandElementSelector::setDemandElements(const std::vector<GNEDemandElement*>& demandElements) {121mySelectingMultipleElements = true;122myCurrentDemandElement = nullptr;123myDemandElementsComboBox->clearItems();124for (const auto& demandElement : demandElements) {125myDemandElementsComboBox->appendIconItem(demandElement->getID().c_str(), demandElement->getACIcon());126}127}128129130void131GNEDemandElementSelector::showDemandElementSelector() {132// first refresh modul133refreshDemandElementSelector();134// if current selected item isn't valid, set DEFAULT_VTYPE_ID or DEFAULT_PEDTYPE_ID135if (myCurrentDemandElement) {136myDemandElementsComboBox->setCurrentItem(myCurrentDemandElement->getID().c_str());137} else if (myDemandElementTags.size() == 1) {138if (myDemandElementTags.at(0) == SUMO_TAG_VTYPE) {139const auto defaultVType = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, DEFAULT_VTYPE_ID);140myDemandElementsComboBox->setCurrentItem(defaultVType->getID().c_str());141}142}143onCmdSelectDemandElement(nullptr, 0, nullptr);144show();145}146147148void149GNEDemandElementSelector::hideDemandElementSelector() {150hide();151}152153154bool155GNEDemandElementSelector::isDemandElementSelectorShown() const {156return shown();157}158159160void161GNEDemandElementSelector::refreshDemandElementSelector() {162// get demand elemenst container163const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();164// clear demand elements comboBox165myDemandElementsComboBox->clearItems();166// fill myTypeMatchBox with list of demand elements167for (const auto& demandElementTag : myDemandElementTags) {168// special case for VTypes169if (demandElementTag == SUMO_TAG_VTYPE) {170// add default types in the first positions depending of frame parent171if (myTagType & GNETagProperties::Type::PERSON) {172// first pedestrian173myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));174myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));175myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));176myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));177myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));178myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));179} else if (myTagType & GNETagProperties::Type::CONTAINER) {180// first container181myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));182myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));183myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));184myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));185myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));186myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));187} else {188// first default vType189myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));190myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));191myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));192myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));193myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));194myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));195}196// add rest of vTypes197for (const auto& vType : ACs->getDemandElements().at(demandElementTag)) {198// avoid insert duplicated default vType199if (DEFAULT_VTYPES.count(vType.second->getID()) == 0) {200myDemandElementsComboBox->appendIconItem(vType.second->getID().c_str(), vType.second->getACIcon());201}202}203} else {204// insert all elements sorted by ID205std::map<std::string, GNEDemandElement*> sortedElements;206for (const auto& demandElement : ACs->getDemandElements().at(demandElementTag)) {207sortedElements[demandElement.second->getID()] = demandElement.second;208}209for (const auto& demandElement : sortedElements) {210myDemandElementsComboBox->appendIconItem(demandElement.first.c_str(), demandElement.second->getACIcon(),211demandElement.second->getTagProperty()->getBackGroundColor());212}213}214}215// update myCurrentDemandElement216if (myDemandElementsComboBox->getNumItems() == 0) {217myCurrentDemandElement = nullptr;218} else if (myCurrentDemandElement) {219for (int i = 0; i < myDemandElementsComboBox->getNumItems(); i++) {220if (myDemandElementsComboBox->getItemText(i) == myCurrentDemandElement->getID()) {221myDemandElementsComboBox->setCurrentItem(i, FALSE);222}223}224} else {225for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {226myCurrentDemandElement = ACs->retrieveDemandElement(*i, myDemandElementsComboBox->getItemText(0), false);227}228if (myCurrentDemandElement == nullptr) {229// update myCurrentDemandElement with the first allowed element230for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {231if (ACs->getDemandElements().at(*i).size() > 0) {232myCurrentDemandElement = ACs->getDemandElements().at(*i).begin()->second;233}234}235}236}237}238239240GNEDemandElement*241GNEDemandElementSelector::getPreviousPlanElement() const {242if (myCurrentDemandElement == nullptr) {243return nullptr;244}245if (!myCurrentDemandElement->getTagProperty()->isPerson() &&246!myCurrentDemandElement->getTagProperty()->isContainer()) {247return nullptr;248}249if (myCurrentDemandElement->getChildDemandElements().empty()) {250return nullptr;251}252return myCurrentDemandElement->getChildDemandElements().back();253}254255256long257GNEDemandElementSelector::onCmdSelectDemandElement(FXObject*, FXSelector, void*) {258// Check if value of myTypeMatchBox correspond to a demand element259for (const auto& demandElementTag : myDemandElementTags) {260for (const auto& demandElement : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(demandElementTag)) {261if (demandElement.second->getID() == myDemandElementsComboBox->getText().text()) {262// set color of myTypeMatchBox to black (valid)263myDemandElementsComboBox->setTextColor(GUIDesignTextColorBlack);264myDemandElementsComboBox->killFocus();265// Set new current demand element266myCurrentDemandElement = demandElement.second;267// call demandElementSelected function268myFrameParent->demandElementSelected();269return 1;270}271}272}273// if demand element selected is invalid, set demand element as null274myCurrentDemandElement = nullptr;275// call demandElementSelected function276myFrameParent->demandElementSelected();277// change color of myDemandElementsComboBox to red (invalid)278myDemandElementsComboBox->setTextColor(GUIDesignTextColorRed);279return 1;280}281282/****************************************************************************/283284285