Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNETLSEditorFrame.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 modifying traffic lights
19/****************************************************************************/
20
22#include <netbuild/NBOwnTLDef.h>
24#include <netedit/GNENet.h>
26#include <netedit/GNEUndoList.h>
43#include <utils/xml/XMLSubSys.h>
44
45#include "GNETLSEditorFrame.h"
46
47// ===========================================================================
48// FOX callback mapping
49// ===========================================================================
50
59
69
76
83
88
89// Object implementation
90FXIMPLEMENT(GNETLSEditorFrame::TLSJunction, MFXGroupBoxModule, TLSJunctionMap, ARRAYNUMBER(TLSJunctionMap))
91FXIMPLEMENT(GNETLSEditorFrame::TLSPrograms, MFXGroupBoxModule, TLSProgramsMap, ARRAYNUMBER(TLSProgramsMap))
92FXIMPLEMENT(GNETLSEditorFrame::TLSAttributes, MFXGroupBoxModule, TLSAttributesMap, ARRAYNUMBER(TLSAttributesMap))
93FXIMPLEMENT(GNETLSEditorFrame::TLSPhases, MFXGroupBoxModule, TLSPhasesMap, ARRAYNUMBER(TLSPhasesMap))
94FXIMPLEMENT(GNETLSEditorFrame::TLSFile, MFXGroupBoxModule, TLSFileMap, ARRAYNUMBER(TLSFileMap))
95
96
97// ===========================================================================
98// method definitions
99// ===========================================================================
100
102 GNEFrame(viewParent, viewNet, TL("Edit Traffic Light")),
103 myEditedDef(nullptr) {
104
105 // Create Overlapped Inspection module only for junctions
107
108 // create TLSJunction module
110
111 // create TLSPrograms module
113
114 // create TLSAttributes module
116
117 // create TLSPhases module
119
120 // create TLSFile module
122}
123
124
126 myTLSPhases->clearPhaseTable();
127}
128
129
130void
132 myOverlappedInspection->clearOverlappedInspection();
133 // show
135}
136
137
138void
140 // recalc table width
141 myTLSPhases->getPhaseTable()->recalcTableWidth();
142}
143
144
145void
147 if (myTLSJunction) {
148 myTLSJunction->updateTLSJunction();
149 }
150 if (myTLSPrograms) {
151 myTLSPrograms->updateTLSPrograms();
152 }
153 if (myTLSAttributes) {
154 myTLSAttributes->updateTLSAttributes();
155 }
156 if (myTLSPhases) {
157 myTLSPhases->updateTLSPhases();
158 }
159 if (myTLSFile) {
160 myTLSFile->updateTLSFile();
161 }
162 update();
163}
164
165
166void
167GNETLSEditorFrame::editTLS(GNEViewNetHelper::ViewObjectsSelector& viewObjects, const Position& clickedPosition, const bool shiftKeyPressed) {
168 // first check if in viewObjects there is a junction
169 if (viewObjects.getJunctionFront()) {
170 // check if we're adding or removing joined TLSs
171 if (myTLSJunction->isJoiningJunctions()) {
172 myTLSJunction->toggleJunctionSelected(viewObjects.getJunctionFront());
173 } else {
174 // show objects under cursor
175 myOverlappedInspection->showOverlappedInspection(viewObjects, clickedPosition, shiftKeyPressed);
176 // hide if we inspect only one junction
177 if (myOverlappedInspection->getNumberOfOverlappedACs()) {
178 if (myOverlappedInspection->getNumberOfOverlappedACs() == 1) {
179 myOverlappedInspection->hiderOverlappedInspection();
180 }
181 for (const auto& junction : viewObjects.getJunctions()) {
182 if (junction == myOverlappedInspection->getCurrentAC()) {
183 editJunction(junction);
184 }
185 }
186 }
187 }
188 } else if (viewObjects.getAdditionalFront() && myTLSAttributes->isSetDetectorsToggleButtonEnabled() &&
190 myTLSAttributes->toggleE1DetectorSelection(viewObjects.getAdditionalFront());
191 }
192 myViewNet->update();
193}
194
195
196bool
198 if (myTLSPrograms->checkHaveModifications()) {
199 // show question dialog
200 const auto questionDialog = GNEQuestionBasicDialog(myViewNet->getViewParent()->getGNEAppWindows(), GNEDialog::Buttons::YES_NO_CANCEL,
201 TL("Save TLS Changes"),
202 TL("There are unsaved changes in the currently edited traffic light."),
203 TL("Do you want to save it before changing mode?"));
204 // continue depending of result
205 if (questionDialog.getResult() == GNEDialog::Result::ACCEPT) {
206 // save modifications
207 myTLSPrograms->onCmdSaveChanges(nullptr, 0, nullptr);
208 return true;
209 } else if (questionDialog.getResult() == GNEDialog::Result::CANCEL) {
210 // cancel modifications
211 myTLSPrograms->onCmdDiscardChanges(nullptr, 0, nullptr);
212 return true;
213 } else {
214 // abort changing mode
215 return false;
216 }
217 } else {
218 return true;
219 }
220}
221
222
223bool
224GNETLSEditorFrame::parseTLSPrograms(const std::string& file) {
225 NBTrafficLightLogicCont& tllCont = myViewNet->getNet()->getTLLogicCont();
226 NBTrafficLightLogicCont tmpTLLCont;
227 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myViewNet->getNet()->getEdgeCont());
228 // existing definitions must be available to update their programs
229 std::set<NBTrafficLightDefinition*> origDefs;
230 for (NBTrafficLightDefinition* def : tllCont.getDefinitions()) {
231 // make a duplicate of every program
232 NBTrafficLightLogic* logic = tllCont.getLogic(def->getID(), def->getProgramID());
233 if (logic != nullptr) {
234 NBTrafficLightDefinition* duplicate = new NBLoadedSUMOTLDef(*def, *logic);
235 std::vector<NBNode*> nodes = def->getNodes();
236 for (auto it_node : nodes) {
237 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
238 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, false, false), true);
239 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, duplicate, true), true);
240 }
241 tmpTLLCont.insert(duplicate);
242 origDefs.insert(duplicate);
243 } else {
244 WRITE_WARNINGF(TL("tlLogic '%', program '%' could not be built"), def->getID(), def->getProgramID());
245 }
246 }
247 //std::cout << " initialized tmpCont with " << origDefs.size() << " defs\n";
248 XMLSubSys::runParser(tllHandler, file);
249
250 std::vector<NBLoadedSUMOTLDef*> loadedTLS;
251 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
252 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
253 if (sdef != nullptr) {
254 loadedTLS.push_back(sdef);
255 }
256 }
257 myViewNet->setStatusBarText(TL("Loaded ") + toString(loadedTLS.size()) + TL(" programs"));
258 for (auto def : loadedTLS) {
259 if (origDefs.count(def) != 0) {
260 // already add to undolist before
261 //std::cout << " skip " << def->getDescription() << "\n";
262 continue;
263 }
264 std::vector<NBNode*> nodes = def->getNodes();
265 //std::cout << " add " << def->getDescription() << " for nodes=" << toString(nodes) << "\n";
266 for (auto it_node : nodes) {
267 GNEJunction* junction = myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
268 //myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, false), true);
269 myViewNet->getUndoList()->add(new GNEChange_TLS(junction, def, true), true);
270 }
271 }
272 // clean up temporary container to avoid deletion of defs when its destruct is called
273 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
274 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
275 }
276 return true;
277}
278
279
280void
282 auto junction = dynamic_cast<GNEJunction*>(AC);
283 if (junction) {
284 editJunction(junction);
285 }
286}
287
288
289void
291 if (myTLSJunction->getCurrentJunction()) {
292 myTLSJunction->getCurrentJunction()->selectTLS(false);
293 if (myTLSPrograms->getNumberOfPrograms() > 0) {
294 for (const auto& node : myTLSPrograms->getCurrentTLSPrograms()->getNodes()) {
295 myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(node->getID())->selectTLS(false);
296 }
297 }
298 }
299 // clean data structures
300 myTLSJunction->setCurrentJunction(nullptr);
301 // check if delete myEditedDef
302 if (myEditedDef) {
303 delete myEditedDef;
304 myEditedDef = nullptr;
305 }
306 // clear internal lanes
307 buildInternalLanes(nullptr);
308 // clean up attributes
309 myTLSPrograms->clearTLSProgramss();
310 // clean up attributes
311 myTLSAttributes->clearTLSAttributes();
312 // only clears when there are no definitions
313 myTLSPhases->initPhaseTable();
314}
315
316
321
322
327
328
333
334
339
340
341void
343 // clean up previous internal lanes
344 for (const auto& internalLanes : myInternalLanes) {
345 for (const auto& internalLane : internalLanes.second) {
346 // remove internal lane from ACs
347 myViewNet->getNet()->getAttributeCarriers()->deleteInternalLane(internalLane);
348 // delete internal lane
349 delete internalLane;
350 }
351 }
352 // clear container
353 myInternalLanes.clear();
354 // create new internal lanes
355 if (tlDef != nullptr) {
356 const int NUM_POINTS = 10;
357 const NBNode* nbnCurrentJunction = myTLSJunction->getCurrentJunction()->getNBNode();
358 // get innerID NWWriter_SUMO::writeInternalEdges
359 const std::string innerID = ":" + nbnCurrentJunction->getID();
360 const NBConnectionVector& links = tlDef->getControlledLinks();
361 // iterate over links
362 for (const auto& link : links) {
363 int tlIndex = link.getTLIndex();
364 PositionVector shape;
365 try {
366 const NBEdge::Connection& con = link.getFrom()->getConnection(link.getFromLane(), link.getTo(), link.getToLane());
367 shape = con.shape;
368 shape.append(con.viaShape);
369 } catch (ProcessError&) {
370 shape = link.getFrom()->getToNode()->computeInternalLaneShape(link.getFrom(), NBEdge::Connection(link.getFromLane(),
371 link.getTo(), link.getToLane()), NUM_POINTS);
372 }
373 if (shape.length() < 2) {
374 // enlarge shape to ensure visibility
375 shape.clear();
376 const PositionVector laneShapeFrom = link.getFrom()->getLaneShape(link.getFromLane());
377 const PositionVector laneShapeTo = link.getTo()->getLaneShape(link.getToLane());
378 shape.push_back(laneShapeFrom.positionAtOffset(MAX2(0.0, laneShapeFrom.length() - 1)));
379 shape.push_back(laneShapeTo.positionAtOffset(MIN2(1.0, laneShapeFrom.length())));
380 }
381 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), innerID + '_' + toString(tlIndex), shape, tlIndex);
382 // add into atribute carriers
383 myViewNet->getNet()->getAttributeCarriers()->insertInternalLane(internalLane);
384 myInternalLanes[tlIndex].push_back(internalLane);
385 }
386 // iterate over crossings
387 for (const auto& nbn : tlDef->getNodes()) {
388 for (const auto& crossing : nbn->getCrossings()) {
389 if (crossing->tlLinkIndex2 > 0 && crossing->tlLinkIndex2 != crossing->tlLinkIndex) {
390 // draw both directions
391 PositionVector forward = crossing->shape;
392 forward.move2side(crossing->width / 4);
393 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, forward, crossing->tlLinkIndex);
394 // add into atribute carriers
395 myViewNet->getNet()->getAttributeCarriers()->insertInternalLane(internalLane);
396 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
397 PositionVector backward = crossing->shape.reverse();
398 backward.move2side(crossing->width / 4);
399 GNEInternalLane* internalLaneReverse = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id + "_r", backward, crossing->tlLinkIndex2);
400 // add into atribute carriers
401 myViewNet->getNet()->getAttributeCarriers()->insertInternalLane(internalLaneReverse);
402 myInternalLanes[crossing->tlLinkIndex2].push_back(internalLaneReverse);
403 } else {
404 // draw only one lane for both directions
405 GNEInternalLane* internalLane = new GNEInternalLane(this, myTLSJunction->getCurrentJunction(), crossing->id, crossing->shape, crossing->tlLinkIndex);
406 // add into atribute carriers
407 myViewNet->getNet()->getAttributeCarriers()->insertInternalLane(internalLane);
408 myInternalLanes[crossing->tlLinkIndex].push_back(internalLane);
409 }
410 }
411 }
412 }
413}
414
415
416std::string
420
421
424 if ((index >= 0) || (index < (int)myEditedDef->getLogic()->getPhases().size())) {
425 return myEditedDef->getLogic()->getPhases().at(index);
426 } else {
427 throw ProcessError(TL("Invalid phase index"));
428 }
429}
430
431
432void
434 myTLSPrograms->markAsModified();
435 // get current selected row
436 const auto selectedRow = myTLSPhases->getPhaseTable()->getCurrentSelectedRow();
437 if (myViewNet->changeAllPhases()) {
438 for (int row = 0; row < (int)myEditedDef->getLogic()->getPhases().size(); row++) {
439 myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
440 }
441 } else {
442 myEditedDef->getLogic()->setPhaseState(myTLSPhases->getPhaseTable()->getCurrentSelectedRow(), lane->getTLIndex(), lane->getLinkState());
443 }
444 // init phaseTable
445 myTLSPhases->initPhaseTable();
446 // select row
447 myTLSPhases->getPhaseTable()->selectRow(selectedRow);
448 // focus table
449 myTLSPhases->getPhaseTable()->setFocus();
450}
451
452
453void
454GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* eventData) {
455 if (myEditedDef != nullptr) {
456 myTLSPrograms->markAsModified();
457 const NBConnectionVector& links = myEditedDef->getControlledLinks();
458 std::set<std::string> fromIDs;
459 fromIDs.insert(lane->getMicrosimID());
460 // if neither the lane nor its edge are selected, apply changes to the whole edge
462 for (auto it_lane : lane->getParentEdge()->getChildLanes()) {
463 fromIDs.insert(it_lane->getMicrosimID());
464 }
465 } else {
466 // if the edge is selected, apply changes to all lanes of all selected edges
468 const auto selectedEdge = myViewNet->getNet()->getAttributeCarriers()->getSelectedEdges();
469 for (const auto& edge : selectedEdge) {
470 for (auto it_lane : edge->getChildLanes()) {
471 fromIDs.insert(it_lane->getMicrosimID());
472 }
473 }
474 }
475 // if the lane is selected, apply changes to all selected lanes
476 if (lane->isAttributeCarrierSelected()) {
477 const auto selectedLanes = myViewNet->getNet()->getAttributeCarriers()->getSelectedLanes();
478 for (auto it_lane : selectedLanes) {
479 fromIDs.insert(it_lane->getMicrosimID());
480 }
481 }
482
483 }
484 // set new state for all connections from the chosen lane IDs
485 for (auto it : links) {
486 if (fromIDs.count(it.getFrom()->getLaneID(it.getFromLane())) > 0) {
487 std::vector<GNEInternalLane*> lanes = myInternalLanes[it.getTLIndex()];
488 for (auto it_lane : lanes) {
489 it_lane->onDefault(obj, sel, eventData);
490 }
491 }
492 }
493 }
494}
495
496
497bool
499 if (myEditedDef != nullptr) {
500 const NBConnectionVector& links = myEditedDef->getControlledLinks();
501 for (auto it : links) {
502 if (it.getFrom()->getID() == edge->getMicrosimID()) {
503 return true;
504 }
505 }
506 }
507 return false;
508}
509
510
511void
513 if ((myTLSJunction->getCurrentJunction() == nullptr) || (!myTLSPrograms->checkHaveModifications() && (junction != myTLSJunction->getCurrentJunction()))) {
514 // discard previous changes
515 myTLSPrograms->discardChanges(false);
516 // set junction
517 myTLSJunction->setCurrentJunction(junction);
518 // init TLS definitions
519 if (myTLSPrograms->initTLSPrograms()) {
520 // init TLSAttributes
521 myTLSAttributes->initTLSAttributes();
522 // begin undo-list
523 myViewNet->getUndoList()->begin(GUIIcon::MODETLS, TL("modifying TLS definition"));
524 // only select TLS if getCurrentJunction exist
525 if (myTLSJunction->getCurrentJunction()) {
526 myTLSJunction->getCurrentJunction()->selectTLS(true);
527 }
528 if (myTLSPrograms->getNumberOfPrograms() > 0) {
529 for (NBNode* node : myTLSPrograms->getCurrentTLSPrograms()->getNodes()) {
530 myViewNet->getNet()->getAttributeCarriers()->retrieveJunction(node->getID())->selectTLS(true);
531 }
532 // update color
533 myTLSPhases->updateTLSColoring();
534 }
535 }
536 } else {
537 myViewNet->setStatusBarText(TL("Unsaved modifications. Abort or Save"));
538 }
540}
541
542
544GNETLSEditorFrame::getSUMOTime(const std::string& string) {
546}
547
548const std::string
552
553// ---------------------------------------------------------------------------
554// GNETLSEditorFrame::TLSAttributes - methods
555// ---------------------------------------------------------------------------
556
558 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light Attributes")),
559 myTLSEditorParent(TLSEditorParent) {
560 // create frame, label and TextField for Offset (By default disabled)
561 FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
562 new FXLabel(horizontalFrame, toString(SUMO_ATTR_OFFSET).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
564 myOffsetTextField->disable();
565 // create frame, label and TextField for parameters (By default disabled)
566 horizontalFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
569 myButtonEditParameters->disable();
570 myParametersTextField->disable();
571 // create set detectors button (By default disabled)
574 TL("Assign E1 detectors") + std::string("\t") + TL("Enable assign E1 mode") + std::string("\t") + TL("Assign E1 detectors to the current TLS"),
575 TL("Assign E1 detectors") + std::string("\t") + TL("Disable assign E1 mode") + std::string("\t") + TL("Assign E1 detectors to the current TLS"),
579}
580
581
583
584
585void
587 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
588 // no TLS programs, disable elements
589 myOffsetTextField->disable();
590 myButtonEditParameters->disable();
591 myParametersTextField->disable();
592 // disable E1 detector mode
595 // clear E1 detectors
596 if (myE1Detectors.size() > 0) {
597 myE1Detectors.clear();
598 myTLSEditorParent->getViewNet()->update();
599 }
600 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
601 // joining TLSs, disable button
602 myOffsetTextField->disable();
603 myButtonEditParameters->disable();
604 myParametersTextField->disable();
605 // disable E1 detector mode
608 // clear E1 detectors
609 if (myE1Detectors.size() > 0) {
610 myE1Detectors.clear();
611 myTLSEditorParent->getViewNet()->update();
612 }
614 // set detectors toggle button is enabled, disable elements
615 myOffsetTextField->disable();
616 myButtonEditParameters->disable();
617 myParametersTextField->disable();
618 } else {
619 myOffsetTextField->enable();
620 myButtonEditParameters->enable();
621 myParametersTextField->enable();
622 // disable E1 detector mode in static
623 if (myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms()->getType() != TrafficLightType::ACTUATED) {
624 // disable E1 detector mode
627 // clear E1 detectors
628 if (myE1Detectors.size() > 0) {
629 myE1Detectors.clear();
630 myTLSEditorParent->getViewNet()->update();
631 }
632 } else {
634 }
635 }
636}
637
638
639void
643
644
645void
649
650
651void
653 // get current edited junction
654 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
655 if (junction == nullptr) {
656 throw ProcessError("Junction cannot be NULL");
657 } else {
658 // enable Offset
659 myOffsetTextField->enable();
661 // enable parameters
662 myButtonEditParameters->enable();
663 myParametersTextField->enable();
665 // reset mySetDetectorsToggleButton
667 }
668}
669
670
671void
673 // clear and disable Offset TextField
674 myOffsetTextField->setText("");
675 myOffsetTextField->disable();
677 // clear and disable parameters TextField
678 myButtonEditParameters->disable();
679 myParametersTextField->setText("");
680 myParametersTextField->disable();
682}
683
684
689
690
691void
696
697
698bool
702 return true;
703 } else {
705 return false;
706 }
707}
708
709
710std::string
714
715
716void
718 myParametersTextField->setText(parameters.c_str());
720 // update E1 detectors
721 if (myTLSEditorParent->myEditedDef->getType() != TrafficLightType::STATIC) {
723 }
724}
725
726
727bool
737
738
739bool
743
744
745bool
747 // get E1 lane ID
748 const auto laneID = E1->getParentLanes().front()->getID();
749 // iterate over all E1 detectors
750 for (auto it = myE1Detectors.begin(); it != myE1Detectors.end(); it++) {
751 if (E1->getID() == it->second) {
752 // already selected, then remove it from detectors
753 myE1Detectors.erase(it);
754 // and remove it from parameters
755 myTLSEditorParent->myEditedDef->unsetParameter(laneID);
756 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
757 // mark TL as modified
758 myTLSEditorParent->myTLSPrograms->markAsModified();
759 return true;
760 } else if (laneID == it->first) {
761 // there is another E1 in the same lane, then swap
762 myE1Detectors.erase(it);
763 myE1Detectors[laneID] = E1->getID();
764 // also in parameters
765 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
766 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
767 // mark TL as modified
768 myTLSEditorParent->myTLSPrograms->markAsModified();
769 return true;
770 }
771 }
772 // add it in parameters
773 myE1Detectors[laneID] = E1->getID();
774 myTLSEditorParent->myEditedDef->setParameter(laneID, E1->getID());
775 myParametersTextField->setText(myTLSEditorParent->myEditedDef->getParametersStr().c_str());
776 // mark TL as modified
777 myTLSEditorParent->myTLSPrograms->markAsModified();
778 return true;
779}
780
781
782const std::map<std::string, std::string>&
786
787
788void
792
793
794long
796 if (isValidOffset()) {
797 myTLSEditorParent->myTLSPrograms->markAsModified();
798 myTLSEditorParent->myEditedDef->setOffset(getOffset());
799 myOffsetTextField->killFocus();
800 myTLSEditorParent->updateModules();
801 }
802 return 1;
803}
804
805
806long
808 if (isValidParameters()) {
809 myTLSEditorParent->myTLSPrograms->markAsModified();
810 myTLSEditorParent->myEditedDef->setParametersStr(getParameters());
811 myParametersTextField->killFocus();
812 myTLSEditorParent->updateModules();
813 }
814 return 1;
815}
816
817
818long
820 // continue depending of myEditedDef
821 if (myTLSEditorParent->myEditedDef) {
822 // get previous parameters
823 const auto previousParameters = getParameters();
824 // open parameters dialog
825 const auto parametersDialog = GNEParametersDialog(myTLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows(),
826 myTLSEditorParent->myEditedDef->getParametersMap());
827 // continue depending of result
828 if (parametersDialog.getResult() == GNEDialog::Result::ACCEPT) {
829 // set parameters in myEditedDef
830 myTLSEditorParent->myEditedDef->setParameters(parametersDialog.getEditedParameters());
831 // set parameters in textfield
832 setParameters(myTLSEditorParent->myEditedDef->getParametersStr());
833 // only mark as modified if parameters are different
834 if (getParameters() != previousParameters) {
835 myTLSEditorParent->myTLSPrograms->markAsModified();
836 }
837 }
838 myTLSEditorParent->updateModules();
839 }
840 return 1;
841}
842
843
844long
846 if (mySetDetectorsToggleButton->getState()) {
847 // set special color
848 mySetDetectorsToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
849 } else {
850 // restore default color
851 mySetDetectorsToggleButton->setBackColor(4293980400);
852 }
853 myTLSEditorParent->updateModules();
854 // update view
855 myTLSEditorParent->getViewNet()->update();
856 return 1;
857}
858
859
860void
862 // first clear E1 detectors
863 myE1Detectors.clear();
864 // iterate over parameters
865 for (const auto& parameter : myTLSEditorParent->myEditedDef->getParametersMap()) {
866 // check if both lane and E1 exists
867 if (myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveLane(parameter.first, false) &&
868 myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_INDUCTION_LOOP, parameter.second, false)) {
869 // add it into list
870 myE1Detectors[parameter.first] = parameter.second;
871 }
872 }
873 myTLSEditorParent->updateModules();
874 // update view net
875 myTLSEditorParent->getViewNet()->update();
876}
877
878// ---------------------------------------------------------------------------
879// GNETLSEditorFrame::TLSJunction - methods
880// ---------------------------------------------------------------------------
881
883 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light")),
884 myTLSEditorParent(TLSEditorParent),
885 myCurrentJunction(nullptr) {
886 const auto staticTooltip = TLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
887 // Create frame for junction IDs
888 FXHorizontalFrame* junctionIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
889 myJunctionIDLabel = new FXLabel(junctionIDFrame, TL("Junction ID"), nullptr, GUIDesignLabelThickedFixed(100));
890 myJunctionIDTextField = new MFXTextFieldIcon(junctionIDFrame, staticTooltip, GUIIcon::EMPTY, nullptr, 0, GUIDesignTextField);
891 // junction ID remains always disabled
892 myJunctionIDTextField->disable();
893 // Create frame for TLS Program ID
894 FXHorizontalFrame* TLSIDFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
895 new FXLabel(TLSIDFrame, TL("TLS ID"), nullptr, GUIDesignLabelThickedFixed(100));
897 // create frame, label and textfield for type
898 FXHorizontalFrame* typeFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
899 new FXLabel(typeFrame, toString(SUMO_ATTR_TYPE).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
900 myTLSTypeComboBox = new MFXComboBoxIcon(typeFrame, staticTooltip, false, GUIDesignComboBoxVisibleItems,
902 // fill comboBox (only certain TL types)
903 myTLSTypeComboBox->appendIconItem(toString(TrafficLightType::STATIC).c_str());
904 myTLSTypeComboBox->appendIconItem(toString(TrafficLightType::ACTUATED).c_str());
906 myTLSTypeComboBox->appendIconItem(toString(TrafficLightType::NEMA).c_str());
907 // create frame for join buttons
908 FXHorizontalFrame* joinButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
909 // create join states button
910 myJoinTLSToggleButton = new MFXToggleButtonTooltip(joinButtons, staticTooltip,
911 TL("Join") + std::string("\t") + TL("Enable join mode") + std::string("\t") + TL("Join TLS and junctions in the current junction."),
912 TL("Join") + std::string("\t") + TL("Disable join mode") + std::string("\t") + TL("Join TLS and junctions in the current junction."),
915 myDisjoinTLSButton = new MFXButtonTooltip(joinButtons, staticTooltip,
916 TL("Disjoin") + std::string("\t") + TL("Disjoin current TLS") + std::string("\t") + TL("Disjoin current TLS."),
918 // create frame for join control buttons
920 // create create tlDef button
921 GUIDesigns::buildFXButton(myJoinControlButtons, TL("Accept"), "", TL("Finish join."),
923 GUIDesigns::buildFXButton(myJoinControlButtons, TL("Cancel"), "", TL("Cancel Join."),
925 // update junction description after creation
927 // show TLS Junction
928 show();
929}
930
931
933
934
935void
937 if ((myCurrentJunction == nullptr) ||
938 (myCurrentJunction->getNBNode()->getControllingTLS().size() == 0)) {
939 // no TLS
940 myJunctionIDTextField->setText(TL("No junction selected"));
941 myTLSIDTextField->setText("");
942 myTLSIDTextField->disable();
943 myTLSTypeComboBox->disable();
944 myJoinTLSToggleButton->disable();
945 myDisjoinTLSButton->disable();
946 myJoinControlButtons->hide();
947 } else {
948 // get first controled TLS
949 const auto TLS = (*myCurrentJunction->getNBNode()->getControllingTLS().begin());
950 // set TLS type in comboBox
951 const int index = myTLSTypeComboBox->findItem(myCurrentJunction->getAttribute(SUMO_ATTR_TLTYPE).c_str());
952 if (index != -1) {
953 myTLSTypeComboBox->setCurrentItem(index, FALSE);
954 }
955 // set text field IDs
956 myJunctionIDTextField->setText(myCurrentJunction->getID().c_str());
957 myTLSIDTextField->setText(TLS->getID().c_str());
958 // continue with more options
959 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled() ||
960 myTLSEditorParent->myTLSPrograms->checkHaveModifications()) {
961 // disable if selecting selecting detectors or we modified the program
962 myTLSIDTextField->setText("");
963 myTLSIDTextField->disable();
964 myTLSTypeComboBox->disable();
965 myJoinTLSToggleButton->disable();
966 myDisjoinTLSButton->disable();
967 myJoinControlButtons->hide();
968 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
969 // partial disable due joining
970 myTLSIDTextField->setText("");
971 myTLSIDTextField->disable();
972 myTLSTypeComboBox->disable();
973 myDisjoinTLSButton->disable();
974 // enable join TLS and show control buttons
975 myJoinTLSToggleButton->enable();
976 myJoinControlButtons->show();
977 } else {
978 // enable
979 myTLSIDTextField->enable();
980 myTLSTypeComboBox->enable();
981 myJoinTLSToggleButton->enable();
982 // disjoint button only if we have more than one TLS controlled
983 if (TLS->getNodes().size() == 1) {
984 myDisjoinTLSButton->disable();
985 } else {
986 myDisjoinTLSButton->enable();
987 }
988 }
989 }
990}
991
992
997
998
999void
1001 myCurrentJunction = junction;
1002 // resfresh module
1004}
1005
1006
1007bool
1009 return (myJoinTLSToggleButton->getState() == TRUE);
1010}
1011
1012
1013bool
1015 return (std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID()) != mySelectedJunctionIDs.end());
1016}
1017
1018
1019void
1021 // avoid current junction
1022 if (junction != myCurrentJunction) {
1023 // find ID in selected junctions
1024 auto it = std::find(mySelectedJunctionIDs.begin(), mySelectedJunctionIDs.end(), junction->getID());
1025 // check if add or remove
1026 if (it == mySelectedJunctionIDs.end()) {
1027 mySelectedJunctionIDs.push_back(junction->getID());
1028 } else {
1029 mySelectedJunctionIDs.erase(it);
1030 }
1031 }
1032}
1033
1034
1035const std::vector<std::string>&
1039
1040
1041long
1043 // get IDs
1044 const std::string currentTLID = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getID();
1045 const std::string newTLID = myTLSIDTextField->getText().text();
1046 // check if ID is valid
1047 if (newTLID.empty() || (newTLID == currentTLID)) {
1048 // same ID or empty
1050 myTLSIDTextField->setText(currentTLID.c_str());
1051 myTLSIDTextField->killFocus();
1052 myTLSEditorParent->update();
1053 // show all moduls
1054 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1055 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1056 myTLSEditorParent->myTLSPhases->showTLSPhases();
1057 myTLSEditorParent->myTLSFile->showTLSFile();
1058 } else if (!SUMOXMLDefinitions::isValidNetID(newTLID) || myCurrentJunction->getNet()->getTLLogicCont().exist(newTLID)) {
1059 // set invalid color
1061 // hide moduls
1062 myTLSEditorParent->myTLSPrograms->hideTLSPrograms();
1063 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1064 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1065 myTLSEditorParent->myTLSFile->hideTLSFile();
1066 } else {
1067 // make a copy of myCurrentJunction and current tlDef (because will be reset after calling discardChanges)
1068 auto junction = myCurrentJunction;
1069 const auto tlDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1070 // restore color
1072 myTLSIDTextField->killFocus();
1073 myTLSEditorParent->update();
1074 // discard previous changes
1075 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1076 // change name using undo-List
1077 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("rename TLS"));
1078 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, tlDef, newTLID), true);
1079 myTLSEditorParent->getViewNet()->getUndoList()->end();
1080 // show all moduls
1081 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1082 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1083 myTLSEditorParent->myTLSPhases->showTLSPhases();
1084 myTLSEditorParent->myTLSFile->showTLSFile();
1085 // edit junction again
1086 myTLSEditorParent->editJunction(junction);
1087 }
1088 myTLSEditorParent->updateModules();
1089 return 1;
1090}
1091
1092
1093long
1095 // get IDs
1096 const std::string currentTLType = toString((*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getType());
1097 const std::string newTLType = myTLSTypeComboBox->getText().text();
1098 // check if ID is valid
1099 if (newTLType.empty() || (newTLType == currentTLType)) {
1100 // same ID or empty, don't change
1102 // set value
1103 const int index = myTLSTypeComboBox->findItem(currentTLType.c_str());
1104 if (index == -1) {
1105 myTLSTypeComboBox->disable();
1106 } else {
1107 myTLSTypeComboBox->setCurrentItem(index);
1108 myTLSTypeComboBox->enable();
1109 }
1110 myTLSTypeComboBox->killFocus();
1111 myTLSEditorParent->update();
1112 // show all moduls
1113 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1114 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1115 myTLSEditorParent->myTLSPhases->showTLSPhases();
1116 myTLSEditorParent->myTLSFile->showTLSFile();
1117 } else if (!SUMOXMLDefinitions::TrafficLightTypes.hasString(newTLType)) {
1118 // set invalid color
1120 // hide moduls
1121 myTLSEditorParent->myTLSPrograms->hideTLSPrograms();
1122 myTLSEditorParent->myTLSAttributes->hideTLSAttributes();
1123 myTLSEditorParent->myTLSPhases->hideTLSPhases();
1124 myTLSEditorParent->myTLSFile->hideTLSFile();
1125 } else {
1126 // reset color
1128 myTLSTypeComboBox->killFocus();
1129 myTLSEditorParent->update();
1130 // make a copy of myCurrentJunction (because will be reset after calling discardChanges)
1131 auto junction = myCurrentJunction;
1132 // discard previous changes
1133 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1134 // change name using undo-List
1135 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("change TLS type"));
1136 junction->setAttribute(SUMO_ATTR_TLTYPE, newTLType, myTLSEditorParent->getViewNet()->getUndoList());
1137 myTLSEditorParent->getViewNet()->getUndoList()->end();
1138 // show all moduls
1139 myTLSEditorParent->myTLSPrograms->showTLSPrograms();
1140 myTLSEditorParent->myTLSAttributes->showTLSAttributes();
1141 myTLSEditorParent->myTLSPhases->showTLSPhases();
1142 myTLSEditorParent->myTLSFile->showTLSFile();
1143 // edit junction again
1144 myTLSEditorParent->editJunction(junction);
1145 }
1146 myTLSEditorParent->updateModules();
1147 return 1;
1148
1149}
1150
1151
1152long
1154 if (myJoinTLSToggleButton->getState()) {
1155 // set special color
1156 myJoinTLSToggleButton->setBackColor(FXRGBA(253, 255, 206, 255));
1157 // clear and fill mySelectedJunctionIDs
1158 mySelectedJunctionIDs.clear();
1159 // get all nodes controlled by this TLS
1160 const auto TLNodes = (*myCurrentJunction->getNBNode()->getControllingTLS().begin())->getNodes();
1161 // fill mySelectedJunctionIDs with TLNodes
1162 mySelectedJunctionIDs.clear();
1163 for (const auto& TLNode : TLNodes) {
1164 mySelectedJunctionIDs.push_back(TLNode->getID());
1165 }
1166 // make a copy of selected junctions
1168 // show control buttons
1169 myJoinControlButtons->show();
1170 getCollapsableFrame()->recalc();
1171 } else {
1172 // hide control buttons
1173 myJoinControlButtons->hide();
1174 getCollapsableFrame()->recalc();
1175 // make a copy of current junction
1176 const auto currentJunction = myCurrentJunction;
1177 // declare vectors for junctions
1178 std::vector<GNEJunction*> selectedJunctions, resetTLJunctions;
1179 // get selected junctions (all except current
1180 for (const auto& selectedJunctionID : mySelectedJunctionIDs) {
1181 if (selectedJunctionID != currentJunction->getID()) {
1182 selectedJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(selectedJunctionID));
1183 }
1184 }
1185 // get junctions to reset TL (all TL nodes except current)
1186 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1187 if (TLNBNode != currentJunction->getNBNode()) {
1188 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1189 }
1190 }
1191 // discard changes
1192 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1193 // begin undo list
1194 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("join TLS"));
1195 // remove tl from TLNBNode
1196 for (const auto& resetTLJunction : resetTLJunctions) {
1197 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1198 }
1199 // now update it in all joined junctions
1200 for (const auto& selectedJunction : selectedJunctions) {
1201 selectedJunction->setAttribute(SUMO_ATTR_TYPE, currentJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1202 selectedJunction->setAttribute(SUMO_ATTR_TLID, currentJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1203 }
1204 // end undo list
1205 myTLSEditorParent->getViewNet()->getUndoList()->end();
1206 // restore default color
1207 myJoinTLSToggleButton->setBackColor(4293980400);
1208 // clear selected junction IDs
1209 mySelectedJunctionIDs.clear();
1210 // edit junction again
1211 myTLSEditorParent->editJunction(currentJunction);
1212 }
1213 myTLSEditorParent->updateModules();
1214 // update view
1215 myTLSEditorParent->getViewNet()->update();
1216 return 1;
1217}
1218
1219
1220long
1222 // make a copy of current junction
1223 const auto currentJunction = myCurrentJunction;
1224 // declare vectors for junctions
1225 std::vector<GNEJunction*> resetTLJunctions;
1226 // get junctions to reset TL
1227 for (const auto& TLNBNode : (*currentJunction->getNBNode()->getControllingTLS().begin())->getNodes()) {
1228 resetTLJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLNBNode->getID()));
1229 }
1230 // save TL types
1231 const auto type = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TYPE);
1232 const auto tlType = resetTLJunctions.front()->getAttribute(SUMO_ATTR_TLTYPE);
1233 // discard changes
1234 myTLSEditorParent->myTLSPrograms->discardChanges(false);
1235 // begin undo list
1236 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("disjoin TLS"));
1237 // the disjoint tlIds will be the junction ids. Ensure that there is no name clash with the current tlId
1238 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1239 const std::string oldId = currentJunction->getAttribute(SUMO_ATTR_TLID);
1240 const std::string tmpIdBase = oldId + "_TMP";
1241 int tmpIndex = 0;
1242 std::string tmpId = tmpIdBase + toString(tmpIndex);
1243 while (tllCont.exist(tmpId)) {
1244 tmpId = tmpIdBase + toString(++tmpIndex);
1245 }
1246 for (NBTrafficLightDefinition* tlDef : currentJunction->getNBNode()->getControllingTLS()) {
1247 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(currentJunction, tlDef, tmpId), true);
1248 }
1249 // remove tl from TLNBNode and the re-initialize as single traffic light
1250 for (const auto& resetTLJunction : resetTLJunctions) {
1251 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, "priority", myTLSEditorParent->getViewNet()->getUndoList());
1252 resetTLJunction->setAttribute(SUMO_ATTR_TYPE, type, myTLSEditorParent->getViewNet()->getUndoList());
1253 resetTLJunction->setAttribute(SUMO_ATTR_TLTYPE, tlType, myTLSEditorParent->getViewNet()->getUndoList());
1254 }
1255 // end undo list
1256 myTLSEditorParent->getViewNet()->getUndoList()->end();
1257 // restore default color
1258 myJoinTLSToggleButton->setBackColor(4293980400);
1259 // clear selected junction IDs
1260 mySelectedJunctionIDs.clear();
1261 // edit junction again
1262 myTLSEditorParent->editJunction(currentJunction);
1263 myTLSEditorParent->updateModules();
1264 return 1;
1265}
1266
1267
1268long
1270 myJoinTLSToggleButton->setState(FALSE, TRUE);
1271 myTLSEditorParent->updateModules();
1272 return 1;
1273}
1274
1275
1276long
1278 // restore selected junction
1280 myJoinTLSToggleButton->setState(FALSE, TRUE);
1281 myTLSEditorParent->updateModules();
1282 return 1;
1283}
1284
1285
1286void
1288 // first reset junction label
1289 myJunctionIDLabel->setText(TL("Junction ID"));
1290 // clear selected junctions
1291 mySelectedJunctionIDs.clear();
1292 // cancel joining junction mode
1293 onCmdCancelJoin(nullptr, 0, nullptr);
1294 // continue depending of current junction
1295 if (myCurrentJunction == nullptr) {
1296 myJunctionIDTextField->setText(TL("No junction selected"));
1297 } else {
1298 // get all TLS assigned to this node
1299 const auto& TLSs = myCurrentJunction->getNBNode()->getControllingTLS();
1300 // check if junction is controlled
1301 if (TLSs.size() > 0) {
1302 // get first TLS
1303 const auto TLS = (*TLSs.begin());
1304 // update junction ID text field
1305 if (TLS->getNodes().size() > 1) {
1306 // declare string
1307 std::string TLSNodesStr;
1308 for (auto it = TLS->getNodes().begin(); it != TLS->getNodes().end(); it++) {
1309 if (it == (TLS->getNodes().end() - 1)) {
1310 TLSNodesStr += (*it)->getID();
1311 } else {
1312 TLSNodesStr += (*it)->getID() + ", ";
1313 }
1314 }
1315 // updated junction fields
1316 myJunctionIDTextField->setText(TLSNodesStr.c_str());
1317 // update junction label if we have multiple nodes
1318 if (TLS->getNodes().size() > 1) {
1319 myJunctionIDLabel->setText(TL("Junction IDs"));
1320 }
1321 // set TLS type in comboBox
1322 const int index = myTLSTypeComboBox->findItem(myCurrentJunction->getAttribute(SUMO_ATTR_TLTYPE).c_str());
1323 if (index != -1) {
1324 myTLSTypeComboBox->setCurrentItem(index, FALSE);
1325 }
1326 }
1327 } else {
1328 // update junction ID text field
1329 myJunctionIDTextField->setText(myCurrentJunction->getID().c_str());
1330 myTLSTypeComboBox->setCurrentItem(0, FALSE);
1331 }
1332 }
1333 // update TLS junction
1335}
1336
1337// ---------------------------------------------------------------------------
1338// GNETLSEditorFrame::TLSPrograms - methods
1339// ---------------------------------------------------------------------------
1340
1342 MFXGroupBoxModule(TLSEditorParent, TL("Traffic Light Programs")),
1343 myTLSEditorParent(TLSEditorParent) {
1344 // create frame, label and comboBox for programID
1345 FXHorizontalFrame* programFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1346 new FXLabel(programFrame, toString(SUMO_ATTR_PROGRAMID).c_str(), nullptr, GUIDesignLabelThickedFixed(100));
1349 myProgramComboBox->disable();
1350 // create auxiliar frames
1351 FXHorizontalFrame* horizontalFrameAux = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1352 FXVerticalFrame* verticalFrameAuxA = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1353 FXVerticalFrame* verticalFrameAuxB = new FXVerticalFrame(horizontalFrameAux, GUIDesignAuxiliarHorizontalFrame);
1354 // create create tlDef button
1355 myCreateButton = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Create TLS"), "", TL("Create a new traffic light program."),
1357 myCreateButton->disable();
1358 // create delete tlDef button
1359 myDeleteButton = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Delete"), "", TL("Delete a traffic light program. If all programs are deleted the junction turns into a priority junction."),
1361 myDeleteButton->disable();
1362 // create reset current tlDef button
1363 myResetSingleButton = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Reset single"), "", TL("Reset current TLS program."),
1365 myResetSingleButton->disable();
1366 // create reset all tlDefs button
1367 myResetAllButton = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Reset all"), "", TL("Reset all TLS programs."),
1369 myResetAllButton->disable();
1370 // create save modifications button
1371 mySaveButon = GUIDesigns::buildFXButton(verticalFrameAuxA, TL("Save"), "", TL("Save program modifications. (Enter)"),
1373 mySaveButon->disable();
1374 // create cancel modifications buttons
1375 myCancelButon = GUIDesigns::buildFXButton(verticalFrameAuxB, TL("Cancel"), "", TL("Discard program modifications. (Esc)"),
1377 myCancelButon->disable();
1378 // show GroupBox
1379 show();
1380}
1381
1382
1384
1385
1386void
1388 if (getNumberOfPrograms() == 0) {
1389 // no TLS Programs, disable buttons except create (if we have a junction)
1390 if (myTLSEditorParent->getTLSJunction()->getCurrentJunction() != nullptr) {
1391 myCreateButton->enable();
1392 } else {
1393 myCreateButton->disable();
1394 }
1395 myDeleteButton->disable();
1396 myResetSingleButton->disable();
1397 myProgramComboBox->disable();
1398 myResetAllButton->disable();
1399 mySaveButon->disable();
1400 myCancelButon->disable();
1401 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1402 // selecting E1, disable buttons
1403 myCreateButton->disable();
1404 myDeleteButton->disable();
1405 myResetSingleButton->disable();
1406 myProgramComboBox->disable();
1407 myResetAllButton->disable();
1408 mySaveButon->disable();
1409 myCancelButon->disable();
1410 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1411 // joining TLSs, disable button
1412 myCreateButton->disable();
1413 myDeleteButton->disable();
1414 myResetSingleButton->disable();
1415 myProgramComboBox->disable();
1416 myResetAllButton->disable();
1417 mySaveButon->disable();
1418 myCancelButon->disable();
1419 } else if (myHaveModifications) {
1420 // modifications, disable button
1421 myCreateButton->disable();
1422 myDeleteButton->disable();
1423 myResetSingleButton->disable();
1424 myProgramComboBox->disable();
1425 myResetAllButton->disable();
1426 // enable save and cancel buttons
1427 mySaveButon->enable();
1428 myCancelButon->enable();
1429 } else {
1430 myCreateButton->enable();
1431 myDeleteButton->enable();
1432 myResetSingleButton->enable();
1433 myProgramComboBox->enable();
1434 // disable save and cancel buttons
1435 mySaveButon->disable();
1436 myCancelButon->disable();
1437 // check if enable reset all
1438 if (getNumberOfPrograms() > 1) {
1439 myResetAllButton->enable();
1440 } else {
1441 myResetAllButton->disable();
1442 }
1443 }
1444 // get current junction
1445 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1446 // update button text
1447 if (currentJunction == nullptr) {
1448 myCreateButton->setText(TL("Create"));
1449 } else if (currentJunction->getNBNode()->isTLControlled()) {
1450 myCreateButton->setText(TL("Duplicate"));
1451 } else {
1452 myCreateButton->setText(TL("Create"));
1453 }
1454}
1455
1456
1457void
1461
1462
1463void
1467
1468
1469bool
1471 // get current edited junction
1472 const auto junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1473 if (junction == nullptr) {
1474 throw ProcessError("Junction cannot be NULL");
1475 } else {
1476 // clear definitions
1477 myTLSPrograms.clear();
1478 // obtain TLSs sorted by ID
1479 std::set<std::string> programIDs;
1480 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1481 myTLSPrograms.push_back(TLS);
1482 programIDs.insert(TLS->getProgramID());
1483 }
1484 for (const auto& programID : programIDs) {
1485 myProgramComboBox->appendIconItem(programID.c_str());
1486 }
1487 // check if enable TLS definitions
1488 if (myTLSPrograms.size() > 0) {
1489 myProgramComboBox->enable();
1490 myProgramComboBox->setCurrentItem(0);
1491 // switch TLS Program
1492 return switchProgram();
1493 }
1494 return false;
1495 }
1496}
1497
1498
1499void
1501 // clear definitions
1502 myTLSPrograms.clear();
1503 // clear and disable myProgramComboBox
1504 myProgramComboBox->clearItems();
1505 myProgramComboBox->disable();
1506}
1507
1508
1509int
1513
1514
1515bool
1519
1520
1521void
1526
1527
1530 // find TLS definition
1531 for (const auto& TLSPrograms : myTLSPrograms) {
1532 if (TLSPrograms->getProgramID() == myProgramComboBox->getText().text()) {
1533 return TLSPrograms;
1534 }
1535 }
1536 throw ProcessError(TL("TLSPrograms cannot be found"));
1537}
1538
1539
1540const std::string
1542 if (myProgramComboBox->getNumItems() == 0) {
1543 return "";
1544 } else {
1545 return myProgramComboBox->getText().text();
1546 }
1547}
1548
1549
1550void
1552 // get junction copy
1553 auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1554 if (currentJunction != nullptr) {
1555 myTLSEditorParent->getViewNet()->getUndoList()->abortAllChangeGroups();
1556 myTLSEditorParent->cleanup();
1557 myTLSEditorParent->getViewNet()->updateViewNet();
1558 // edit junction again
1559 if (editJunctionAgain) {
1560 myTLSEditorParent->editJunction(currentJunction);
1561 }
1562 }
1563 myTLSEditorParent->updateModules();
1564}
1565
1566
1567long
1568GNETLSEditorFrame::TLSPrograms::onCmdCreate(FXObject*, FXSelector, void*) {
1569 // get current edited junction (needed because onCmdDiscardChanges clear junction)
1570 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1571 // abort because we onCmdOk assumes we wish to save an edited definition
1572 discardChanges(false);
1573 // check number of edges
1574 if (currentJunction->getGNEIncomingEdges().empty() && currentJunction->getGNEOutgoingEdges().empty()) {
1575 // open warning dialog
1576 GNEWarningBasicDialog(myTLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows(),
1577 TL("TLS cannot be created"),
1578 TL("Traffic Light cannot be created because junction must have"),
1579 TL("at least one incoming edge and one outgoing edge.")
1580 );
1581 return 1;
1582 }
1583 // check number of connections
1584 if (currentJunction->getGNEConnections().empty()) {
1585 // open warning dialog
1586 GNEWarningBasicDialog(myTLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows(),
1587 TL("TLS cannot be created"),
1588 TL("Traffic Light cannot be created because junction"),
1589 TL("must have at least one connection.")
1590 );
1591 return 1;
1592 }
1593 // check uncontrolled connections
1594 bool connectionControlled = false;
1595 for (const auto& connection : currentJunction->getGNEConnections()) {
1596 if (!connection->getNBEdgeConnection().uncontrolled) {
1597 connectionControlled = true;
1598 }
1599 }
1600 if (!connectionControlled) {
1601 // open warning dialog
1602 GNEWarningBasicDialog(myTLSEditorParent->getViewNet()->getViewParent()->getGNEAppWindows(),
1603 TL("TLS cannot be created"),
1604 TL("Traffic Light cannot be created because junction"),
1605 TL("must have at least one controlled connection.")
1606 );
1607 return 1;
1608 }
1609 // all checks ok, then create TLS in junction
1610 createTLS(currentJunction);
1611 // edit junction
1612 myTLSEditorParent->editJunction(currentJunction);
1613 // switch to the last program
1614 myProgramComboBox->setCurrentItem(myProgramComboBox->getNumItems() - 1, TRUE);
1615 myTLSEditorParent->updateModules();
1616 return 1;
1617}
1618
1619
1620long
1621GNETLSEditorFrame::TLSPrograms::onCmdDelete(FXObject*, FXSelector, void*) {
1622 // get current junction
1623 GNEJunction* currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1624 // get current edited tlDef
1625 NBTrafficLightDefinition* tlDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1626 // check if remove entire TLS or only one program
1627 const bool changeJunctionType = (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 1);
1628 // abort because onCmdOk assumes we wish to save an edited definition
1629 discardChanges(false);
1630 // check if change junction type
1631 if (changeJunctionType) {
1632 currentJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1633 } else {
1634 // just remove TLDef
1635 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(currentJunction, tlDef, false), true);
1636 // edit junction again
1637 myTLSEditorParent->editJunction(currentJunction);
1638 }
1639 myTLSEditorParent->updateModules();
1640 return 1;
1641}
1642
1643
1644long
1646 // obtain junction and old definitions
1647 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1648 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1649 const std::string programID = oldDef->getProgramID();
1650 // discard changes
1651 discardChanges(false);
1652 // begin undo
1653 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("reset current program"));
1654 // remove old definition
1655 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, oldDef, false), true);
1656 // create new definition, and add it
1657 NBOwnTLDef* newDef = new NBOwnTLDef(oldDef->getID(), oldDef->getNodes(), oldDef->getOffset(), oldDef->getType());
1658 newDef->setProgramID(programID);
1659 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newDef, true, true), true);
1660 // set old index
1661 // end undo
1662 myTLSEditorParent->getViewNet()->getUndoList()->end();
1663 // inspect junction again
1664 myTLSEditorParent->editJunction(junction);
1665 // switch to programID
1666 int index = -1;
1667 for (int i = 0; i < myProgramComboBox->getNumItems(); i++) {
1668 if (myProgramComboBox->getItemText(i) == programID) {
1669 index = i;
1670 }
1671 }
1672 if (index != -1) {
1673 myProgramComboBox->setCurrentItem(index, TRUE);
1674 }
1675 myTLSEditorParent->updateModules();
1676 return 1;
1677}
1678
1679
1680long
1682 // obtain junction and old definitions
1683 GNEJunction* junction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1684 NBTrafficLightDefinition* oldDef = myTLSEditorParent->myTLSPrograms->getCurrentTLSPrograms();
1685 // get a list of all affected nodes
1686 std::vector<GNEJunction*> TLSJunctions;
1687 for (const auto& TLSNode : oldDef->getNodes()) {
1688 TLSJunctions.push_back(myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(TLSNode->getID()));
1689 }
1690 // discard all previous changes
1691 discardChanges(false);
1692 // begin undo
1693 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TL("reset TLS"));
1694 // set junction as priority (this will also remove all program, see GNEJunction::setJunctionType)
1695 for (const auto& TLSJunction : TLSJunctions) {
1696 TLSJunction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::PRIORITY), myTLSEditorParent->getViewNet()->getUndoList());
1697 }
1698 // create TLS in junction
1699 createTLS(junction);
1700 // set TLS in all other junctions
1701 for (const auto& TLSJunction : TLSJunctions) {
1702 if (TLSJunction != junction) {
1703 TLSJunction->setAttribute(SUMO_ATTR_TYPE, TLSJunction->getAttribute(SUMO_ATTR_TYPE), myTLSEditorParent->getViewNet()->getUndoList());
1704 TLSJunction->setAttribute(SUMO_ATTR_TLID, TLSJunction->getAttribute(SUMO_ATTR_TLID), myTLSEditorParent->getViewNet()->getUndoList());
1705 }
1706 }
1707 // end undo
1708 myTLSEditorParent->getViewNet()->getUndoList()->end();
1709 // edit junction
1710 myTLSEditorParent->editJunction(junction);
1711 return 1;
1712}
1713
1714
1715long
1717 // check if program is valid (user may input arbitrary text)
1718 bool found = false;
1719 for (const auto& TLSPrograms : myTLSPrograms) {
1720 if (TLSPrograms->getProgramID() == myProgramComboBox->getText().text()) {
1721 found = true;
1722 break;
1723 }
1724 }
1725 if (!found) {
1726 // reset field to a valid program
1727 myProgramComboBox->setText(myTLSPrograms.front()->getProgramID().c_str());
1728 }
1729 switchProgram();
1730 return 1;
1731}
1732
1733
1734long
1736 // get junction copy
1737 const auto currentJunction = myTLSEditorParent->myTLSJunction->getCurrentJunction();
1738 // get current program
1739 const auto currentProgram = myProgramComboBox->getCurrentItem();
1740 // check that junction is valid
1741 if (currentJunction != nullptr) {
1742 const auto oldDefinition = getCurrentTLSPrograms();
1743 std::vector<NBNode*> nodes = oldDefinition->getNodes();
1744 GNEUndoList* undoList = myTLSEditorParent->getViewNet()->getUndoList();
1745 for (const auto& node : nodes) {
1746 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1747 undoList->add(new GNEChange_TLS(junction, oldDefinition, false), true);
1748 undoList->add(new GNEChange_TLS(junction, myTLSEditorParent->myEditedDef, true), true);
1749 // synchronize crossing tl-indices in case they were changed (via onCmdCleanStates)
1750 for (const auto& gc : junction->getGNECrossings()) {
1751 NBNode::Crossing* c = gc->getNBCrossing();
1752 if (c) {
1753 gc->setAttribute(SUMO_ATTR_TLLINKINDEX, toString(c->tlLinkIndex), undoList);
1754 gc->setAttribute(SUMO_ATTR_TLLINKINDEX2, toString(c->tlLinkIndex2), undoList);
1755 }
1756 }
1757
1758
1759 }
1760 // end change
1761 myTLSEditorParent->getViewNet()->getUndoList()->end();
1762 // mark as saved
1763 myHaveModifications = false;
1764 // reset myEditedDef (because is already in eine undo-list)
1765 myTLSEditorParent->myEditedDef = nullptr;
1766 myTLSEditorParent->cleanup();
1767 myTLSEditorParent->getViewNet()->updateViewNet();
1768 // edit junction again
1769 myTLSEditorParent->editJunction(currentJunction);
1770 // change program
1771 myProgramComboBox->setCurrentItem(currentProgram, TRUE);
1772 } else {
1773 // discard changes inspecting junction again
1774 discardChanges(true);
1775 }
1776 myTLSEditorParent->updateModules();
1777 return 1;
1778}
1779
1780
1781long
1783 // discard changes inspecting junction again
1784 discardChanges(true);
1785 return 1;
1786}
1787
1788
1789void
1791 // get current TLS program id
1792 const auto currentTLS = getCurrentTLSProgramID();
1793 // check conditions
1794 if (junction == nullptr) {
1795 throw ProcessError("junction cannot be null");
1797 // set junction as TLS
1798 junction->setAttribute(SUMO_ATTR_TYPE, toString(SumoXMLNodeType::TRAFFIC_LIGHT), myTLSEditorParent->getViewNet()->getUndoList());
1799 } else if (junction->getNBNode()->isTLControlled()) {
1800 // use existing traffic light as template for type, signal groups, controlled nodes etc
1801 NBTrafficLightDefinition* tpl = nullptr;
1802 for (const auto& TLS : junction->getNBNode()->getControllingTLS()) {
1803 if (TLS->getProgramID() == currentTLS) {
1804 tpl = TLS;
1805 }
1806 }
1807 // if template is empty, use first TLS
1808 if (tpl == nullptr) {
1809 tpl = *junction->getNBNode()->getControllingTLS().begin();
1810 }
1811 // create new logic
1813 // create new TLDef
1814 NBLoadedSUMOTLDef* newDef = new NBLoadedSUMOTLDef(*tpl, *newLogic);
1815 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1816 newDef->setProgramID(tllCont.getNextProgramID(newDef->getID()));
1817 // remove new logic
1818 delete newLogic;
1819 // add it using GNEChange_TLS
1820 myTLSEditorParent->getViewNet()->getUndoList()->begin(GUIIcon::MODETLS, TLF("duplicate program '%' of traffic light '%'", tpl->getProgramID(), tpl->getID()));
1821 for (NBNode* node : newDef->getNodes()) {
1822 GNEJunction* j = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(node->getID());
1823 // not forcing insertion because we already ensured a new id and multiple junctions will attempt insertion
1824 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(j, newDef, true, false), true);
1825 }
1826 myTLSEditorParent->getViewNet()->getUndoList()->end();
1827 } else {
1828 // for some reason the traffic light was not built, try again
1829 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, nullptr, true, true), true);
1830 }
1831}
1832
1833
1834bool
1836 if (myTLSEditorParent->myTLSJunction->getCurrentJunction() == nullptr) {
1837 throw ProcessError("Junction cannot be NULL");
1838 } else {
1839 // reset save flag
1840 myHaveModifications = false;
1841 // get current definition
1843 // logic may not have been recomputed yet. recompute to be sure
1844 NBTrafficLightLogicCont& tllCont = myTLSEditorParent->getViewNet()->getNet()->getTLLogicCont();
1845 // compute junction
1846 myTLSEditorParent->getViewNet()->getNet()->computeJunction(myTLSEditorParent->myTLSJunction->getCurrentJunction());
1847 // obtain TrafficLight logic vinculated with tlDef
1848 NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
1849 // check that tllLogic exist
1850 if (tllogic != nullptr) {
1851 // now we can be sure that the tlDef is up to date (i.e. re-guessed)
1852 myTLSEditorParent->buildInternalLanes(tlDef);
1853 // create working duplicate from original def
1854 delete myTLSEditorParent->myEditedDef;
1855 myTLSEditorParent->myEditedDef = new NBLoadedSUMOTLDef(*tlDef, *tllogic);
1856 // set values
1857 myTLSEditorParent->myTLSAttributes->setOffset(myTLSEditorParent->myEditedDef->getLogic()->getOffset());
1858 myTLSEditorParent->myTLSAttributes->setParameters(myTLSEditorParent->myEditedDef->getLogic()->getParametersStr());
1859 // init phaseTable with the new TLS
1860 myTLSEditorParent->myTLSPhases->initPhaseTable();
1861 } else {
1862 // tlDef has no valid logic (probably because id does not control any links
1863 discardChanges(false);
1864 myTLSEditorParent->getViewNet()->setStatusBarText(TL("Traffic Light does not control any links"));
1865 return false;
1866 }
1867 }
1868 return true;
1869}
1870
1871// ---------------------------------------------------------------------------
1872// GNETLSEditorFrame::TLSPhases - methods
1873// ---------------------------------------------------------------------------
1874
1877 myTLSEditorParent(TLSEditorParent) {
1878 // create GNETLSTable
1879 myPhaseTable = new GNETLSTable(this);
1880 // hide phase table
1881 myPhaseTable->hide();
1882 FXHorizontalFrame* phaseButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrameUniform);
1883 FXVerticalFrame* col1 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // left button columm
1884 FXVerticalFrame* col2 = new FXVerticalFrame(phaseButtons, GUIDesignAuxiliarHorizontalFrame); // right button column
1885 // create cleanup states button
1887 TL("Clean States") + std::string("\t") +
1888 TL("Clean unused states from all phase") + std::string("\t") +
1889 TL("Clean unused states from all phase. (Not allowed for multiple programs)"),
1891 myCleanStatesButton->disable();
1892 // add unused states button
1894 TL("Add States") + std::string("\t") +
1895 TL("Extend the state vector for all phases by one entry") + std::string("\t") +
1896 TL("Extend the state vector for all phases by one entry. (Unused until a connection or crossing is assigned to the new index)"),
1898 myAddStates->disable();
1899 // group states button
1901 TL("Group Sig.") + std::string("\t") +
1902 TL("Shorten state definition by letting connections with the same signal states use the same index") + std::string("\t") +
1903 TL("Shorten state definition by letting connections with the same signal states use the same index. (Not allowed for multiple programs)"),
1905 myGroupSignalsButton->disable();
1906 // ungroup states button
1908 TL("Ungroup Sig.") + std::string("\t") +
1909 TL("Let every connection use a distinct index (reverse state grouping)") + std::string("\t") +
1910 TL("Let every connection use a distinct index (reverse state grouping). (Not allowed for multiple programs)"),
1912 myUngroupSignalsButton->disable();
1913 // show TLSFile
1914 show();
1915}
1916
1917
1920
1921
1922void
1924 if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
1925 // selecting E1, disable buttons
1926 myPhaseTable->disable();
1927 myCleanStatesButton->disable();
1928 myAddStates->disable();
1929 myGroupSignalsButton->disable();
1930 myUngroupSignalsButton->disable();
1931 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
1932 // joining TLSs, disable buttons
1933 myPhaseTable->disable();
1934 myCleanStatesButton->disable();
1935 myAddStates->disable();
1936 myGroupSignalsButton->disable();
1937 myUngroupSignalsButton->disable();
1938 myUngroupSignalsButton->disable();
1939 } else if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
1940 // no TLSs, disable buttons
1941 myPhaseTable->disable();
1942 myCleanStatesButton->disable();
1943 myAddStates->disable();
1944 myGroupSignalsButton->disable();
1945 myUngroupSignalsButton->disable();
1946 } else if (myTLSEditorParent->myEditedDef == nullptr) {
1947 // no edited definition, disable buttons
1948 myPhaseTable->disable();
1949 myCleanStatesButton->disable();
1950 myAddStates->disable();
1951 myGroupSignalsButton->disable();
1952 myUngroupSignalsButton->disable();
1953 } else {
1954 myPhaseTable->enable();
1955 myCleanStatesButton->enable();
1956 myAddStates->enable();
1957 myGroupSignalsButton->enable();
1958 if (myTLSEditorParent->myEditedDef->usingSignalGroups()) {
1959 myUngroupSignalsButton->enable();
1960 } else {
1961 myUngroupSignalsButton->disable();
1962 }
1963 }
1964}
1965
1966
1967void
1971
1972
1973void
1977
1978
1983
1984
1989
1990
1991void
1993 // first clear table
1995 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() > 0) {
1996 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
1998 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
2000 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
2002 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
2004 }
2005 // select first element (by default)
2006 myPhaseTable->selectRow(0);
2007 // recalc width and show
2008 myPhaseTable->recalcTableWidth();
2009 myPhaseTable->show();
2010 } else {
2011 myPhaseTable->hide();
2012 }
2013 update();
2014}
2015
2016
2017void
2021
2022
2023bool
2024GNETLSEditorFrame::TLSPhases::changePhaseValue(const int col, const int row, const std::string& value) {
2025 // Declare columns
2026 int colDuration = 1;
2027 int colState = -1;
2028 int colNext = -1;
2029 int colName = -1;
2030 int colMinDur = -1;
2031 int colMaxDur = -1;
2032 int colEarliestEnd = -1;
2033 int colLatestEnd = -1;
2034 int colVehExt = -1;
2035 int colYellow = -1;
2036 int colRed = -1;
2037 // set columns depending of traffic light type
2038 if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC) {
2039 colState = 2;
2040 colNext = 3;
2041 colName = 4;
2042 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::ACTUATED) {
2043 colMinDur = 2;
2044 colMaxDur = 3;
2045 colState = 4;
2046 colEarliestEnd = 5;
2047 colLatestEnd = 6;
2048 colNext = 7;
2049 colName = 8;
2050 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::DELAYBASED) {
2051 colMinDur = 2;
2052 colMaxDur = 3;
2053 colState = 4;
2054 colNext = 5;
2055 colName = 6;
2056 } else if (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA) {
2057 colMinDur = 2;
2058 colMaxDur = 3;
2059 colState = 4;
2060 colVehExt = 5;
2061 colYellow = 6;
2062 colRed = 7;
2063 colNext = 8;
2064 colName = 9;
2065 }
2066 // check column
2067 if (col == colDuration) {
2068 return setDuration(col, row, value);
2069 } else if (col == colState) {
2070 return setState(col, row, value);
2071 } else if (col == colNext) {
2072 return setNext(row, value);
2073 } else if (col == colName) {
2074 return setName(row, value);
2075 } else if (col == colMinDur) {
2076 return setMinDur(row, value);
2077 } else if (col == colMaxDur) {
2078 return setMaxDur(row, value);
2079 } else if (col == colEarliestEnd) {
2080 return setEarliestEnd(row, value);
2081 } else if (col == colLatestEnd) {
2082 return setLatestEnd(row, value);
2083 } else if (col == colVehExt) {
2084 return setVehExt(row, value);
2085 } else if (col == colYellow) {
2086 return setYellow(row, value);
2087 } else if (col == colRed) {
2088 return setRed(row, value);
2089 } else {
2090 throw ProcessError(TL("invalid column"));
2091 }
2092}
2093
2094
2095void
2096GNETLSEditorFrame::TLSPhases::addPhase(const int row, const char c) {
2097 // mark TLS as modified
2098 myTLSEditorParent->myTLSPrograms->markAsModified();
2099 // build default phase
2100 const int newIndex = buildDefaultPhase(row);
2101 // check if override state
2102 switch (c) {
2103 case 'r':
2104 case 'y':
2105 case 'g':
2106 case 'G':
2107 myTLSEditorParent->myEditedDef->getLogic()->overrideState(newIndex, c);
2108 break;
2109 default:
2110 break;
2111 }
2112 // int phase table again
2114 // mark new row as selected
2115 myPhaseTable->selectRow(newIndex);
2116 // set focus in table
2117 getPhaseTable()->setFocus();
2118}
2119
2120
2121void
2123 // mark TLS as modified
2124 myTLSEditorParent->myTLSPrograms->markAsModified();
2125 // build default phase
2126 const int newIndex = buildDefaultPhase(row);
2127 // coply old phase in the new phase
2128 myTLSEditorParent->myEditedDef->getLogic()->copyPhase(row, row + 1);
2129 // int phase table again
2131 // mark new row as selected
2132 myPhaseTable->selectRow(newIndex);
2133 // set focus in table
2134 getPhaseTable()->setFocus();
2135}
2136
2137
2138void
2140 // mark TLS ad modified
2141 myTLSEditorParent->myTLSPrograms->markAsModified();
2142 // calculate new row
2143 const auto newRow = MAX2(0, (row - 1));
2144 // delete selected row
2145 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row);
2146 // int phase table again
2148 // mark new row as selected
2149 myPhaseTable->selectRow(newRow);
2150 // set focus in table
2151 getPhaseTable()->setFocus();
2152}
2153
2154
2155void
2157 // mark TLS ad modified
2158 myTLSEditorParent->myTLSPrograms->markAsModified();
2159 // delete selected row
2160 if (row == 0) {
2161 myTLSEditorParent->myEditedDef->getLogic()->swapfirstPhase();
2162 } else {
2163 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row - 1);
2164 }
2165 // int phase table again
2167 // mark new row as selected
2168 if (row == 0) {
2169 myPhaseTable->selectRow((int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1);
2170 } else {
2171 myPhaseTable->selectRow(row - 1);
2172 }
2173 // set focus in table
2174 getPhaseTable()->setFocus();
2175}
2176
2177
2178void
2180 // mark TLS ad modified
2181 myTLSEditorParent->myTLSPrograms->markAsModified();
2182 // delete selected row
2183 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2184 myTLSEditorParent->myEditedDef->getLogic()->swaplastPhase();
2185 } else {
2186 myTLSEditorParent->myEditedDef->getLogic()->swapPhase(row, row + 1);
2187 }
2188 // int phase table again
2190 // mark new row as selected
2191 if (row == (int)myTLSEditorParent->myEditedDef->getLogic()->getPhases().size() - 1) {
2192 myPhaseTable->selectRow(0);
2193 } else {
2194 myPhaseTable->selectRow(row + 1);
2195 }
2196 // set focus in table
2197 getPhaseTable()->setFocus();
2198}
2199
2200
2201void
2203 // get phase
2204 const auto& phase = myTLSEditorParent->getPhase(myPhaseTable->getCurrentSelectedRow());
2205 // need not hold since links could have been deleted somewhere else and indices may be reused
2206 for (const auto& internalLane : myTLSEditorParent->myInternalLanes) {
2207 int tlIndex = internalLane.first;
2208 std::vector<GNEInternalLane*> lanes = internalLane.second;
2210 if (tlIndex >= 0 && tlIndex < (int)phase.state.size()) {
2211 state = (LinkState)phase.state[tlIndex];
2212 }
2213 for (const auto& lane : lanes) {
2214 lane->setLinkState(state);
2215 }
2216 }
2217 // update view net (for coloring)
2218 myTLSEditorParent->getViewNet()->updateViewNet();
2219}
2220
2221
2222long
2224 if (myTLSEditorParent->myEditedDef->cleanupStates()) {
2225 myTLSEditorParent->myTLSPrograms->markAsModified();
2226 }
2227 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2229 myPhaseTable->setFocus();
2230 myTLSEditorParent->myTLSPrograms->markAsModified();
2231 myTLSEditorParent->updateModules();
2232 return 1;
2233}
2234
2235
2236long
2238 myTLSEditorParent->myEditedDef->getLogic()->setStateLength(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks() + 1);
2239 myTLSEditorParent->myTLSPrograms->markAsModified();
2241 myPhaseTable->setFocus();
2242 myTLSEditorParent->updateModules();
2243 return 1;
2244}
2245
2246
2247long
2249 myTLSEditorParent->myEditedDef->groupSignals();
2250 myTLSEditorParent->myTLSPrograms->markAsModified();
2251 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2253 myPhaseTable->setFocus();
2254 myTLSEditorParent->updateModules();
2255 return 1;
2256}
2257
2258
2259long
2261 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2262 myTLSEditorParent->myEditedDef->ungroupSignals();
2263 myTLSEditorParent->myTLSPrograms->markAsModified();
2264 myTLSEditorParent->buildInternalLanes(myTLSEditorParent->myEditedDef);
2266 myPhaseTable->setFocus();
2267 myTLSEditorParent->updateModules();
2268 return 1;
2269}
2270
2271
2272void
2274 // declare constants for columns
2275 const int colDuration = 1;
2276 const int colState = 2;
2277 const int colNext = 3;
2278 const int colName = 4;
2279 // get phases
2280 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2281 // adjust table
2282 myPhaseTable->setTableSize("sup-midtb", (int)phases.size());
2283 // fill rows
2284 for (int row = 0; row < (int)phases.size(); row++) {
2285 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2286 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2287 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2288 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2289 }
2290 // set columns
2291 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2292 myPhaseTable->setColumnLabelTop(colState, "state");
2293 myPhaseTable->setColumnLabelTop(colNext, "next");
2294 myPhaseTable->setColumnLabelTop(colName, "name");
2295 // set bot labels
2296 updateCycleDuration(colDuration);
2297 updateStateSize(colState);
2298 // set focus
2299 myPhaseTable->setFocus();
2300}
2301
2302
2303void
2305 // declare constants for columns
2306 const int colDuration = 1;
2307 const int colMinDur = 2;
2308 const int colMaxDur = 3;
2309 const int colState = 4;
2310 const int colEarliestEnd = 5;
2311 const int colLatestEnd = 6;
2312 const int colNext = 7;
2313 const int colName = 8;
2314 // get phases
2315 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2316 // adjust table
2317 myPhaseTable->setTableSize("suffpff-midtb", (int)phases.size());
2318 // fill rows
2319 for (int row = 0; row < (int)phases.size(); row++) {
2320 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2321 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2322 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2323 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2324 myPhaseTable->setItemText(row, colEarliestEnd, varDurString(phases.at(row).earliestEnd).c_str());
2325 myPhaseTable->setItemText(row, colLatestEnd, varDurString(phases.at(row).latestEnd).c_str());
2326 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2327 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2328 }
2329 // set columns
2330 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2331 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2332 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2333 myPhaseTable->setColumnLabelTop(colEarliestEnd, "ear.end", "earlyEnd");
2334 myPhaseTable->setColumnLabelTop(colLatestEnd, "lat.end", "latestEnd");
2335 myPhaseTable->setColumnLabelTop(colState, "state");
2336 myPhaseTable->setColumnLabelTop(colNext, "next");
2337 myPhaseTable->setColumnLabelTop(colName, "name");
2338 // set bot labels
2339 updateCycleDuration(colDuration);
2340 updateStateSize(colState);
2341 // set focus
2342 myPhaseTable->setFocus();
2343}
2344
2345
2346void
2348 // declare constants for columns
2349 const int colDuration = 1;
2350 const int colMinDur = 2;
2351 const int colMaxDur = 3;
2352 const int colState = 4;
2353 const int colNext = 5;
2354 const int colName = 6;
2355 // get phases
2356 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2357 // adjust table
2358 myPhaseTable->setTableSize("suffp-midtb", (int)phases.size());
2359 // fill rows
2360 for (int row = 0; row < (int)phases.size(); row++) {
2361 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2362 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2363 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2364 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2365 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2366 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2367 }
2368 // set columns
2369 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2370 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2371 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2372 myPhaseTable->setColumnLabelTop(colState, "state");
2373 myPhaseTable->setColumnLabelTop(colNext, "next");
2374 myPhaseTable->setColumnLabelTop(colName, "name");
2375 // set bot labels
2376 updateCycleDuration(colDuration);
2377 updateStateSize(colState);
2378 // set focus
2379 myPhaseTable->setFocus();
2380}
2381
2382
2383void
2385 // declare constants for columns
2386 const int colDuration = 1;
2387 const int colMinDur = 2;
2388 const int colMaxDur = 3;
2389 const int colState = 4;
2390 const int colVehExt = 5;
2391 const int colYellow = 6;
2392 const int colRed = 7;
2393 const int colNext = 8;
2394 const int colName = 9;
2395 // get phases
2396 const auto& phases = myTLSEditorParent->myEditedDef->getLogic()->getPhases();
2397 // adjust table
2398 myPhaseTable->setTableSize("suffpfff-midtb", (int)phases.size());
2399 // fill rows
2400 for (int row = 0; row < (int)phases.size(); row++) {
2401 myPhaseTable->setItemText(row, colDuration, getSteps2Time(phases.at(row).duration).c_str());
2402 myPhaseTable->setItemText(row, colMinDur, varDurString(phases.at(row).minDur).c_str());
2403 myPhaseTable->setItemText(row, colMaxDur, varDurString(phases.at(row).maxDur).c_str());
2404 myPhaseTable->setItemText(row, colState, phases.at(row).state.c_str());
2405 myPhaseTable->setItemText(row, colVehExt, varDurString(phases.at(row).vehExt).c_str());
2406 myPhaseTable->setItemText(row, colYellow, varDurString(phases.at(row).yellow).c_str());
2407 myPhaseTable->setItemText(row, colRed, varDurString(phases.at(row).red).c_str());
2408 myPhaseTable->setItemText(row, colNext, phases.at(row).next.size() > 0 ? toString(phases.at(row).next).c_str() : "");
2409 myPhaseTable->setItemText(row, colName, phases.at(row).name.c_str());
2410 }
2411 // set columns
2412 myPhaseTable->setColumnLabelTop(colDuration, "dur");
2413 myPhaseTable->setColumnLabelTop(colMinDur, "min");
2414 myPhaseTable->setColumnLabelTop(colMaxDur, "max");
2415 myPhaseTable->setColumnLabelTop(colState, "state");
2416 myPhaseTable->setColumnLabelTop(colVehExt, "vehExt", "vehicle extension");
2417 myPhaseTable->setColumnLabelTop(colYellow, "yellow");
2418 myPhaseTable->setColumnLabelTop(colRed, "red");
2419 myPhaseTable->setColumnLabelTop(colNext, "next");
2420 myPhaseTable->setColumnLabelTop(colName, "name");
2421 // set bot labels
2422 updateCycleDuration(colDuration);
2423 updateStateSize(colState);
2424 // set focus
2425 myPhaseTable->setFocus();
2426}
2427
2428
2429int
2431 // get option container
2432 const auto& neteditOptions = OptionsCont::getOptions();
2433 // check if TLS is static
2434 const bool TLSStatic = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::STATIC);
2435 const bool NEMA = (myTLSEditorParent->myEditedDef->getType() == TrafficLightType::NEMA);
2436 // calculate new index
2437 const int newIndex = row + 1;
2438 // duplicate current row
2439 auto duration = getSUMOTime(myPhaseTable->getItemText(row, 1));
2440 const auto oldState = myPhaseTable->getItemText(row, TLSStatic ? 2 : 4);
2441 auto state = oldState;
2442 // update crossingINdices
2443 std::set<int> crossingIndices;
2444 for (const auto& node : myTLSEditorParent->myEditedDef->getNodes()) {
2445 for (const auto& crossing : node->getCrossings()) {
2446 crossingIndices.insert(crossing->tlLinkIndex);
2447 crossingIndices.insert(crossing->tlLinkIndex2);
2448 }
2449 }
2450 // smart adapations for new state
2451 bool haveGreen = false;
2452 bool haveYellow = false;
2453 for (const auto& linkStateChar : state) {
2454 if ((linkStateChar == LINKSTATE_TL_GREEN_MAJOR) || (linkStateChar == LINKSTATE_TL_GREEN_MINOR)) {
2455 haveGreen = true;
2456 } else if ((linkStateChar == LINKSTATE_TL_YELLOW_MAJOR) || (linkStateChar == LINKSTATE_TL_YELLOW_MINOR)) {
2457 haveYellow = true;
2458 }
2459 }
2460 if (haveGreen && haveYellow) {
2461 // guess left-mover state
2462 duration = TIME2STEPS(neteditOptions.getInt("tls.left-green.time"));
2463 for (int i = 0; i < (int)state.size(); i++) {
2464 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2465 state[i] = LINKSTATE_TL_RED;
2466 } else if (state[i] == LINKSTATE_TL_GREEN_MINOR) {
2467 state[i] = LINKSTATE_TL_GREEN_MAJOR;
2468 }
2469 }
2470 } else if (haveGreen) {
2471 // guess yellow state
2472 myTLSEditorParent->myEditedDef->setParticipantsInformation();
2473 duration = TIME2STEPS(myTLSEditorParent->myEditedDef->computeBrakingTime(neteditOptions.getFloat("tls.yellow.min-decel")));
2474 for (int i = 0; i < (int)state.size(); i++) {
2475 if ((state[i] == LINKSTATE_TL_GREEN_MAJOR) || (state[i] == LINKSTATE_TL_GREEN_MINOR)) {
2476 if (crossingIndices.count(i) == 0) {
2477 state[i] = LINKSTATE_TL_YELLOW_MINOR;
2478 } else {
2479 state[i] = LINKSTATE_TL_RED;
2480 }
2481 }
2482 }
2483 } else if (haveYellow) {
2484 duration = TIME2STEPS(neteditOptions.isDefault("tls.allred.time") ? 2 : neteditOptions.getInt("tls.allred.time"));
2485 // guess all-red state
2486 for (int i = 0; i < (int)state.size(); i++) {
2487 if ((state[i] == LINKSTATE_TL_YELLOW_MAJOR) || (state[i] == LINKSTATE_TL_YELLOW_MINOR)) {
2488 state[i] = LINKSTATE_TL_RED;
2489 }
2490 }
2491 }
2492 // fix continuous green states
2493 const int nextIndex = (myPhaseTable->getNumRows() > newIndex) ? newIndex : 0;
2494 const std::string state2 = myPhaseTable->getItemText(nextIndex, (TLSStatic ? 2 : 4));
2495 for (int i = 0; i < (int)state.size(); i++) {
2496 if (((oldState[i] == LINKSTATE_TL_GREEN_MAJOR) || (oldState[i] == LINKSTATE_TL_GREEN_MINOR)) &&
2497 ((state2[i] == LINKSTATE_TL_GREEN_MAJOR) || (state2[i] == LINKSTATE_TL_GREEN_MINOR))) {
2498 state[i] = oldState[i];
2499 }
2500 }
2501 // add new step
2502 if (NEMA) {
2503 myTLSEditorParent->myEditedDef->getLogic()->addStep(string2time("90"), state, string2time("5"), string2time("50"),
2505 string2time("2"), string2time("3"), string2time("2"), "1", std::vector<int>(), newIndex);
2506 } else {
2507 myTLSEditorParent->myEditedDef->getLogic()->addStep(duration, state, std::vector<int>(), "", newIndex);
2508 }
2509 // return new index
2510 return newIndex;
2511}
2512
2513
2514bool
2515GNETLSEditorFrame::TLSPhases::setDuration(const int col, const int row, const std::string& value) {
2516 // check value
2517 if (value.empty()) {
2518 // input empty, reset
2519 getPhaseTable()->setItemText(row, col, getSteps2Time(myTLSEditorParent->getPhase(row).duration).c_str());
2520 return true;
2522 const auto duration = getSUMOTime(value);
2523 // check that duration > 0
2524 if (duration > 0) {
2525 myTLSEditorParent->myEditedDef->getLogic()->setPhaseDuration(row, duration);
2526 myTLSEditorParent->myTLSPrograms->markAsModified();
2527 // update Cycle duration
2529 return true;
2530 } else {
2531 return false;
2532 }
2533 } else {
2534 return false;
2535 }
2536}
2537
2538
2539bool
2540GNETLSEditorFrame::TLSPhases::setState(const int col, const int row, const std::string& value) {
2541 // get state
2542 const auto& phase = myTLSEditorParent->getPhase(row);
2543 // declare new state. If value is empty, use previous value (reset)
2544 const auto newState = value.empty() ? phase.state : value;
2545 // insert phase
2546 try {
2547 myTLSEditorParent->myEditedDef->getLogic()->addStep(phase.duration, newState, phase.next, phase.name, row);
2548 } catch (ProcessError&) {
2549 // invalid character in newState
2550 return false;
2551 }
2552 // delete next phase
2553 try {
2554 myTLSEditorParent->myEditedDef->getLogic()->deletePhase(row + 1);
2555 } catch (InvalidArgument&) {
2556 WRITE_ERROR(TL("Error deleting phase '") + toString(row + 1) + "'");
2557 return false;
2558 }
2559 // mark TLS as modified depending of value
2560 if (value.size() > 0) {
2561 myTLSEditorParent->myTLSPrograms->markAsModified();
2562 // select row
2563 myPhaseTable->selectRow(row);
2564 } else {
2565 // input empty, reset
2566 getPhaseTable()->setItemText(row, col, newState);
2567 }
2568 // update state size
2569 updateStateSize(col);
2570 return true;
2571}
2572
2573
2574bool
2575GNETLSEditorFrame::TLSPhases::setNext(const int row, const std::string& value) {
2576 // check next
2577 if (GNEAttributeCarrier::canParse<std::vector<int> >(value)) {
2578 const auto nextEdited = GNEAttributeCarrier::parse<std::vector<int> >(value);
2579 for (const auto nextPhase : nextEdited) {
2580 if ((nextPhase < 0) || (nextPhase >= myPhaseTable->getNumRows())) {
2581 return false;
2582 }
2583 }
2584 // set new next
2585 myTLSEditorParent->myEditedDef->getLogic()->setPhaseNext(row, nextEdited);
2586 myTLSEditorParent->myTLSPrograms->markAsModified();
2587 return true;
2588 } else {
2589 return false;
2590 }
2591}
2592
2593
2594bool
2595GNETLSEditorFrame::TLSPhases::setName(const int row, const std::string& value) {
2596 // update name (currently no check needed)
2597 myTLSEditorParent->myEditedDef->getLogic()->setPhaseName(row, value);
2598 myTLSEditorParent->myTLSPrograms->markAsModified();
2599 return true;
2600}
2601
2602
2603bool
2604GNETLSEditorFrame::TLSPhases::setMinDur(const int row, const std::string& value) {
2605 // check value
2606 if (value.empty()) {
2607 // set empty value
2608 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2609 myTLSEditorParent->myTLSPrograms->markAsModified();
2610 return true;
2612 const auto minDur = getSUMOTime(value);
2613 // check that minDur > 0
2614 if (minDur > 0) {
2615 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, minDur);
2616 myTLSEditorParent->myTLSPrograms->markAsModified();
2617 return true;
2618 } else {
2619 return false;
2620 }
2621 } else if (StringUtils::prune(value).empty()) {
2622 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMinDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2623 myTLSEditorParent->myTLSPrograms->markAsModified();
2624 return true;
2625 } else {
2626 return false;
2627 }
2628}
2629
2630
2631bool
2632GNETLSEditorFrame::TLSPhases::setMaxDur(const int row, const std::string& value) {
2633 // check value
2634 if (value.empty()) {
2635 // set empty value
2636 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2637 myTLSEditorParent->myTLSPrograms->markAsModified();
2638 return true;
2640 const auto maxDur = getSUMOTime(value);
2641 // check that minDur > 0
2642 if (maxDur > 0) {
2643 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, maxDur);
2644 myTLSEditorParent->myTLSPrograms->markAsModified();
2645 return true;
2646 } else {
2647 return false;
2648 }
2649 } else if (StringUtils::prune(value).empty()) {
2650 myTLSEditorParent->myEditedDef->getLogic()->setPhaseMaxDuration(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2651 myTLSEditorParent->myTLSPrograms->markAsModified();
2652 return true;
2653 } else {
2654 return false;
2655 }
2656}
2657
2658
2659bool
2660GNETLSEditorFrame::TLSPhases::setEarliestEnd(const int row, const std::string& value) {
2661 // check value
2662 if (value.empty()) {
2663 // set empty value
2664 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2665 myTLSEditorParent->myTLSPrograms->markAsModified();
2666 return true;
2668 const auto earliestEnd = getSUMOTime(value);
2669 // check that earliestEnd > 0
2670 if (earliestEnd > 0) {
2671 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, earliestEnd);
2672 myTLSEditorParent->myTLSPrograms->markAsModified();
2673 return true;
2674 } else {
2675 return false;
2676 }
2677 } else if (StringUtils::prune(value).empty()) {
2678 myTLSEditorParent->myEditedDef->getLogic()->setPhaseEarliestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2679 myTLSEditorParent->myTLSPrograms->markAsModified();
2680 return true;
2681 } else {
2682 return false;
2683 }
2684}
2685
2686
2687bool
2688GNETLSEditorFrame::TLSPhases::setLatestEnd(const int row, const std::string& value) {
2689 // check value
2690 if (value.empty()) {
2691 // set empty value
2692 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2693 myTLSEditorParent->myTLSPrograms->markAsModified();
2694 return true;
2696 const auto latestEnd = getSUMOTime(value);
2697 // check that latestEnd > 0
2698 if (latestEnd > 0) {
2699 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, latestEnd);
2700 myTLSEditorParent->myTLSPrograms->markAsModified();
2701 return true;
2702 } else {
2703 return false;
2704 }
2705 } else if (StringUtils::prune(value).empty()) {
2706 myTLSEditorParent->myEditedDef->getLogic()->setPhaseLatestEnd(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2707 myTLSEditorParent->myTLSPrograms->markAsModified();
2708 return true;
2709 } else {
2710 return false;
2711 }
2712}
2713
2714
2715bool
2716GNETLSEditorFrame::TLSPhases::setVehExt(const int row, const std::string& value) {
2717 // check value
2718 if (value.empty()) {
2719 // set empty value
2720 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2721 myTLSEditorParent->myTLSPrograms->markAsModified();
2722 return true;
2724 const auto vehExt = getSUMOTime(value);
2725 // check that vehExt > 0
2726 if (vehExt > 0) {
2727 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, vehExt);
2728 myTLSEditorParent->myTLSPrograms->markAsModified();
2729 return true;
2730 } else {
2731 return false;
2732 }
2733 } else if (StringUtils::prune(value).empty()) {
2734 myTLSEditorParent->myEditedDef->getLogic()->setPhaseVehExt(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2735 myTLSEditorParent->myTLSPrograms->markAsModified();
2736 return true;
2737 } else {
2738 return false;
2739 }
2740}
2741
2742
2743bool
2744GNETLSEditorFrame::TLSPhases::setYellow(const int row, const std::string& value) {
2745 // check value
2746 if (value.empty()) {
2747 // set empty value
2748 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2749 myTLSEditorParent->myTLSPrograms->markAsModified();
2750 return true;
2752 const auto yellow = getSUMOTime(value);
2753 // check that yellow > 0
2754 if (yellow > 0) {
2755 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, yellow);
2756 myTLSEditorParent->myTLSPrograms->markAsModified();
2757 return true;
2758 } else {
2759 return false;
2760 }
2761 } else if (StringUtils::prune(value).empty()) {
2762 myTLSEditorParent->myEditedDef->getLogic()->setPhaseYellow(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2763 myTLSEditorParent->myTLSPrograms->markAsModified();
2764 return true;
2765 } else {
2766 return false;
2767 }
2768}
2769
2770
2771bool
2772GNETLSEditorFrame::TLSPhases::setRed(const int row, const std::string& value) {
2773 // check value
2774 if (value.empty()) {
2775 // set empty value
2776 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2777 myTLSEditorParent->myTLSPrograms->markAsModified();
2778 return true;
2780 const auto red = getSUMOTime(value);
2781 // check that red > 0
2782 if (red > 0) {
2783 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, red);
2784 myTLSEditorParent->myTLSPrograms->markAsModified();
2785 return true;
2786 } else {
2787 return false;
2788 }
2789 } else if (StringUtils::prune(value).empty()) {
2790 myTLSEditorParent->myEditedDef->getLogic()->setPhaseRed(row, NBTrafficLightDefinition::UNSPECIFIED_DURATION);
2791 myTLSEditorParent->myTLSPrograms->markAsModified();
2792 return true;
2793 } else {
2794 return false;
2795 }
2796}
2797
2798
2799void
2801 SUMOTime cycleDuration = 0;
2802 for (const auto& phase : myTLSEditorParent->myEditedDef->getLogic()->getPhases()) {
2803 cycleDuration += phase.duration;
2804 }
2805 // update bot label with cycle duration
2806 myPhaseTable->setColumnLabelBot(col, getSteps2Time(cycleDuration));
2807}
2808
2809
2810void
2812 // update bot label with number of links
2813 myPhaseTable->setColumnLabelBot(col, "Links: " + toString(myTLSEditorParent->myEditedDef->getLogic()->getNumLinks()));
2814}
2815
2816// ---------------------------------------------------------------------------
2817// GNETLSEditorFrame::TLSFile - methods
2818// ---------------------------------------------------------------------------
2819
2821 MFXGroupBoxModule(TLSEditorParent, TL("TLS Program File")),
2822 myTLSEditorParent(TLSEditorParent) {
2823 FXHorizontalFrame* buttonsFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
2824 // create create tlDef button
2825 myLoadButton = GUIDesigns::buildFXButton(buttonsFrame, TL("Load"), "", TL("Load TLS program from additional file"), GUIIconSubSys::getIcon(GUIIcon::OPEN), this, MID_GNE_TLSFRAME_FILE_LOADPROGRAM, GUIDesignButton);
2826 myLoadButton->disable();
2827 // create create tlDef button
2828 mySaveButton = GUIDesigns::buildFXButton(buttonsFrame, TL("Save"), "", TL("Save TLS program to additional file"), GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_GNE_TLSFRAME_FILE_SAVEPROGRAM, GUIDesignButton);
2829 mySaveButton->disable();
2830 // show TLSFile
2831 show();
2832}
2833
2834
2836
2837
2838void
2840 if (myTLSEditorParent->myTLSPrograms->getNumberOfPrograms() == 0) {
2841 myLoadButton->disable();
2842 mySaveButton->disable();
2843 } else if (myTLSEditorParent->myTLSAttributes->isSetDetectorsToggleButtonEnabled()) {
2844 // selecting E1, disable buttons
2845 myLoadButton->disable();
2846 mySaveButton->disable();
2847 } else if (myTLSEditorParent->myTLSJunction->isJoiningJunctions()) {
2848 // joining TLSs, disable button
2849 myLoadButton->disable();
2850 mySaveButton->disable();
2851 } else {
2852 myLoadButton->enable();
2853 mySaveButton->enable();
2854 }
2855}
2856
2857
2858void
2862
2863
2864void
2868
2869
2870long
2872 FXFileDialog opendialog(getCollapsableFrame(), "Load TLS Program");
2873 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::MODETLS));
2874 opendialog.setSelectMode(SELECTFILE_EXISTING);
2875 opendialog.setPatternList(SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str());
2876 if (gCurrentFolder.length() != 0) {
2877 opendialog.setDirectory(gCurrentFolder);
2878 }
2879 if (opendialog.execute()) {
2880 // run parser
2881 NBTrafficLightLogicCont tmpTLLCont;
2882 NIXMLTrafficLightsHandler tllHandler(tmpTLLCont, myTLSEditorParent->getViewNet()->getNet()->getEdgeCont(), true);
2883 tmpTLLCont.insert(myTLSEditorParent->myEditedDef);
2884 XMLSubSys::runParser(tllHandler, opendialog.getFilename().text());
2885
2886 NBLoadedSUMOTLDef* newDefSameProgram = nullptr;
2887 std::set<NBLoadedSUMOTLDef*> newDefsOtherProgram;
2888 for (auto item : tmpTLLCont.getPrograms(myTLSEditorParent->myEditedDef->getID())) {
2889 if (item.second != myTLSEditorParent->myEditedDef) {
2890 NBLoadedSUMOTLDef* sdef = dynamic_cast<NBLoadedSUMOTLDef*>(item.second);
2891 if (item.first == myTLSEditorParent->myEditedDef->getProgramID()) {
2892 newDefSameProgram = sdef;
2893 } else {
2894 newDefsOtherProgram.insert(sdef);
2895 }
2896 }
2897 }
2898 const int newPrograms = (int)newDefsOtherProgram.size();
2899 if (newPrograms > 0 || newDefSameProgram != nullptr) {
2900 std::vector<NBNode*> nodes = myTLSEditorParent->myEditedDef->getNodes();
2901 for (auto newProg : newDefsOtherProgram) {
2902 for (auto it_node : nodes) {
2903 GNEJunction* junction = myTLSEditorParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveJunction(it_node->getID());
2904 myTLSEditorParent->getViewNet()->getUndoList()->add(new GNEChange_TLS(junction, newProg, true), true);
2905 }
2906 }
2907 if (newPrograms > 0) {
2908 WRITE_MESSAGE(TL("Loaded ") + toString(newPrograms) + TL(" new programs for tlLogic '") + myTLSEditorParent->myEditedDef->getID() + "'");
2909 }
2910 if (newDefSameProgram != nullptr) {
2911 // replace old program when loading the same program ID
2912 myTLSEditorParent->myEditedDef = newDefSameProgram;
2913 WRITE_MESSAGE(TL("Updated program '") + newDefSameProgram->getProgramID() + TL("' for tlLogic '") + myTLSEditorParent->myEditedDef->getID() + "'");
2914 }
2915 } else {
2916 if (tllHandler.getSeenIDs().count(myTLSEditorParent->myEditedDef->getID()) == 0) {
2917 myTLSEditorParent->getViewNet()->setStatusBarText(TL("No programs found for traffic light '") + myTLSEditorParent->myEditedDef->getID() + "'");
2918 }
2919 }
2920
2921 // clean up temporary container to avoid deletion of defs when its destruct is called
2922 for (NBTrafficLightDefinition* def : tmpTLLCont.getDefinitions()) {
2923 tmpTLLCont.removeProgram(def->getID(), def->getProgramID(), false);
2924 }
2925
2926 myTLSEditorParent->myTLSPhases->initPhaseTable();
2927 myTLSEditorParent->myTLSPrograms->markAsModified();
2928 }
2929 myTLSEditorParent->updateModules();
2930 return 0;
2931}
2932
2933
2934long
2936 FXString file = MFXUtils::getFilename2Write(this, TL("Save TLS Program as"),
2937 SUMOXMLDefinitions::XMLFileExtensions.getMultilineString().c_str(),
2939 // check file
2940 if (file != "") {
2941 // add xml extension
2942 file = FileHelpers::addExtension(file.text(), ".xml").c_str();
2943 OutputDevice& device = OutputDevice::getDevice(file.text());
2944 // save program
2945 device.writeXMLHeader("additional", "additional_file.xsd");
2946 NWWriter_SUMO::writeTrafficLight(device, myTLSEditorParent->myEditedDef->getLogic());
2947 device.close();
2948 }
2949 myTLSEditorParent->updateModules();
2950 return 1;
2951}
2952
2953
2954std::string
2956 const double time = STEPS2TIME(steps);
2957 if (time == std::floor(time)) {
2958 return toString(int(time));
2959 } else {
2960 return toString(time);
2961 }
2962}
2963
2964/****************************************************************************/
FXDEFMAP(GNETLSEditorFrame::TLSJunction) TLSJunctionMap[]
long long int SUMOTime
Definition GUI.h:36
@ MID_GNE_TLSFRAME_TLSJUNCTION_DISJOIN
Disjoin TLS.
@ MID_GNE_TLSFRAME_DEFINITION_RESETCURRENT
reset current (single) TLS program
@ MID_GNE_TLSFRAME_PHASES_ADDUNUSED
add unused states
@ MID_GNE_TLSFRAME_ATTRIBUTES_TOGGLEDETECTOR
set detectors in TLS
@ MID_GNE_TLSFRAME_TLSJUNCTION_TOGGLEJOIN
join TLS
@ MID_GNE_TLSFRAME_PHASES_CLEANUP
cleanup unused states
@ MID_GNE_TLSFRAME_PHASES_GROUPSTATES
group states
@ MID_GNE_BUTTON_CANCEL
cancel button
@ MID_GNE_TLSFRAME_DEFINITION_DELETE
delete TLS
@ MID_GNE_TLSFRAME_FILE_SAVEPROGRAM
cleanup unused states
@ MID_GNE_TLSFRAME_PHASES_UNGROUPSTATES
ungroup states
@ MID_GNE_TLSFRAME_DEFINITION_CREATE
Create TLS.
@ MID_GNE_TLSFRAME_DEFINITION_SAVE
accept TLS modification
@ MID_GNE_TLSFRAME_DEFINITION_SWITCHPROGRAM
switch between programs
@ MID_GNE_TLSFRAME_DEFINITION_DISCARD
cancel TLS modification
@ MID_GNE_TLSFRAME_DEFINITION_RESETALL
reset all TLS programs
@ MID_GNE_TLSFRAME_TLSJUNCTION_TYPE
current TLS ID
@ MID_GNE_TLSFRAME_TLSJUNCTION_ID
current TLS ID
@ MID_GNE_BUTTON_ACCEPT
accept button
@ MID_GNE_TLSFRAME_ATTRIBUTES_OFFSET
TLS offset.
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERSDIALOG
TLS parameters.
@ MID_GNE_TLSFRAME_FILE_LOADPROGRAM
Load Program.
@ MID_GNE_TLSFRAME_ATTRIBUTES_PARAMETERS
TLS parameters.
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition GUIDesigns.h:106
#define GUIDesignTextColorRed
red color (for invalid text)
Definition GUIDesigns.h:44
#define GUIDesignButton
Definition GUIDesigns.h:100
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition GUIDesigns.h:304
#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 GUIDesignAuxiliarHorizontalFrameUniform
design for auxiliar (Without borders) horizontal frame used to pack another frames uniform
Definition GUIDesigns.h:436
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition GUIDesigns.h:92
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:64
#define GUIDesignTextColorBlack
black color (for correct text)
Definition GUIDesigns.h:38
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:254
FXString gCurrentFolder
The folder used as last.
@ MODETLS
Definition GUIIcons.h:369
@ DISJOIN
Definition GUIIcons.h:127
@ OPEN
open icons
Definition GUIIcons.h:77
@ EMPTY
Definition GUIIcons.h:59
@ SAVE
save icons
Definition GUIIcons.h:90
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
const std::string invalid_return< std::string >::value
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_YELLOW_MAJOR
The link has yellow light, may pass.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake).
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ SUMO_ATTR_TLLINKINDEX2
link: the index of the opposite direction link of a pedestrian crossing
@ SUMO_ATTR_OFFSET
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_TLLINKINDEX
link: the index of the link within the traffic light
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
const unsigned char TLS[]
Definition TLS.cpp:22
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static std::string addExtension(const std::string &path, const std::string &extension)
Add an extension to the given file path.
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
const std::string getID() const override
get ID (all Attribute Carriers have one)
static T parse(const std::string &string)
parses a value of type T from string (used for basic types: int, double, bool, etc....
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:145
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
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
LinkState getLinkState() const
whether link state has been modified
int getTLIndex() const
get Traffic Light index
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
std::string getAttribute(SumoXMLAttr key) const override
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
NBNode * getNBNode() const
Return net build node.
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:214
long onCmdSetParameters(FXObject *, FXSelector, void *)
Called when the user changes parameters of a TLS.
long onCmdSetOffset(FXObject *, FXSelector, void *)
bool isValidOffset()
is current offset valid
long onCmdParametersDialog(FXObject *, FXSelector, void *ptr)
Called when user press edit parameters button.
MFXToggleButtonTooltip * mySetDetectorsToggleButton
toggle button for set detectors mode
bool isSetDetectorsToggleButtonEnabled() const
toggle button for set detectors mode
bool isValidParameters()
are current parameter valid
void updateTLSAttributes()
update TLSAttributes module
FXTextField * myOffsetTextField
the TextField for modifying offset
void disableE1DetectorMode()
disable detector mode
SUMOTime getOffset() const
get current offset in string format
void setParameters(const std::string &parameters)
set new parameters
const std::map< std::string, std::string > & getE1Detectors() const
get E1 detectors vinculated with this TLS
void clearTLSAttributes()
clear TLS attributes
void setOffset(const SUMOTime &offset)
set new offset
std::map< std::string, std::string > myE1Detectors
set with E1 detector IDs and their lanes vinculated with the TLS <laneID, E1ID>
std::string getParameters() const
get current parameters in string format
bool toggleE1DetectorSelection(const GNEAdditional *E1)
select or unselect E1 detector in the current TLS
void initTLSAttributes()
initializes the definitions and corresponding listbox
FXButton * myButtonEditParameters
button for edit parameters
TLSAttributes(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
FXTextField * myParametersTextField
the TextField for modifying parameters
void hideTLSAttributes()
hide TLSAttributes
void showTLSAttributes()
show TLSAttributes
GNETLSEditorFrame * myTLSEditorParent
pointer to TLSEditorParent
long onCmdToggleDetectorMode(FXObject *, FXSelector, void *ptr)
Called when user toggle set detector mode.
void updateTLSFile()
update TLSFile module
FXButton * myLoadButton
load button
FXButton * mySaveButton
save button
long onCmdLoadTLSProgram(FXObject *, FXSelector, void *)
load TLS Program from an additional file
TLSFile(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
std::string writeSUMOTime(SUMOTime steps)
FOX needs this.
long onCmdSaveTLSProgram(FXObject *, FXSelector, void *)
save TLS Program to an additional file
GNETLSEditorFrame * myTLSEditorParent
pointer to TLSEditor Parent
long onCmdChangeType(FXObject *, FXSelector, void *)
Called when the user change TLS Type.
long onCmdDisjoinTLS(FXObject *, FXSelector, void *)
Called when the user join TLS.
std::vector< std::string > mySelectedJunctionIDs
selected junction (used for join)
GNETLSEditorFrame * myTLSEditorParent
TLS editor frame parent.
void refreshTLSJunction()
FOX needs this.
FXHorizontalFrame * myJoinControlButtons
frame for accept/cancel buttons
const std::vector< std::string > & getSelectedJunctionIDs() const
get selected junction IDs
long onCmdToggleJoinTLS(FXObject *, FXSelector, void *)
Called when the user join TLS.
std::vector< std::string > myOriginalSelectedJunctionIDs
original selected junction (used for join)
long onCmdRenameTLS(FXObject *, FXSelector, void *)
TLSJunction(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
long onCmdCancelJoin(FXObject *, FXSelector, void *)
cancel join
MFXComboBoxIcon * myTLSTypeComboBox
ComboBox for TLS Types.
MFXToggleButtonTooltip * myJoinTLSToggleButton
Toggle button for join TLS.
void updateTLSJunction()
update TLSJunction module
void toggleJunctionSelected(const GNEJunction *junction)
select or unselect junction in the current TLS
long onCmdAcceptJoin(FXObject *, FXSelector, void *)
accept join
GNEJunction * getCurrentJunction() const
get current modified junction
void setCurrentJunction(GNEJunction *junction)
set current junction
FXLabel * myJunctionIDLabel
label for junction ID
GNEJunction * myCurrentJunction
the junction of the tls is being modified
bool isJunctionSelected(const GNEJunction *junction) const
check if given junction is selected (used fo joining)
MFXTextFieldIcon * myJunctionIDTextField
text field for junction ID
MFXButtonTooltip * myDisjoinTLSButton
button for disjoin TLS
bool isJoiningJunctions() const
is joining junctions
MFXTextFieldIcon * myTLSIDTextField
text field for junction ID
bool setEarliestEnd(const int row, const std::string &value)
set earliestEnd
long onCmdUngroupStates(FXObject *, FXSelector, void *)
Called when the user ungroups states.
GNETLSTable * myPhaseTable
table for selecting and rearranging phases and for changing duration
long onCmdCleanStates(FXObject *, FXSelector, void *)
long onCmdGroupStates(FXObject *, FXSelector, void *)
Called when the user groups states.
void clearPhaseTable()
clear phase thable
MFXButtonTooltip * myGroupSignalsButton
group signals button
bool setVehExt(const int row, const std::string &value)
set vehExt
MFXButtonTooltip * myAddStates
add states button
int buildDefaultPhase(const int row)
build default phase
void updateTLSPhases()
update TLSPhases module
TLSPhases(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
void movePhaseDown(const int row)
move phase down
void initActuatedPhaseTable()
init actuated phase table
void initPhaseTable()
initializes the phase table
void initNEMAPhaseTable()
init NEMA phase table
bool setYellow(const int row, const std::string &value)
set yellow
bool changePhaseValue(const int col, const int row, const std::string &value)
change phase value (state, name, next, etc.)
void initDelayBasePhaseTable()
init delayBase phase table
void movePhaseUp(const int row)
move phase up
bool setMinDur(const int row, const std::string &value)
set minDur
bool setLatestEnd(const int row, const std::string &value)
set latestEnd
MFXButtonTooltip * myCleanStatesButton
clean states button
void updateStateSize(const int col)
update state size
MFXButtonTooltip * myUngroupSignalsButton
ungroup signals button
long onCmdAddUnusedStates(FXObject *, FXSelector, void *)
Called when the user cleans up states.
void initStaticPhaseTable()
init static phase table
GNETLSEditorFrame * myTLSEditorParent
pointer to TLSEditor Parent
bool setDuration(const int col, const int row, const std::string &value)
set duration
bool setMaxDur(const int row, const std::string &value)
set maxDur
void updateTLSColoring()
update TLS coloring
GNETLSTable * getPhaseTable() const
get phase table
void removePhase(const int row)
delete phase
bool setRed(const int row, const std::string &value)
set red
bool setName(const int row, const std::string &value)
set name
bool setState(const int col, const int row, const std::string &value)
set state
void duplicatePhase(const int row)
duplicate phase
void addPhase(const int row, const char c=' ')
add phase
GNETLSEditorFrame * getTLSEditorParent() const
get TLSEditor Parent
bool setNext(const int row, const std::string &value)
set next
void updateCycleDuration(const int col)
recomputes cycle duration and updates label
bool checkHaveModifications() const
check if current TLS was modified
FXButton * mySaveButon
button for save TLS program
void updateTLSPrograms()
update TLSPrograms module
bool initTLSPrograms()
init TLS Definitions
long onCmdDefSwitchTLSProgram(FXObject *, FXSelector, void *)
Called when the user switches a TLS.
MFXComboBoxIcon * myProgramComboBox
the comboBox for selecting the tl-definition to edit
GNETLSEditorFrame * myTLSEditorParent
pointer to GNETLSEditorFrame parent
FXButton * myCancelButon
button for cancel TLS program
void clearTLSProgramss()
clear TLS Definitions
int getNumberOfPrograms() const
get number of programs
long onCmdSaveChanges(FXObject *, FXSelector, void *)
Called when the user presses the save-Button.
void hideTLSPrograms()
hide TLSPrograms
void createTLS(GNEJunction *junction)
FOX needs this.
bool myHaveModifications
whether the current tls was modified
std::vector< NBTrafficLightDefinition * > myTLSPrograms
the list of Definitions for the current junction
FXButton * myDeleteButton
button for delete existent TLS program
long onCmdDiscardChanges(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
void discardChanges(const bool editJunctionAgain)
discard changes
long onCmdCreate(FXObject *, FXSelector, void *)
FXButton * myResetAllButton
button for reset all TLS program
long onCmdResetAll(FXObject *, FXSelector, void *)
Called when the user press button reset all TLS Programs.
FXButton * myResetSingleButton
button for reset TLS program
long onCmdResetCurrentProgram(FXObject *, FXSelector, void *)
Called when the user press button reset current TLS Program.
NBTrafficLightDefinition * getCurrentTLSPrograms() const
get current definition
TLSPrograms(GNETLSEditorFrame *TLSEditorParent)
FOX-declaration.
void showTLSPrograms()
show TLSPrograms
void markAsModified()
mark Program as modified
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user press button delete TLS Program.
const std::string getCurrentTLSProgramID() const
get current program ID
FXButton * myCreateButton
button for create new TLS program
GNETLSEditorFrame::TLSFile * myTLSFile
module for load/Save TLS Programs
GNETLSEditorFrame::TLSPrograms * myTLSPrograms
module for TLS Definition
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
GNEOverlappedInspection * myOverlappedInspection
Overlapped Inspection.
GNETLSEditorFrame::TLSPhases * getTLSPhases() const
get module for TLS Phases
GNETLSEditorFrame::TLSAttributes * getTLSAttributes() const
get module for TLS attributes
GNETLSEditorFrame::TLSAttributes * myTLSAttributes
module for TLS attributes
static std::string varDurString(SUMOTime dur)
convert duration (potentially undefined) to string
bool isTLSSaved()
check if modifications in TLS was saved
void editJunction(GNEJunction *junction)
edits the traffic light for the given junction
GNETLSEditorFrame::TLSPhases * myTLSPhases
module for TLS Phases
void selectedOverlappedElement(GNEAttributeCarrier *AC)
open GNEAttributesCreator extended dialog (can be reimplemented in frame children)
GNETLSEditorFrame(GNEViewParent *viewParent, GNEViewNet *viewNet)
Constructor.
std::map< int, std::vector< GNEInternalLane * > > myInternalLanes
the internal lanes belonging to the current junction indexed by their tl-index
void updateModules()
update modules
bool parseTLSPrograms(const std::string &file)
parse TLS Programs from a file
bool controlsEdge(GNEEdge *edge) const
whether the given edge is controlled by the currently edited tlDef
static const std::string getSteps2Time(const SUMOTime value)
converts to SUMOTime
void buildInternalLanes(const NBTrafficLightDefinition *tlDef)
builds internal lanes for the given tlDef
const NBTrafficLightLogic::PhaseDefinition & getPhase(const int index)
get certain phase of the current traffic light
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
GNETLSEditorFrame::TLSJunction * getTLSJunction() const
get module for TLS Junction
static SUMOTime getSUMOTime(const std::string &value)
converts to SUMOTime
~GNETLSEditorFrame()
Destructor.
NBLoadedSUMOTLDef * myEditedDef
the traffic light definition being edited
void frameWidthUpdated()
function called after setting new width in current frame
void editTLS(GNEViewNetHelper::ViewObjectsSelector &viewObjects, const Position &clickedPosition, const bool shiftKeyPressed)
edits the traffic light for the given clicked junction
GNETLSEditorFrame::TLSJunction * myTLSJunction
module for TLS Junction
GNETLSEditorFrame::TLSPrograms * getTLSPrograms() const
get module for TLS Definition
void cleanup()
cleans up previous lanes
void show()
show inspector frame
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
class used to group all variables related with objects under cursor after a click over view
GNEAdditional * getAdditionalFront() const
get front additional element or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
const std::vector< GNEJunction * > & getJunctions() const
get vector with junctions
GNEViewParent * getViewParent() const
get the net object
A single child window which contains a view of the simulation area.
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
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
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
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)
Options
GroupBoxModule options.
MFXGroupBoxModule(GNEFrame *frame, const std::string &text, const int options=Options::COLLAPSIBLE)
constructor for frames
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:116
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition MFXUtils.cpp:145
A loaded (complete) traffic light logic.
void setProgramID(const std::string &programID)
Sets the programID.
A definition of a pedestrian crossing.
Definition NBNode.h:135
int tlLinkIndex
the traffic light index of this crossing (if controlled)
Definition NBNode.h:162
Represents a single node (junction) during network building.
Definition NBNode.h:66
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node).
Definition NBNode.h:345
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:336
A traffic light logics which must be computed (only nodes/edges are given).
Definition NBOwnTLDef.h:44
The base class for traffic light logic definitions.
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
const std::string & getProgramID() const
Returns the ProgramID.
TrafficLightType getType() const
get the algorithm type (static etc..)
virtual void setProgramID(const std::string &programID)
Sets the programID.
NBTrafficLightLogic * compute(const OptionsCont &oc)
Computes the traffic light logic.
SUMOTime getOffset()
Returns the offset.
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
static const SUMOTime UNSPECIFIED_DURATION
The definition of a single phase of the logic.
A container for traffic light definitions and built programs.
bool exist(const std::string &newID, bool requireComputed=true) const
check if exists a definition with the given ID
bool removeProgram(const std::string id, const std::string programID, bool del=true)
Removes a program of a logic definition from the dictionary.
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
NBTrafficLightLogic * getLogic(const std::string &id, const std::string &programID) const
Returns the computed logic for the given name.
std::string getNextProgramID(const std::string &id) const
Returns a new (unused) programID for the given traffic light.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
A SUMO-compliant built logic for a traffic light.
Importer for edge connections stored in XML.
const std::set< std::string > & getSeenIDs()
static void writeTrafficLight(OutputDevice &into, const NBTrafficLightLogic *logic)
writes a single traffic light logic to the given device
const std::string & getID() const
Returns the id.
Definition Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
static bool areParametersValid(const std::string &value, bool report=false, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.
void append(const PositionVector &v, double sameThreshold=2.0)
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
PositionVector reverse() const
reverse position vector
static const RGBColor BLACK
Definition RGBColor.h:196
static const RGBColor RED
named colors
Definition RGBColor.h:188
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
static StringBijection< XMLFileExtension > XMLFileExtensions
XML file Extensions.
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
A structure which describes a connection between edges or lanes.
Definition NBEdge.h:201
PositionVector viaShape
shape of via
Definition NBEdge.h:282
PositionVector shape
shape of Connection
Definition NBEdge.h:270