Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/gui/globjects/GUICursorDialog.cpp
169684 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 GUICursorDialog.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Sep 2022
17
///
18
// Dialog for edit element under cursor
19
/****************************************************************************/
20
#include <config.h>
21
22
#include <utils/gui/div/GUIDesigns.h>
23
#include <utils/gui/windows/GUIAppEnum.h>
24
#include <utils/gui/windows/GUIMainWindow.h>
25
#include <utils/gui/windows/GUISUMOAbstractView.h>
26
27
#include <netedit/GNEUndoList.h>
28
29
#include "GUICursorDialog.h"
30
31
32
#define NUM_VISIBLE_ITEMS 10
33
34
// ===========================================================================
35
// FOX callback mapping
36
// ===========================================================================
37
38
FXDEFMAP(GUICursorDialog) GUICursorDialogMap[] = {
39
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_SETFRONTELEMENT, GUICursorDialog::onCmdSetFrontElement),
40
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_DELETEELEMENT, GUICursorDialog::onCmdDeleteElement),
41
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_SELECTELEMENT, GUICursorDialog::onCmdSelectElement),
42
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_PROPERTIES, GUICursorDialog::onCmdOpenPropertiesPopUp),
43
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_MOVEUP, GUICursorDialog::onCmdMoveListUp),
44
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_MOVEDOWN, GUICursorDialog::onCmdMoveListDown),
45
FXMAPFUNC(SEL_COMMAND, MID_CURSORDIALOG_FRONT, GUICursorDialog::onCmdProcessFront),
46
FXMAPFUNC(SEL_COMMAND, FXWindow::ID_UNPOST, GUICursorDialog::onCmdUnpost),
47
};
48
49
// Object implementation
50
FXIMPLEMENT(GUICursorDialog, GUIGLObjectPopupMenu, GUICursorDialogMap, ARRAYNUMBER(GUICursorDialogMap))
51
52
// ===========================================================================
53
// member method definitions
54
// ===========================================================================
55
56
GUICursorDialog::GUICursorDialog(GUIGLObjectPopupMenu::PopupType type, GUISUMOAbstractView* view, const std::vector<GUIGlObject*>& objects) :
57
GUIGLObjectPopupMenu(view->getMainWindow(), view, type),
58
myType(type),
59
myView(view) {
60
// continue depending of properties
61
if (type == GUIGLObjectPopupMenu::PopupType::PROPERTIES) {
62
buildDialogElements(view, TL("Overlapped objects"), GUIIcon::MODEINSPECT, MID_CURSORDIALOG_PROPERTIES, objects);
63
} else if (type == GUIGLObjectPopupMenu::PopupType::DELETE_ELEMENT) {
64
buildDialogElements(view, TL("Delete element"), GUIIcon::MODEDELETE, MID_CURSORDIALOG_DELETEELEMENT, objects);
65
} else if (type == GUIGLObjectPopupMenu::PopupType::SELECT_ELEMENT) {
66
buildDialogElements(view, TL("Select element"), GUIIcon::MODESELECT, MID_CURSORDIALOG_SELECTELEMENT, objects);
67
} else if (type == GUIGLObjectPopupMenu::PopupType::FRONT_ELEMENT) {
68
buildDialogElements(view, TL("Mark front element"), GUIIcon::FRONTELEMENT, MID_CURSORDIALOG_SETFRONTELEMENT, objects);
69
}
70
}
71
72
73
GUICursorDialog::~GUICursorDialog() {
74
// delete all menu commands
75
for (const auto& GLObject : myMenuCommandGLObjects) {
76
delete GLObject.first;
77
}
78
}
79
80
81
long
82
GUICursorDialog::onCmdSetFrontElement(FXObject* obj, FXSelector, void*) {
83
// search element in myGLObjects
84
for (const auto& GLObject : myMenuCommandGLObjects) {
85
if (GLObject.first == obj) {
86
GLObject.second->markAsFrontElement();
87
}
88
}
89
// destroy popup
90
myView->destroyPopup();
91
return 1;
92
}
93
94
95
long
96
GUICursorDialog::onCmdDeleteElement(FXObject* obj, FXSelector, void*) {
97
// search element in myGLObjects
98
for (const auto& GLObject : myMenuCommandGLObjects) {
99
if (GLObject.first == obj) {
100
GLObject.second->deleteGLObject();
101
}
102
}
103
// destroy popup
104
myView->destroyPopup();
105
return 1;
106
}
107
108
109
long
110
GUICursorDialog::onCmdSelectElement(FXObject* obj, FXSelector, void*) {
111
// search element in myGLObjects
112
for (const auto& GLObject : myMenuCommandGLObjects) {
113
if (GLObject.first == obj) {
114
GLObject.second->selectGLObject();
115
}
116
}
117
// destroy popup
118
myView->destroyPopup();
119
return 1;
120
}
121
122
123
long
124
GUICursorDialog::onCmdOpenPropertiesPopUp(FXObject* obj, FXSelector, void*) {
125
// search element in myGLObjects
126
for (const auto& GLObject : myMenuCommandGLObjects) {
127
if (GLObject.first == obj) {
128
myView->replacePopup(GLObject.second->getPopUpMenu(*myView->getMainWindow(), *myView));
129
return 1;
130
}
131
}
132
return 0;
133
}
134
135
136
long
137
GUICursorDialog::onCmdMoveListUp(FXObject*, FXSelector, void*) {
138
myListIndex -= NUM_VISIBLE_ITEMS;
139
updateList();
140
show();
141
return 0;
142
}
143
144
145
long
146
GUICursorDialog::onCmdMoveListDown(FXObject*, FXSelector, void*) {
147
myListIndex += NUM_VISIBLE_ITEMS;
148
updateList();
149
show();
150
return 0;
151
}
152
153
154
long
155
GUICursorDialog::onCmdProcessFront(FXObject*, FXSelector, void*) {
156
if (myMenuCommandGLObjects.size() > 0) {
157
// continue depending of properties
158
if (myType == GUIGLObjectPopupMenu::PopupType::DELETE_ELEMENT) {
159
myMenuCommandGLObjects.front().second->deleteGLObject();
160
} else if (myType == GUIGLObjectPopupMenu::PopupType::SELECT_ELEMENT) {
161
myMenuCommandGLObjects.front().second->selectGLObject();
162
} else if (myType == GUIGLObjectPopupMenu::PopupType::FRONT_ELEMENT) {
163
myMenuCommandGLObjects.front().second->markAsFrontElement();
164
}
165
}
166
return 0;
167
}
168
169
170
long
171
GUICursorDialog::onCmdUnpost(FXObject* obj, FXSelector, void* ptr) {
172
// ignore move up, down and header
173
if ((obj == myMoveUpMenuCommand) || (obj == myMoveDownMenuCommand) || (obj == myMenuHeader)) {
174
return 1;
175
}
176
if (grabowner) {
177
grabowner->handle(this, FXSEL(SEL_COMMAND, ID_UNPOST), ptr);
178
} else {
179
popdown();
180
if (grabbed()) {
181
ungrab();
182
}
183
}
184
return 1;
185
}
186
187
188
void
189
GUICursorDialog::updateList() {
190
// first hide all menu commands
191
for (const auto& GLObject : myMenuCommandGLObjects) {
192
GLObject.first->hide();
193
}
194
// check if disable menu command up
195
if (myListIndex == 0) {
196
myMoveUpMenuCommand->disable();
197
} else {
198
myMoveUpMenuCommand->enable();
199
}
200
// show menu commands depending of myListIndex
201
if ((myListIndex + NUM_VISIBLE_ITEMS) > (int)myMenuCommandGLObjects.size()) {
202
for (int i = (int)myMenuCommandGLObjects.size() - NUM_VISIBLE_ITEMS; i < (int)myMenuCommandGLObjects.size(); i++) {
203
myMenuCommandGLObjects.at(i).first->show();
204
}
205
myMoveDownMenuCommand->disable();
206
} else {
207
for (int i = myListIndex; i < (myListIndex + NUM_VISIBLE_ITEMS); i++) {
208
myMenuCommandGLObjects.at(i).first->show();
209
}
210
myMoveDownMenuCommand->enable();
211
}
212
// recalc popup
213
recalc();
214
}
215
216
217
void
218
GUICursorDialog::buildDialogElements(GUISUMOAbstractView* view, const FXString text, GUIIcon icon, FXSelector sel, const std::vector<GUIGlObject*>& objects) {
219
// create header
220
myMenuHeader = new MFXMenuHeader(this, view->getMainWindow()->getBoldFont(), text, GUIIconSubSys::getIcon(icon), nullptr, 0);
221
new FXMenuSeparator(this);
222
// check if create move up menu command
223
if (objects.size() > NUM_VISIBLE_ITEMS) {
224
myMoveUpMenuCommand = GUIDesigns::buildFXMenuCommand(this, "Previous", GUIIconSubSys::getIcon(GUIIcon::ARROW_UP), this, MID_CURSORDIALOG_MOVEUP);
225
new FXMenuSeparator(this);
226
}
227
// create a menu command for every object
228
for (const auto& GLObject : objects) {
229
myMenuCommandGLObjects.push_back(std::make_pair(GUIDesigns::buildFXMenuCommand(this, GLObject->getMicrosimID(), GLObject->getGLIcon(), this, sel), GLObject));
230
}
231
// check if create move down menu command
232
if (objects.size() > NUM_VISIBLE_ITEMS) {
233
new FXMenuSeparator(this);
234
myMoveDownMenuCommand = GUIDesigns::buildFXMenuCommand(this, "Next", GUIIconSubSys::getIcon(GUIIcon::ARROW_DOWN), this, MID_CURSORDIALOG_MOVEDOWN);
235
updateList();
236
}
237
}
238
239
/****************************************************************************/
240
241