Path: blob/main/src/netedit/frames/GNEDemandSelector.cpp
193905 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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, GNEGroupBoxModule, DemandElementSelectorMap, ARRAYNUMBER(DemandElementSelectorMap))414243// ===========================================================================44// method definitions45// ===========================================================================4647GNEDemandElementSelector::GNEDemandElementSelector(GNEFrame* frameParent, SumoXMLTag demandElementTag, const GNETagProperties::Type tagType) :48GNEGroupBoxModule(frameParent, TLF("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,65const std::vector<SumoXMLTag> exceptions) :66GNEGroupBoxModule(frameParent, TL("Parent element")),67myFrameParent(frameParent),68myCurrentDemandElement(nullptr),69myTagType(GNETagProperties::Type::OTHER),70mySelectingMultipleElements(false) {71// fill myDemandElementTags72for (const auto& tagType : tagTypes) {73const auto tagPropertiesByType = frameParent->getViewNet()->getNet()->getTagPropertiesDatabase()->getTagPropertiesByType(tagType);74for (const auto tagProperty : tagPropertiesByType) {75if (std::find(exceptions.begin(), exceptions.end(), tagProperty->getTag()) == exceptions.end()) {76myDemandElementTags.push_back(tagProperty->getTag());77}78}79}80// Create MFXComboBoxIcon81myDemandElementsComboBox = new MFXComboBoxIcon(getCollapsableFrame(), frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),82true, GUIDesignComboBoxVisibleItems, this, MID_GNE_SET_TYPE, GUIDesignComboBox);83// refresh demand element MatchBox84refreshDemandElementSelector();85// shown after creation86show();87}888990GNEDemandElementSelector::~GNEDemandElementSelector() {}919293GNEDemandElement*94GNEDemandElementSelector::getCurrentDemandElement() const {95return myCurrentDemandElement;96}979899const std::vector<SumoXMLTag>&100GNEDemandElementSelector::getAllowedTags() const {101return myDemandElementTags;102}103104105void106GNEDemandElementSelector::setDemandElement(GNEDemandElement* demandElement) {107mySelectingMultipleElements = false;108// Set new current demand element109myCurrentDemandElement = demandElement;110if (demandElement != nullptr) {111// check that demandElement tag correspond to a tag of myDemandElementTags112if (std::find(myDemandElementTags.begin(), myDemandElementTags.end(), demandElement->getTagProperty()->getTag()) != myDemandElementTags.end()) {113// update text of myDemandElementsComboBox114myDemandElementsComboBox->setCurrentItem(demandElement->getID().c_str());115}116}117// call demandElementSelected function118myFrameParent->demandElementSelected();119}120121122void123GNEDemandElementSelector::setDemandElements(const std::vector<GNEDemandElement*>& demandElements) {124mySelectingMultipleElements = true;125myCurrentDemandElement = nullptr;126myDemandElementsComboBox->clearItems();127for (const auto& demandElement : demandElements) {128myDemandElementsComboBox->appendIconItem(demandElement->getID().c_str(), demandElement->getACIcon());129}130}131132133void134GNEDemandElementSelector::showDemandElementSelector() {135// first refresh modul136refreshDemandElementSelector();137// if current selected item isn't valid, set DEFAULT_VTYPE_ID or DEFAULT_PEDTYPE_ID138if (myCurrentDemandElement) {139myDemandElementsComboBox->setCurrentItem(myCurrentDemandElement->getID().c_str());140} else if (myDemandElementTags.size() == 1) {141if (myDemandElementTags.at(0) == SUMO_TAG_VTYPE) {142const auto defaultVType = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, DEFAULT_VTYPE_ID);143myDemandElementsComboBox->setCurrentItem(defaultVType->getID().c_str());144}145}146onCmdSelectDemandElement(nullptr, 0, nullptr);147show();148}149150151void152GNEDemandElementSelector::hideDemandElementSelector() {153hide();154}155156157bool158GNEDemandElementSelector::isDemandElementSelectorShown() const {159return shown();160}161162163void164GNEDemandElementSelector::refreshDemandElementSelector() {165// get demand elemenst container166const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();167// clear demand elements comboBox168myDemandElementsComboBox->clearItems();169// fill myTypeMatchBox with list of demand elements170for (const auto& demandElementTag : myDemandElementTags) {171// special case for VTypes172if (demandElementTag == SUMO_TAG_VTYPE) {173// add default types in the first positions depending of frame parent174if (myTagType & GNETagProperties::Type::PERSON) {175// first pedestrian176myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));177myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));178myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));179myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));180myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));181myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));182} else if (myTagType & GNETagProperties::Type::CONTAINER) {183// first container184myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));185myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));186myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));187myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));188myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));189myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));190} else {191// first default vType192myDemandElementsComboBox->appendIconItem(DEFAULT_VTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_DEFAULT), FXRGBA(253, 255, 206, 255));193myDemandElementsComboBox->appendIconItem(DEFAULT_BIKETYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_BIKE), FXRGBA(253, 255, 206, 255));194myDemandElementsComboBox->appendIconItem(DEFAULT_TAXITYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_TAXI), FXRGBA(253, 255, 206, 255));195myDemandElementsComboBox->appendIconItem(DEFAULT_RAILTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_RAIL), FXRGBA(253, 255, 206, 255));196myDemandElementsComboBox->appendIconItem(DEFAULT_PEDTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_PEDESTRIAN), FXRGBA(253, 255, 206, 255));197myDemandElementsComboBox->appendIconItem(DEFAULT_CONTAINERTYPE_ID.c_str(), GUIIconSubSys::getIcon(GUIIcon::VTYPE_CONTAINER), FXRGBA(253, 255, 206, 255));198}199// add rest of vTypes200for (const auto& vType : ACs->getDemandElements().at(demandElementTag)) {201// avoid insert duplicated default vType202if (DEFAULT_VTYPES.count(vType.second->getID()) == 0) {203myDemandElementsComboBox->appendIconItem(vType.second->getID().c_str(), vType.second->getACIcon());204}205}206} else {207// insert all elements sorted by ID208std::map<std::string, GNEDemandElement*> sortedElements;209for (const auto& demandElement : ACs->getDemandElements().at(demandElementTag)) {210sortedElements[demandElement.second->getID()] = demandElement.second;211}212for (const auto& demandElement : sortedElements) {213myDemandElementsComboBox->appendIconItem(demandElement.first.c_str(), demandElement.second->getACIcon(),214demandElement.second->getTagProperty()->getBackGroundColor());215}216}217}218// update myCurrentDemandElement219if (myDemandElementsComboBox->getNumItems() == 0) {220myCurrentDemandElement = nullptr;221} else if (myCurrentDemandElement) {222for (int i = 0; i < myDemandElementsComboBox->getNumItems(); i++) {223if (myDemandElementsComboBox->getItemText(i) == myCurrentDemandElement->getID()) {224myDemandElementsComboBox->setCurrentItem(i, FALSE);225}226}227} else {228for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {229myCurrentDemandElement = ACs->retrieveDemandElement(*i, myDemandElementsComboBox->getItemText(0), false);230}231if (myCurrentDemandElement == nullptr) {232// update myCurrentDemandElement with the first allowed element233for (auto i = myDemandElementTags.begin(); (i != myDemandElementTags.end()) && (myCurrentDemandElement == nullptr); i++) {234if (ACs->getDemandElements().at(*i).size() > 0) {235myCurrentDemandElement = ACs->getDemandElements().at(*i).begin()->second;236}237}238}239}240}241242243GNEDemandElement*244GNEDemandElementSelector::getPreviousPlanElement() const {245if (myCurrentDemandElement == nullptr) {246return nullptr;247}248if (!myCurrentDemandElement->getTagProperty()->isPerson() &&249!myCurrentDemandElement->getTagProperty()->isContainer()) {250return nullptr;251}252if (myCurrentDemandElement->getChildDemandElements().empty()) {253return nullptr;254}255return myCurrentDemandElement->getChildDemandElements().back();256}257258259long260GNEDemandElementSelector::onCmdSelectDemandElement(FXObject*, FXSelector, void*) {261// Check if value of myTypeMatchBox correspond to a demand element262for (const auto& demandElementTag : myDemandElementTags) {263for (const auto& demandElement : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements().at(demandElementTag)) {264if (demandElement.second->getID() == myDemandElementsComboBox->getText().text()) {265// set color of myTypeMatchBox to black (valid)266myDemandElementsComboBox->setTextColor(GUIDesignTextColorBlack);267myDemandElementsComboBox->killFocus();268// Set new current demand element269myCurrentDemandElement = demandElement.second;270// call demandElementSelected function271myFrameParent->demandElementSelected();272return 1;273}274}275}276// if demand element selected is invalid, set demand element as null277myCurrentDemandElement = nullptr;278// call demandElementSelected function279myFrameParent->demandElementSelected();280// change color of myDemandElementsComboBox to red (invalid)281myDemandElementsComboBox->setTextColor(GUIDesignTextColorRed);282return 1;283}284285/****************************************************************************/286287288