Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEDistributionFrame.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/****************************************************************************/
18// The Widget for edit distribution elements
19/****************************************************************************/
20
27#include <netedit/GNENet.h>
29#include <netedit/GNEUndoList.h>
33
35
36#define TEMPORAL_FILENAME std::string()
37
38// ===========================================================================
39// FOX callback mapping
40// ===========================================================================
41
47
52
53
58
62
63// Object implementation
64FXIMPLEMENT(GNEDistributionFrame::DistributionEditor, MFXGroupBoxModule, DistributionEditorMap, ARRAYNUMBER(DistributionEditorMap))
65FXIMPLEMENT(GNEDistributionFrame::DistributionSelector, MFXGroupBoxModule, DistributionSelectorMap, ARRAYNUMBER(DistributionSelectorMap))
66FXIMPLEMENT(GNEDistributionFrame::DistributionRow, FXHorizontalFrame, DistributionRowMap, ARRAYNUMBER(DistributionRowMap))
67FXIMPLEMENT(GNEDistributionFrame::DistributionValuesEditor, MFXGroupBoxModule, DistributionValuesEditorMap, ARRAYNUMBER(DistributionValuesEditorMap))
68
69
70// ===========================================================================
71// method definitions
72// ===========================================================================
73
74// ---------------------------------------------------------------------------
75// GNEDistributionFrame::DistributionEditor - methods
76// ---------------------------------------------------------------------------
77
79 MFXGroupBoxModule(frameParent, TL("Distribution Editor")),
80 myFrameParent(frameParent),
81 myDistributionTag(distributionTag) {
82 // get staticTooltip menu
83 auto staticTooltipMenu = myFrameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
84 // Create new distribution
85 myCreateDistributionButton = new MFXButtonTooltip(getCollapsableFrame(), staticTooltipMenu, TL("New"),
87 myCreateDistributionButton->setTipText(TLF("Create new %", toString(myDistributionTag)).c_str()),
88 // Delete distribution
89 myDeleteDistributionButton = new MFXButtonTooltip(getCollapsableFrame(), staticTooltipMenu, TL("Delete"),
91 myDeleteDistributionButton->setTipText(TLF("Delete current edited %", toString(myDistributionTag)).c_str()),
92 // show editor
93 show();
94}
95
96
98
99
102 return myDistributionTag;
103}
104
105
106long
108 auto undoList = myFrameParent->getViewNet()->getUndoList();
109 // obtain a new valid ID
110 const auto distributionID = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->generateDemandElementID(myDistributionTag);
111 // create new distribution
112 GNEDemandElement* distribution = nullptr;
113 if (myDistributionTag == SUMO_TAG_VTYPE_DISTRIBUTION) {
114 distribution = new GNEVTypeDistribution(distributionID, myFrameParent->getViewNet()->getNet(), TEMPORAL_FILENAME, -1);
115 } else if (myDistributionTag == SUMO_TAG_ROUTE_DISTRIBUTION) {
116 distribution = new GNERouteDistribution(distributionID, myFrameParent->getViewNet()->getNet(), TEMPORAL_FILENAME);
117 } else {
118 throw ProcessError("Invalid distribution");
119 }
120 // add it using undoList (to allow undo-redo)
121 undoList->begin(distribution->getTagProperty()->getGUIIcon(), "create distribution");
122 undoList->add(new GNEChange_DemandElement(distribution, true), true);
123 undoList->end();
124 // refresh selector using created distribution
125 myDistributionSelector->setDistribution(distribution);
126 return 1;
127}
128
129
130long
132 auto undoList = myFrameParent->getViewNet()->getUndoList();
133 auto currentDistribution = myDistributionSelector->getCurrentDistribution();
134 if (currentDistribution) {
135 // begin undo list operation
136 undoList->begin(currentDistribution->getTagProperty()->getGUIIcon(), "delete " + currentDistribution->getTagProperty()->getTagStr() + " distribution");
137 // remove distribution
138 myFrameParent->getViewNet()->getNet()->deleteDemandElement(myDistributionSelector->getCurrentDistribution(), undoList);
139 // end undo list operation
140 undoList->end();
141 // refresh selector
142 myDistributionSelector->refreshDistributionSelector();
143 }
144 return 1;
145}
146
147
148long
150 // check if we have a selected distribution
151 if (myDistributionSelector->getCurrentDistribution()) {
152 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
153 } else {
154 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
155 }
156}
157
158// ---------------------------------------------------------------------------
159// GNETypeFrame::DistributionSelector - methods
160// ---------------------------------------------------------------------------
161
163 MFXGroupBoxModule(frameParent, TL("Distribution selector")),
164 myFrameParent(frameParent) {
165 // Create MFXComboBoxIcon
168 // DistributionSelector is always shown
169 show();
170}
171
172
174
175
176void
178 myCurrentDistribution = distribution;
179 refreshDistributionSelector();
180}
181
182
185 return myCurrentDistribution;
186
187}
188
189
190void
192 // fill distributions
193 fillDistributionComboBox();
194 // set current item
195 for (int i = 0; i < (int)myDistributionsComboBox->getNumItems(); i++) {
196 if (myDistributionsComboBox->getItemText(i) == myCurrentDistribution->getID()) {
197 myDistributionsComboBox->setCurrentItem(i);
198 }
199 }
200}
201
202
203void
205 // fill distributions
206 const auto distributions = fillDistributionComboBox();
207 // update current distribution (used if myCurrentDistribution was deleted during undo-redo)
208 myCurrentDistribution = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveDemandElement(myCurrentDistribution, false);
209 // update comboBox
210 if (myCurrentDistribution) {
211 for (int i = 0; i < (int)myDistributionsComboBox->getNumItems(); i++) {
212 if (myDistributionsComboBox->getItemText(i) == myCurrentDistribution->getID()) {
213 myDistributionsComboBox->setCurrentItem(i);
214 }
215 }
216 } else if (distributions.size() > 0) {
217 // set first distribution
218 myCurrentDistribution = distributions.begin()->second;
219 }
220 // continue depending of myCurrentDistribution
221 if (myCurrentDistribution) {
222 // show modules
223 myAttributesEditor->showAttributesEditor(myCurrentDistribution, true);
224 myDistributionValuesEditor->showDistributionValuesEditor();
225 } else {
226 // hide modules
227 myAttributesEditor->hideAttributesEditor();
228 myDistributionValuesEditor->hideDistributionValuesEditor();
229 }
230}
231
232
233long
235 const auto viewNet = myFrameParent->getViewNet();
236 const auto& distributions = viewNet->getNet()->getAttributeCarriers()->getDemandElements().at(myDistributionEditor->getDistributionTag());
237 // Check if value of myTypeMatchBox correspond of an allowed additional tags
238 for (const auto& distribution : distributions) {
239 if (distribution.second->getID() == myDistributionsComboBox->getText().text()) {
240 // set pointer
241 myCurrentDistribution = distribution.second;
242 // set color of myTypeMatchBox to black (valid)
243 myDistributionsComboBox->setTextColor(GUIDesignTextColorBlack);
244 // show modules
245 myAttributesEditor->showAttributesEditor(distribution.second, true);
246 myDistributionValuesEditor->showDistributionValuesEditor();
247 // update viewNet
248 viewNet->updateViewNet();
249 return 1;
250 }
251 }
252 // not found, then reset myCurrentDistribution
253 myCurrentDistribution = nullptr;
254 // hide modules
255 myAttributesEditor->hideAttributesEditor();
256 myDistributionValuesEditor->hideDistributionValuesEditor();
257 // set color of myTypeMatchBox to red (invalid)
258 myDistributionsComboBox->setTextColor(GUIDesignTextColorRed);
259 // update viewNet
260 viewNet->updateViewNet();
261 return 1;
262}
263
264
265long
267 const auto& demandElements = myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getDemandElements();
268 if (demandElements.at(myDistributionEditor->getDistributionTag()).size() > 0) {
269 return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), nullptr);
270 } else {
271 return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), nullptr);
272 }
273}
274
275
276std::map<std::string, GNEDemandElement*>
278 // get ACs
279 const auto& ACs = myFrameParent->getViewNet()->getNet()->getAttributeCarriers();
280 // clear items
281 myDistributionsComboBox->clearItems();
282 // fill with distributions sorted by ID
283 std::map<std::string, GNEDemandElement*> distributions;
284 for (const auto& distribution : ACs->getDemandElements().at(myDistributionEditor->getDistributionTag())) {
285 distributions[distribution.second->getID()] = distribution.second;
286 }
287 for (const auto& distribution : distributions) {
288 myDistributionsComboBox->appendIconItem(distribution.first.c_str(), distribution.second->getACIcon());
289 }
290 // return distributions sorted by ID
291 return distributions;
292}
293
294// ---------------------------------------------------------------------------
295// GNEDistributionFrame::DistributionRow - methods
296// ---------------------------------------------------------------------------
297
299 FXHorizontalFrame(attributeEditorParent->getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame),
300 myDistributionValuesEditorParent(attributeEditorParent),
301 myAC(AC) {
302 // get staticTooltip menu
303 auto staticTooltipMenu = attributeEditorParent->getFrameParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
304 // create label
305 myIconLabel = new FXLabel(this, "", AC->getACIcon(), GUIDesignLabelIconThick);
306 // Create and disable MFXTextFieldIcon for string attributes
309 // Create MFXTextFieldIcon for string attributes
311 GUIDesignTextFieldFixedRestricted(50, TEXTFIELD_REAL));
312 // create delete buton
313 myDeleteRowButton = new MFXButtonTooltip(this, staticTooltipMenu,
315 myDeleteRowButton->setTipText(TL("Delete distribution value"));
316 // only create if parent was created
317 if (getParent()->id() && attributeEditorParent->myDistributionSelector->getCurrentDistribution()) {
318 // create DistributionRow
319 FXHorizontalFrame::create();
320 // refresh row
321 refreshRow();
322 // Show DistributionRow
323 show();
324 }
325}
326
327
328void
330 // only destroy if parent was created
331 if (getParent()->id()) {
332 FXHorizontalFrame::destroy();
333 }
334}
335
336
337void
339 myIDTextField->setText(myAC->getAttribute(SUMO_ATTR_REFID).c_str());
340 myProbabilityTextField->setText(myAC->getAttribute(SUMO_ATTR_PROB).c_str());
341}
342
343
344long
346 // finish
347 return 1;
348}
349
350
351long
353 // finish
354 return 1;
355}
356
357// ---------------------------------------------------------------------------
358// GNEDistributionFrame::DistributionValuesEditor - methods
359// ---------------------------------------------------------------------------
360
362 DistributionSelector* distributionSelector, GNEAttributesEditor* attributesEditor) :
363 MFXGroupBoxModule(frameParent, TL("Distribution values")),
364 myFrameParent(frameParent),
365 myDistributionEditor(distributionEditor),
366 myDistributionSelector(distributionSelector),
367 myAttributesEditor(attributesEditor) {
368 // set relations
373 // get staticTooltip menu
374 auto staticTooltipMenu = frameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
375 // Create bot frame elements
378 myAddButton->setTipText(TL("Add new distribution value"));
379 new FXHorizontalFrame(myBotFrame, GUIDesignAuxiliarHorizontalFrame);
381 mySumLabel = new FXLabel(myBotFrame, "", nullptr, GUIDesignLabelThickedFixed(50));
383}
384
385
386void
388 // remake rows
389 refreshRows();
390 // show DistributionValuesEditor
391 show();
392}
393
394
395void
397 // hide also DistributionValuesEditor
398 hide();
399}
400
401
402void
404 // first remove all rows
405 for (auto& row : myDistributionRows) {
406 // destroy and delete all rows
407 if (row != nullptr) {
408 row->destroy();
409 delete row;
410 row = nullptr;
411 }
412 }
413 myDistributionRows.clear();
414 // continue if we have a distribution to edit
415 if (myDistributionSelector->getCurrentDistribution()) {
416 // Iterate over distribution key-values
417 for (const auto& distributionRef : myDistributionSelector->getCurrentDistribution()->getChildDemandElements()) {
418 // create distribution row
419 auto distributionRow = new DistributionRow(this, distributionRef);
420 // add into distribution rows
421 myDistributionRows.push_back(distributionRow);
422 }
423 }
424 // check if enable or disable add button
425 if (myDistributionRows.size() > 0) {
426 myAddButton->enable();
427 } else {
428 myAddButton->disable();
429 }
430 // update sum label
431 updateSumLabel();
432 // reparent bot frame button (to place it at bottom)
433 myBotFrame->reparent(getCollapsableFrame());
434}
435
436
441
442
443void
445 // update probability
446 double sumProbability = 0;
447 for (const auto& distributionRef : myDistributionSelector->getCurrentDistribution()->getChildDemandElements()) {
448 sumProbability += distributionRef->getAttributeDouble(SUMO_ATTR_PROB);
449 }
450 mySumLabel->setText(toString(sumProbability).c_str());
451}
452
453
454long
456 // open distribution dialog
457 GNEDistributionRefDialog distributionDialog(myDistributionSelector->getCurrentDistribution());
458 // only refresh if we added a new row
459 if (distributionDialog.getResult() == GNEDialog::Result::ACCEPT) {
460 refreshRows();
461 }
462 return 1;
463}
464
465/****************************************************************************/
FXDEFMAP(GNEDistributionFrame::DistributionEditor) DistributionEditorMap[]
#define TEMPORAL_FILENAME
@ MID_GNE_DELETE
delete element
Definition GUIAppEnum.h:997
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition GUIAppEnum.h:993
@ MID_GNE_BUTTON_REMOVE
remove button
@ MID_GNE_BUTTON_ADD
add button
@ MID_GNE_CREATE
create element
Definition GUIAppEnum.h:995
@ MID_GNE_SET_TYPE
used to select a type of element in a combo box
#define GUIDesignTextColorRed
red color (for invalid text)
Definition GUIDesigns.h:44
#define GUIDesignLabelFixed(width)
label, icon before text, text centered and custom width
Definition GUIDesigns.h:248
#define GUIDesignButtonIcon
button only with icon
Definition GUIDesigns.h:109
#define GUIDesignButton
Definition GUIDesigns.h:100
#define GUIDesignComboBox
Definition GUIDesigns.h:295
#define GUIDesignTextField
Definition GUIDesigns.h:74
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:430
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:64
#define GUIDesignTextColorBlack
black color (for correct text)
Definition GUIDesigns.h:38
#define GUIDesignTextFieldFixedRestricted(width, type)
text field with fixed width
Definition GUIDesigns.h:83
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:254
#define GUIDesignLabelIconThick
label squared over frame with thick and with text justify to center
Definition GUIDesigns.h:257
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_ATTR_REFID
@ SUMO_ATTR_PROB
int GUIDesignHeight
the default height for GUI elements
Definition StdDefs.cpp:40
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
FXIcon * getACIcon() const
get FXIcon associated to this AC
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
Result getResult() const
get result to indicate if this dialog was closed accepting or rejecting changes
Definition GNEDialog.cpp:96
long onCmdDeleteDistribution(FXObject *, FXSelector, void *)
Called when "Delete distribution" button is clicked.
SumoXMLTag getDistributionTag() const
get distribution tag
long onUpdDeleteDistribution(FXObject *sender, FXSelector, void *)
Called when "Delete distribution" button is updated.
long onCmdCreateDistribution(FXObject *, FXSelector, void *)
Called when "create distribution" button is clicked.
DistributionSelector * myDistributionSelector
distribution selector
void destroy()
destroy DistributionRow (but don't delete)
MFXTextFieldIcon * myProbabilityTextField
textField to modify the probability attribute
long onCmdSetProbability(FXObject *, FXSelector, void *)
try to set new probability
DistributionRow(DistributionValuesEditor *attributeEditorParent, GNEAttributeCarrier *AC)
FOX-declaration.
long onCmdRemoveRow(FXObject *, FXSelector, void *)
remove row
MFXTextFieldIcon * myIDTextField
comboBox with ID
MFXButtonTooltip * myDeleteRowButton
delete row button
GNEDemandElement * getCurrentDistribution() const
current distribution
DistributionValuesEditor * myDistributionValuesEditor
distribution values editor
std::map< std::string, GNEDemandElement * > fillDistributionComboBox()
FOX need this.
long onCmdSelectDistribution(FXObject *, FXSelector, void *)
Called when the user select distribution in ComboBox.
void refreshDistributionIDs()
refresh distribution IDs (only call when user change ID in internal attributes)
MFXComboBoxIcon * myDistributionsComboBox
comboBox with the list of distributions
DistributionEditor * myDistributionEditor
pointer to distribution editor
GNEAttributesEditor * myAttributesEditor
attributes editor
long onCmdUpdateDistribution(FXObject *sender, FXSelector, void *)
update distribution comboBox
void setDistribution(GNEDemandElement *distribution)
refresh modul
DistributionSelector(GNEFrame *frameParent)
constructor
GNEAttributesEditor * myAttributesEditor
attributes editor
DistributionValuesEditor(GNEFrame *frameParent, DistributionEditor *distributionEditor, DistributionSelector *distributionSelector, GNEAttributesEditor *attributesEditor)
constructor
GNEFrame * getFrameParent() const
pointer to GNEFrame parent
DistributionEditor * myDistributionEditor
distribution editor
long onCmdAddRow(FXObject *, FXSelector, void *)
Called when user press the add button.
DistributionSelector * myDistributionSelector
distribution selector
void showDistributionValuesEditor()
show attributes of multiple ACs
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:152
GUIIcon getGUIIcon() const
get GUI icon associated to this tag property
GNEViewParent * getViewParent() const
get the net object
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
virtual void disable()
Disable text field.