Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEInspectorFrame.cpp
Go to the documentation of this file.
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/****************************************************************************/
19// The Widget for modifying network-element attributes (i.e. lane speed)
20/****************************************************************************/
21
23#include <netedit/GNENet.h>
25#include <netedit/GNEUndoList.h>
33
34#include "GNEInspectorFrame.h"
35
36// ===========================================================================
37// FOX callback mapping
38// ===========================================================================
39
43
49
50// Object implementation
51FXIMPLEMENT(GNEInspectorFrame, FXVerticalFrame, GNEInspectorFrameMap, ARRAYNUMBER(GNEInspectorFrameMap))
52FXIMPLEMENT(GNEInspectorFrame::TemplateEditor, MFXGroupBoxModule, TemplateEditorMap, ARRAYNUMBER(TemplateEditorMap))
53
54
55// ===========================================================================
56// method definitions
57// ===========================================================================
58
59// ---------------------------------------------------------------------------
60// GNEInspectorFrame::TemplateEditor - methods
61// ---------------------------------------------------------------------------
62
64 MFXGroupBoxModule(inspectorFrameParent, TL("Templates")),
65 myInspectorFrameParent(inspectorFrameParent),
66 myEdgeTemplate(nullptr) {
67 // Create set template button
69 // Create copy template button
71 // Create copy template button
73}
74
75
78
79
80bool
82 // show template editor only if we're editing an edge in Network mode AND we have at least one inspected edge
83 if (myInspectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
84 for (const auto& AC : myInspectorFrameParent->getViewNet()->getInspectedElements().getACs()) {
85 if (AC->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
86 // update buttons and show module
88 show();
89 return true;
90 }
91 }
92 }
93 return false;
94}
95
96
97void
99 // hide template editor
100 hide();
101}
102
103
108
109
110void
112 // delete previous template edge
113 if (myEdgeTemplate) {
114 delete myEdgeTemplate;
115 myEdgeTemplate = nullptr;
116 }
117 // update edge template
118 if (edge) {
120 // use template by default
121 myInspectorFrameParent->myViewNet->getViewParent()->getCreateEdgeFrame()->setUseEdgeTemplate();
122 }
123}
124
125
126void
128 if (myEdgeTemplate) {
129 myEdgeTemplate->updateLaneTemplates();
130 // use template by default
131 myInspectorFrameParent->myViewNet->getViewParent()->getCreateEdgeFrame()->setUseEdgeTemplate();
132 }
133}
134
135void
137 // check if template editor AND mySetTemplateButton is enabled
138 if (shown() && mySetTemplateButton->isEnabled()) {
139 onCmdSetTemplate(nullptr, 0, nullptr);
140 }
141}
142
143
144void
146 // check if template editor AND myCopyTemplateButton is enabled
147 if (shown() && myCopyTemplateButton->isEnabled()) {
148 onCmdCopyTemplate(nullptr, 0, nullptr);
149 }
150}
151
152
153void
155 // check if template editor AND myClearTemplateButton is enabled
156 if (shown() && myClearTemplateButton->isEnabled()) {
157 onCmdClearTemplate(nullptr, 0, nullptr);
158 }
159}
160
161
162long
164 // apply to all selected edges
165 for (const auto& AC : myInspectorFrameParent->myViewNet->getInspectedElements().getACs()) {
166 if (AC->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
167 // set template
168 setEdgeTemplate(myInspectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC->getID()));
169 // update buttons
171 }
172 }
173 return 1;
174}
175
176
177long
179 // first check
180 if (myEdgeTemplate) {
181 // begin copy template
182 myInspectorFrameParent->myViewNet->getUndoList()->begin(myEdgeTemplate, "copy edge template");
183 // iterate over inspected ACs
184 for (const auto& AC : myInspectorFrameParent->myViewNet->getInspectedElements().getACs()) {
185 // avoid copy template in the same edge
186 if (AC->getID() != myEdgeTemplate->getID()) {
187 // retrieve edge ID (and throw exception if edge doesn't exist)
188 myInspectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC->getID())->copyTemplate(myEdgeTemplate, myInspectorFrameParent->myViewNet->getUndoList());
189 }
190 }
191 // end copy template
192 myInspectorFrameParent->myViewNet->getUndoList()->end();
193 // refresh inspector parent
194 myInspectorFrameParent->myAttributesEditor->refreshAttributesEditor();
195 }
196 return 1;
197}
198
199
200long
202 // set null edge
203 setEdgeTemplate(nullptr);
204 // update buttons
206 return 1;
207}
208
209
210void
212 const auto& inspectedElements = myInspectorFrameParent->getViewNet()->getInspectedElements();
213 // only show set template button if we have exactly one inspected edge
214 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_EDGE)) {
215 mySetTemplateButton->setText((TLF("Set edge '%' as Template", inspectedElements.getFirstAC()->getID())).c_str());
216 mySetTemplateButton->show();
217 } else {
218 mySetTemplateButton->hide();
219 }
220 // enable or disable clear buttons depending of myEdgeTemplate
221 if (myEdgeTemplate) {
222 // update caption of copy button
223 if (inspectedElements.isInspectingSingleElement()) {
224 myCopyTemplateButton->setText(("Copy '" + myEdgeTemplate->getID() + "' into edge '" + inspectedElements.getFirstAC()->getID() + "'").c_str());
225 } else {
226 myCopyTemplateButton->setText(("Copy '" + myEdgeTemplate->getID() + "' into " + toString(inspectedElements.getACs().size()) + " selected edges").c_str());
227 }
228 // enable set and clear buttons
229 myCopyTemplateButton->enable();
230 myClearTemplateButton->enable();
231 } else {
232 // update caption of copy button
233 myCopyTemplateButton->setText(TL("No edge Template Set"));
234 // disable set and clear buttons
235 myCopyTemplateButton->disable();
236 myClearTemplateButton->disable();
237 }
238}
239
240// ---------------------------------------------------------------------------
241// GNEInspectorFrame - methods
242// ---------------------------------------------------------------------------
243
245 GNEFrame(viewParent, viewNet, "Inspector") {
246
247 // Create back button
250 myHeaderLeftFrame->hide();
251 myBackButton->hide();
252
253 // Create Overlapped Inspection module
255
256 // Create Attributes Editor module
258
259 // Create Template editor module
261
262 // Create GNEElementTree module
264}
265
266
268
269
270void
273 // stop reparenting
274 myAttributesEditor->abortReparenting();
275 // show
277}
278
279
280void
282 myViewNet->getInspectedElements().inspectACs({});
284}
285
286
287bool
289 const Position& clickedPosition, const bool shiftKeyPressed) {
290 // get unlocked attribute carrier front
291 auto AC = viewObjects.getAttributeCarrierFront();
292 // first check if we have clicked over an Attribute Carrier
293 if (AC) {
294 // if Control key is Pressed, select instead inspect element
295 if (myViewNet->getMouseButtonKeyPressed().controlKeyPressed()) {
296 // toggle networkElement selection
297 if (AC->isAttributeCarrierSelected()) {
298 AC->unselectAttributeCarrier();
299 } else {
300 AC->selectAttributeCarrier();
301 }
302 } else {
303 // show Overlapped Inspection module
304 myOverlappedInspection->showOverlappedInspection(viewObjects, clickedPosition, shiftKeyPressed);
305 // focus upper element of inspector frame
307 }
308 return true;
309 } else {
310 return false;
311 }
312}
313
314
315void
317 std::vector<GNEAttributeCarrier*> itemsToInspect;
318 // Use the implementation of inspect for multiple AttributeCarriers to avoid repetition of code
319 if (AC) {
320 if (AC->isAttributeCarrierSelected() && !myViewNet->getMouseButtonKeyPressed().altKeyPressed()) {
321 // obtain selected ACs depending of current supermode
322 const auto selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
323 // reserve space
324 itemsToInspect.reserve(selectedACs.size());
325 // iterate over selected ACs
326 for (const auto& selectedAC : selectedACs) {
327 // filter ACs to inspect using Tag as criterion
328 if (selectedAC->getTagProperty()->getTag() == AC->getTagProperty()->getTag()) {
329 itemsToInspect.push_back(selectedAC);
330 }
331 }
332 } else {
333 itemsToInspect.push_back(AC);
334 }
335 }
336 inspectElements(itemsToInspect, previousInspectedAC);
337}
338
339void
340GNEInspectorFrame::inspectElements(const std::vector<GNEAttributeCarrier*>& ACs, GNEAttributeCarrier* previousInspectedAC) {
341 myViewNet->getInspectedElements().inspectACs(ACs);
342 myPreviousInspectedAC = previousInspectedAC;
344}
345
346
347void
349 // simply clear overlapped inspection (it refresh inspector frame)
350 myOverlappedInspection->clearOverlappedInspection();
351}
352
353
354void
356 const auto& inspectedElements = myViewNet->getInspectedElements();
357 // check if show back button
359 myHeaderLeftFrame->show();
360 myBackButton->show();
361 } else {
362 myHeaderLeftFrame->hide();
363 myBackButton->hide();
364 }
365 // Show all attribute editors (will be automatically hidden if there are no elements to inspect)
366 myAttributesEditor->showAttributesEditor(inspectedElements.getACs(), true);
367 // Hide other moduls
368 myTemplateEditor->hideTemplateEditor();
369 myHierarchicalElementTree->hideHierarchicalElementTree();
370 // If vector of attribute Carriers contain data
371 if (inspectedElements.isInspectingElements()) {
372 // Set header
373 std::string headerString;
374 if (inspectedElements.getFirstAC()->getTagProperty()->isNetworkElement()) {
375 headerString = "Net: ";
376 } else if (inspectedElements.getFirstAC()->getTagProperty()->isAdditionalElement()) {
377 headerString = "Additional: ";
378 } else if (inspectedElements.getFirstAC()->getTagProperty()->isShapeElement()) {
379 headerString = "Shape: ";
380 } else if (inspectedElements.getFirstAC()->getTagProperty()->isTAZElement()) {
381 headerString = "TAZ: ";
382 } else if (inspectedElements.getFirstAC()->getTagProperty()->isWireElement()) {
383 headerString = "WIRE: ";
384 } else if (inspectedElements.getFirstAC()->getTagProperty()->isVehicle()) {
385 headerString = "Vehicle: ";
386 } else if (inspectedElements.getFirstAC()->getTagProperty()->isRoute()) {
387 headerString = "Route: ";
388 } else if (inspectedElements.getFirstAC()->getTagProperty()->isPerson()) {
389 headerString = "Person: ";
390 } else if (inspectedElements.getFirstAC()->getTagProperty()->isPlanPerson()) {
391 headerString = "PersonPlan: ";
392 } else if (inspectedElements.getFirstAC()->getTagProperty()->isContainer()) {
393 headerString = "Container: ";
394 } else if (inspectedElements.getFirstAC()->getTagProperty()->isPlanContainer()) {
395 headerString = "ContainerPlan: ";
396 } else if (inspectedElements.getFirstAC()->getTagProperty()->isVehicleStop()) {
397 headerString = "Stop: ";
398 } else if (inspectedElements.getFirstAC()->getTagProperty()->isDataElement()) {
399 headerString = "Data: ";
400 }
401 if (myViewNet->getInspectedElements().isInspectingMultipleElements()) {
402 headerString += toString(inspectedElements.getACs().size()) + " ";
403 }
404 headerString += inspectedElements.getFirstAC()->getTagStr();
405 if (myViewNet->getInspectedElements().isInspectingMultipleElements()) {
406 headerString += "s";
407 }
408 // Set headerString into header label
409 getFrameHeaderLabel()->setText(headerString.c_str());
410
411 // If attributes correspond to an Edge and we aren't in demand mode, show template editor
412 myTemplateEditor->showTemplateEditor();
413
414 // if we inspect a single Attribute carrier vector, show their children
415 if (inspectedElements.isInspectingSingleElement()) {
416 myHierarchicalElementTree->showHierarchicalElementTree(inspectedElements.getFirstAC());
417 }
418 } else {
419 getFrameHeaderLabel()->setText(TL("Inspect"));
420 myOverlappedInspection->hiderOverlappedInspection();
421 }
422 // update frame width
423 setFrameWidth(myViewNet->getViewParent()->getFrameAreaWidth());
424 // update viewNet
425 myViewNet->update();
426}
427
428
433
434
439
440
445
446
451
452
453long
456 return 1;
457}
458
459
460void
464
465
466void
468 inspectElement(AC);
469 // update view (due dotted contour)
470 myViewNet->updateViewNet();
471}
472
473/****************************************************************************/
FXDEFMAP(GNEInspectorFrame) GNEInspectorFrameMap[]
@ MID_GNE_INSPECTORFRAME_INSPECTPREVIOUSELEMENT
go back to the previous element
@ MID_HOTKEY_SHIFT_F2_TEMPLATE_COPY
copy template
Definition GUIAppEnum.h:266
@ MID_HOTKEY_SHIFT_F1_TEMPLATE_SET
set template
Definition GUIAppEnum.h:264
@ MID_HOTKEY_SHIFT_F3_TEMPLATE_CLEAR
clear template
Definition GUIAppEnum.h:268
#define GUIDesignButton
Definition GUIDesigns.h:100
#define GUIDesignButtonRectangular
little rectangular button used in frames (For example, in "help" buttons)
Definition GUIDesigns.h:112
@ BIGARROWLEFT
Definition GUIIcons.h:276
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
@ SUMO_TAG_EDGE
begin/end of the description of an edge
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
void setFrameWidth(const int newWidth)
set width of GNEFrame
Definition GNEFrame.cpp:128
void focusUpperElement()
focus upper element of frame
Definition GNEFrame.cpp:104
FXLabel * getFrameHeaderLabel() const
get the label for the frame's header
Definition GNEFrame.cpp:157
GNEViewNet * myViewNet
FOX need this.
Definition GNEFrame.h:122
virtual void show()
show Frame
Definition GNEFrame.cpp:110
virtual void hide()
hide Frame
Definition GNEFrame.cpp:119
GNEFrame(GNEViewParent *viewParent, GNEViewNet *viewNet, const std::string &frameLabel)
Constructor.
Definition GNEFrame.cpp:42
FXHorizontalFrame * myHeaderLeftFrame
fame for left header elements
Definition GNEFrame.h:131
void hideTemplateEditor()
hide template editor
GNEInspectorFrame * myInspectorFrameParent
current GNEInspectorFrame parent
void clearTemplate()
clear template (used by shortcut)
void setEdgeTemplate(const GNEEdge *edge)
set edge template
FXButton * myClearTemplateButton
clear template button
FXButton * mySetTemplateButton
set template button
long onCmdCopyTemplate(FXObject *, FXSelector, void *)
copy edge attributes from edge template
void setTemplate()
set template (used by shortcut)
TemplateEditor(GNEInspectorFrame *inspectorFrameParent)
FOX-declaration.
FXButton * myCopyTemplateButton
copy template button
GNEEdgeTemplate * myEdgeTemplate
edge Template
long onCmdSetTemplate(FXObject *, FXSelector, void *)
GNEEdgeTemplate * getEdgeTemplate() const
get edge template (to copy attributes from)
void copyTemplate()
copy template (used by shortcut)
void updateEdgeTemplate()
update edge template
bool showTemplateEditor()
show template editor
long onCmdClearTemplate(FXObject *, FXSelector, void *)
clear current edge template
long onCmdInspectPreviousElement(FXObject *, FXSelector, void *)
called when user press inspet previous elemnt button
GNEAttributeCarrier * myPreviousInspectedAC
Pointer to previous element inspected.
void selectedOverlappedElement(GNEAttributeCarrier *AC)
open GNEAttributesCreator extended dialog (can be reimplemented in frame children)
TemplateEditor * getTemplateEditor() const
get template editor
GNEInspectorFrame(GNEViewParent *viewParent, GNEViewNet *viewNet)
Constructor.
void inspectElements(const std::vector< GNEAttributeCarrier * > &ACs, GNEAttributeCarrier *previousInspectedAC=nullptr)
Inspect the given elements.
GNEElementTree * getHierarchicalElementTree() const
get GNEElementTree modul
bool inspectClickedElements(GNEViewNetHelper::ViewObjectsSelector &viewObjects, const Position &clickedPosition, const bool shiftKeyPressed)
process click over Viewnet
void show()
show inspector frame
GNEAttributesEditor * myAttributesEditor
Attributes editor.
GNEOverlappedInspection * myOverlappedInspection
FOX need this.
GNEOverlappedInspection * getOverlappedInspection() const
get GNEOverlappedInspection modul
void clearInspection()
clear inspection
GNEAttributesEditor * getAttributesEditor() const
get AttributesEditor
void hide()
hide inspector frame
FXButton * myBackButton
Back Button.
void inspectElement(GNEAttributeCarrier *AC, GNEAttributeCarrier *previousInspectedAC=nullptr)
Inspect a single element.
GNEElementTree * myHierarchicalElementTree
Attribute Carrier Hierarchy.
void refreshInspection()
refresh current inspection
~GNEInspectorFrame()
Destructor.
TemplateEditor * myTemplateEditor
Template editor.
void updateFrameAfterUndoRedo()
function called after undo/redo in the current frame (can be reimplemented in frame children)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
class used to group all variables related with objects under cursor after a click over view
GNEAttributeCarrier * getAttributeCarrierFront() const
get front attribute carrier or a pointer to nullptr
A single child window which contains a view of the simulation area.
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXGroupBoxModule (based on FXGroupBox).
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
MFXGroupBoxModule(GNEFrame *frame, const std::string &text, const int options=Options::COLLAPSIBLE)
constructor for frames
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37