Path: blob/main/src/utils/gui/globjects/GUICursorDialog.cpp
169684 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 GUICursorDialog.cpp14/// @author Pablo Alvarez Lopez15/// @date Sep 202216///17// Dialog for edit element under cursor18/****************************************************************************/19#include <config.h>2021#include <utils/gui/div/GUIDesigns.h>22#include <utils/gui/windows/GUIAppEnum.h>23#include <utils/gui/windows/GUIMainWindow.h>24#include <utils/gui/windows/GUISUMOAbstractView.h>2526#include <netedit/GNEUndoList.h>2728#include "GUICursorDialog.h"293031#define NUM_VISIBLE_ITEMS 103233// ===========================================================================34// FOX callback mapping35// ===========================================================================3637FXDEFMAP(GUICursorDialog) GUICursorDialogMap[] = {38FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_SETFRONTELEMENT, GUICursorDialog::onCmdSetFrontElement),39FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_DELETEELEMENT, GUICursorDialog::onCmdDeleteElement),40FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_SELECTELEMENT, GUICursorDialog::onCmdSelectElement),41FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_PROPERTIES, GUICursorDialog::onCmdOpenPropertiesPopUp),42FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_MOVEUP, GUICursorDialog::onCmdMoveListUp),43FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_MOVEDOWN, GUICursorDialog::onCmdMoveListDown),44FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_FRONT, GUICursorDialog::onCmdProcessFront),45FXMAPFUNC(SEL_COMMAND, FXWindow::ID_UNPOST, GUICursorDialog::onCmdUnpost),46};4748// Object implementation49FXIMPLEMENT(GUICursorDialog, GUIGLObjectPopupMenu, GUICursorDialogMap, ARRAYNUMBER(GUICursorDialogMap))5051// ===========================================================================52// member method definitions53// ===========================================================================5455GUICursorDialog::GUICursorDialog(GUIGLObjectPopupMenu::PopupType type, GUISUMOAbstractView* view, const std::vector<GUIGlObject*>& objects) :56GUIGLObjectPopupMenu(view->getMainWindow(), view, type),57myType(type),58myView(view) {59// continue depending of properties60if (type == GUIGLObjectPopupMenu::PopupType::PROPERTIES) {61buildDialogElements(view, TL("Overlapped objects"), GUIIcon::MODEINSPECT, MID_CURSORDIALOG_PROPERTIES, objects);62} else if (type == GUIGLObjectPopupMenu::PopupType::DELETE_ELEMENT) {63buildDialogElements(view, TL("Delete element"), GUIIcon::MODEDELETE, MID_CURSORDIALOG_DELETEELEMENT, objects);64} else if (type == GUIGLObjectPopupMenu::PopupType::SELECT_ELEMENT) {65buildDialogElements(view, TL("Select element"), GUIIcon::MODESELECT, MID_CURSORDIALOG_SELECTELEMENT, objects);66} else if (type == GUIGLObjectPopupMenu::PopupType::FRONT_ELEMENT) {67buildDialogElements(view, TL("Mark front element"), GUIIcon::FRONTELEMENT, MID_CURSORDIALOG_SETFRONTELEMENT, objects);68}69}707172GUICursorDialog::~GUICursorDialog() {73// delete all menu commands74for (const auto& GLObject : myMenuCommandGLObjects) {75delete GLObject.first;76}77}787980long81GUICursorDialog::onCmdSetFrontElement(FXObject* obj, FXSelector, void*) {82// search element in myGLObjects83for (const auto& GLObject : myMenuCommandGLObjects) {84if (GLObject.first == obj) {85GLObject.second->markAsFrontElement();86}87}88// destroy popup89myView->destroyPopup();90return 1;91}929394long95GUICursorDialog::onCmdDeleteElement(FXObject* obj, FXSelector, void*) {96// search element in myGLObjects97for (const auto& GLObject : myMenuCommandGLObjects) {98if (GLObject.first == obj) {99GLObject.second->deleteGLObject();100}101}102// destroy popup103myView->destroyPopup();104return 1;105}106107108long109GUICursorDialog::onCmdSelectElement(FXObject* obj, FXSelector, void*) {110// search element in myGLObjects111for (const auto& GLObject : myMenuCommandGLObjects) {112if (GLObject.first == obj) {113GLObject.second->selectGLObject();114}115}116// destroy popup117myView->destroyPopup();118return 1;119}120121122long123GUICursorDialog::onCmdOpenPropertiesPopUp(FXObject* obj, FXSelector, void*) {124// search element in myGLObjects125for (const auto& GLObject : myMenuCommandGLObjects) {126if (GLObject.first == obj) {127myView->replacePopup(GLObject.second->getPopUpMenu(*myView->getMainWindow(), *myView));128return 1;129}130}131return 0;132}133134135long136GUICursorDialog::onCmdMoveListUp(FXObject*, FXSelector, void*) {137myListIndex -= NUM_VISIBLE_ITEMS;138updateList();139show();140return 0;141}142143144long145GUICursorDialog::onCmdMoveListDown(FXObject*, FXSelector, void*) {146myListIndex += NUM_VISIBLE_ITEMS;147updateList();148show();149return 0;150}151152153long154GUICursorDialog::onCmdProcessFront(FXObject*, FXSelector, void*) {155if (myMenuCommandGLObjects.size() > 0) {156// continue depending of properties157if (myType == GUIGLObjectPopupMenu::PopupType::DELETE_ELEMENT) {158myMenuCommandGLObjects.front().second->deleteGLObject();159} else if (myType == GUIGLObjectPopupMenu::PopupType::SELECT_ELEMENT) {160myMenuCommandGLObjects.front().second->selectGLObject();161} else if (myType == GUIGLObjectPopupMenu::PopupType::FRONT_ELEMENT) {162myMenuCommandGLObjects.front().second->markAsFrontElement();163}164}165return 0;166}167168169long170GUICursorDialog::onCmdUnpost(FXObject* obj, FXSelector, void* ptr) {171// ignore move up, down and header172if ((obj == myMoveUpMenuCommand) || (obj == myMoveDownMenuCommand) || (obj == myMenuHeader)) {173return 1;174}175if (grabowner) {176grabowner->handle(this, FXSEL(SEL_COMMAND, ID_UNPOST), ptr);177} else {178popdown();179if (grabbed()) {180ungrab();181}182}183return 1;184}185186187void188GUICursorDialog::updateList() {189// first hide all menu commands190for (const auto& GLObject : myMenuCommandGLObjects) {191GLObject.first->hide();192}193// check if disable menu command up194if (myListIndex == 0) {195myMoveUpMenuCommand->disable();196} else {197myMoveUpMenuCommand->enable();198}199// show menu commands depending of myListIndex200if ((myListIndex + NUM_VISIBLE_ITEMS) > (int)myMenuCommandGLObjects.size()) {201for (int i = (int)myMenuCommandGLObjects.size() - NUM_VISIBLE_ITEMS; i < (int)myMenuCommandGLObjects.size(); i++) {202myMenuCommandGLObjects.at(i).first->show();203}204myMoveDownMenuCommand->disable();205} else {206for (int i = myListIndex; i < (myListIndex + NUM_VISIBLE_ITEMS); i++) {207myMenuCommandGLObjects.at(i).first->show();208}209myMoveDownMenuCommand->enable();210}211// recalc popup212recalc();213}214215216void217GUICursorDialog::buildDialogElements(GUISUMOAbstractView* view, const FXString text, GUIIcon icon, FXSelector sel, const std::vector<GUIGlObject*>& objects) {218// create header219myMenuHeader = new MFXMenuHeader(this, view->getMainWindow()->getBoldFont(), text, GUIIconSubSys::getIcon(icon), nullptr, 0);220new FXMenuSeparator(this);221// check if create move up menu command222if (objects.size() > NUM_VISIBLE_ITEMS) {223myMoveUpMenuCommand = GUIDesigns::buildFXMenuCommand(this, "Previous", GUIIconSubSys::getIcon(GUIIcon::ARROW_UP), this, MID_CURSORDIALOG_MOVEUP);224new FXMenuSeparator(this);225}226// create a menu command for every object227for (const auto& GLObject : objects) {228myMenuCommandGLObjects.push_back(std::make_pair(GUIDesigns::buildFXMenuCommand(this, GLObject->getMicrosimID(), GLObject->getGLIcon(), this, sel), GLObject));229}230// check if create move down menu command231if (objects.size() > NUM_VISIBLE_ITEMS) {232new FXMenuSeparator(this);233myMoveDownMenuCommand = GUIDesigns::buildFXMenuCommand(this, "Next", GUIIconSubSys::getIcon(GUIIcon::ARROW_DOWN), this, MID_CURSORDIALOG_MOVEDOWN);234updateList();235}236}237238/****************************************************************************/239240241