SUMO - Simulation of Urban MObility
GNETLSEditorFrame.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Widget for modifying traffic lights
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <iostream>
41 
42 #include "GNETLSEditorFrame.h"
43 #include "GNEViewNet.h"
44 #include "GNEViewParent.h"
45 #include "GNENet.h"
46 #include "GNEJunction.h"
47 #include "GNEEdge.h"
48 #include "GNELane.h"
49 #include "GNEUndoList.h"
50 #include "GNEInternalLane.h"
51 #include "GNEChange_TLS.h"
52 
53 // ===========================================================================
54 // FOX callback mapping
55 // ===========================================================================
56 FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[] = {
57  FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GNETLSEditorFrame::onCmdCancel),
58  FXMAPFUNC(SEL_COMMAND, MID_OK, GNETLSEditorFrame::onCmdOK),
70  FXMAPFUNC(SEL_DESELECTED, MID_GNE_PHASE_TABLE, GNETLSEditorFrame::onCmdPhaseSwitch),
79  FXMAPFUNC(SEL_UPDATE, MID_CANCEL, GNETLSEditorFrame::onUpdModified),
80  FXMAPFUNC(SEL_UPDATE, MID_OK, GNETLSEditorFrame::onUpdModified),
81 };
82 
83 
84 // Object implementation
85 FXIMPLEMENT(GNETLSEditorFrame, FXVerticalFrame, GNETLSEditorFrameMap, ARRAYNUMBER(GNETLSEditorFrameMap))
86 
87 
88 // ===========================================================================
89 // method definitions
90 // ===========================================================================
91 GNETLSEditorFrame::GNETLSEditorFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet):
92  GNEFrame(horizontalFrameParent, viewNet, "Edit Traffic Light"),
93  myTableFont(new FXFont(getApp(), "Courier New", 9)),
94  myCurrentJunction(0),
95  myHaveModifications(false),
96  myEditedDef(0) {
97  // create groupbox for description
98  myGroupBoxJunction = new FXGroupBox(myContentFrame, "Junction", GUIDesignGroupBoxFrame);
99  // Create frame for junction ID
100  FXHorizontalFrame* junctionIDFrame = new FXHorizontalFrame(myGroupBoxJunction, GUIDesignAuxiliarHorizontalFrame);
101  myLabelJunctionID = new FXLabel(junctionIDFrame, "Junction ID", 0, GUIDesignLabelAttribute);
102  myTextFieldJunctionID = new FXTextField(junctionIDFrame, GUIDesignTextFieldNCol, this, MID_GNE_TLS_SELECT_JUNCTION, GUIDesignTextField);
103  myTextFieldJunctionID->setEditable(false);
104  // create frame for junction status
105  FXHorizontalFrame* junctionIDStatus = new FXHorizontalFrame(myGroupBoxJunction, GUIDesignAuxiliarHorizontalFrame);
106  myLabelJunctionStatus = new FXLabel(junctionIDStatus, "Status", 0, GUIDesignLabelAttribute);
107  myTextFieldJunctionStatus = new FXTextField(junctionIDStatus, GUIDesignTextFieldNCol, this, MID_GNE_TLS_UPDATE_STATUS, GUIDesignTextField);
108  myTextFieldJunctionStatus->setEditable(false);
109 
110  // create groupbox for tl df
111  myGroupBoxTLSDef = new FXGroupBox(myContentFrame, "Traffic lights definition", GUIDesignGroupBoxFrame);
112 
113  // create create tlDef button
114  myNewTLProgram = new FXButton(myGroupBoxTLSDef, "Create TLS\t\tCreate a new traffic light program", 0, this, MID_GNE_DEF_CREATE, GUIDesignButton);
115 
116  // create delete tlDef button
117  myDeleteTLProgram = new FXButton(myGroupBoxTLSDef, "Delete TLS\t\tDelete a traffic light program. If all programs are deleted the junction turns into a priority junction.", 0, this, MID_GNE_DEF_DELETE, GUIDesignButton);
118 
119  // create TLS attributes
120  myTLSAttributes = new TLSAttributes(myContentFrame, this);
121 
122  // create groupbox for phases
123  myGroupBoxPhases = new FXGroupBox(myContentFrame, "Phases", GUIDesignGroupBoxFrame);
124 
125  // create and configure phase table
126  myTableScroll = new FXScrollWindow(myGroupBoxPhases, LAYOUT_FILL_X | LAYOUT_FIX_HEIGHT);
127  myPhaseTable = new FXTable(myTableScroll, this, MID_GNE_PHASE_TABLE, GUIDesignTableLimitedHeight);
128  myPhaseTable->setColumnHeaderMode(LAYOUT_FIX_HEIGHT);
129  myPhaseTable->setColumnHeaderHeight(0);
130  myPhaseTable->setRowHeaderMode(LAYOUT_FIX_WIDTH);
131  myPhaseTable->setRowHeaderWidth(0);
132  myPhaseTable->hide();
133  myPhaseTable->setFont(myTableFont);
134  myPhaseTable->setHelpText("phase duration in seconds | phase state");
135 
136  // create total duration info label
137  myCycleDuration = new FXLabel(myGroupBoxPhases, "", 0, GUIDesignLabelLeft);
138 
139  // create new phase button
140  myInsertDuplicateButton = new FXButton(myGroupBoxPhases, "Copy Phase\t\tInsert duplicate phase after selected phase", 0, this, MID_GNE_PHASE_CREATE, GUIDesignButton);
141 
142  // create delete phase button
143  myDeleteSelectedPhaseButton = new FXButton(myGroupBoxPhases, "Delete Phase\t\tDelete selected phase", 0, this, MID_GNE_PHASE_DELETE, GUIDesignButton);
144 
145  // create groupbox for modifications
146  myGroupBoxModifications = new FXGroupBox(myContentFrame, "Modifications", GUIDesignGroupBoxFrame);
147 
148  // create discard modifications buttons
149  myDiscardModificationsButtons = new FXButton(myGroupBoxModifications, "Cancel\t\tDiscard program modifications (Esc)", 0, this, MID_CANCEL, GUIDesignButton);
150 
151  // create save modifications button
152  mySaveModificationsButtons = new FXButton(myGroupBoxModifications, "Save\t\tSave program modifications (Enter)", 0, this, MID_OK, GUIDesignButton);
153 
154 
155  // "Add 'off' program"
156  /*
157  new FXButton(myContentFrame, "Add \"Off\"-Program\t\tAdds a program for switching off this traffic light",
158  0, this, MID_GNE_DEF_ADDOFF, GUIDesignButton);
159  */
160 
161  updateDescription();
162 }
163 
164 
166  delete myTableFont;
167  cleanup();
168 }
169 
170 
171 void
173  if (myCurrentJunction == 0 || (!myHaveModifications && (junction != myCurrentJunction))) {
174  onCmdCancel(0, 0, 0);
175  myViewNet->getUndoList()->p_begin("modifying traffic light definition");
176  myCurrentJunction = junction;
180  } else {
181  myViewNet->setStatusBarText("Unsaved modifications. Abort or Save");
182  }
183 }
184 
185 
186 long
187 GNETLSEditorFrame::onCmdCancel(FXObject*, FXSelector, void*) {
188  if (myCurrentJunction != 0) {
190  cleanup();
191  myViewNet->update();
192  }
193  return 1;
194 }
195 
196 
197 long
198 GNETLSEditorFrame::onCmdOK(FXObject*, FXSelector, void*) {
199  if (myCurrentJunction != 0) {
200  if (myHaveModifications) {
202  std::vector<NBNode*> nodes = oldDefinition->getNodes();
203  for (auto it : nodes) {
204  GNEJunction* junction = myViewNet->getNet()->retrieveJunction(it->getID());
205  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, oldDefinition, false), true);
206  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myEditedDef, true), true);
207  }
208  myEditedDef = 0;
210  cleanup();
211  myViewNet->update();
212  } else {
213  onCmdCancel(0, 0, 0);
214  }
215  }
216  return 1;
217 }
218 
219 
220 long
221 GNETLSEditorFrame::onCmdDefCreate(FXObject*, FXSelector, void*) {
222  GNEJunction* junction = myCurrentJunction;
223  onCmdCancel(0, 0, 0); // abort because we onCmdOk assumes we wish to save an edited definition
226  } else {
227  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, 0, true, true), true);
228  }
229  editJunction(junction);
230  return 1;
231 }
232 
233 
234 long
235 GNETLSEditorFrame::onCmdDefDelete(FXObject*, FXSelector, void*) {
236  GNEJunction* junction = myCurrentJunction;
237  const bool changeType = myTLSAttributes->getNumberOfTLSDefinitions() == 1;
238  onCmdCancel(0, 0, 0); // abort because onCmdOk assumes we wish to save an edited definition
239  if (changeType) {
241  } else {
243  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, tlDef, false), true);
244  }
245  return 1;
246 }
247 
248 
249 long
250 GNETLSEditorFrame::onCmdDefSwitch(FXObject*, FXSelector, void*) {
251  assert(myCurrentJunction != 0);
254  // logic may not have been recomputed yet. recompute to be sure
257  NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
258  if (tllogic != 0) {
259  // now we can be sure that the tlDef is up to date (i.e. re-guessed)
260  buildIinternalLanes(tlDef);
261  // create working copy from original def
262  delete myEditedDef;
263  myEditedDef = new NBLoadedSUMOTLDef(tlDef, tllogic);
264 
266  initPhaseTable();
268  myCycleDuration->show();
269  } else {
270  // tlDef has no valid logic (probably because id does not control any links
271  onCmdCancel(0, 0, 0);
272  myViewNet->setStatusBarText("Traffic light does not control any links");
273  }
274  return 1;
275 }
276 
277 
278 long
279 GNETLSEditorFrame::onUpdDefSwitch(FXObject* o, FXSelector, void*) {
280  const bool enable = myTLSAttributes->getNumberOfTLSDefinitions() > 0 && !myHaveModifications;
281  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
282  return 1;
283 }
284 
285 
286 long
287 GNETLSEditorFrame::onUpdNeedsDef(FXObject* o, FXSelector, void*) {
288  const bool enable = myTLSAttributes->getNumberOfTLSDefinitions() > 0;
289  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
290  return 1;
291 }
292 
293 
294 long
295 GNETLSEditorFrame::onUpdNeedsDefAndPhase(FXObject* o, FXSelector, void*) {
296  // do not delete the last phase
297  const bool enable = myTLSAttributes->getNumberOfTLSDefinitions() > 0 && myPhaseTable->getNumRows() > 1;
298  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
299  return 1;
300 }
301 
302 
303 long
304 GNETLSEditorFrame::onUpdDefCreate(FXObject* o, FXSelector, void*) {
305  const bool enable = myCurrentJunction != 0 && !myHaveModifications;
306  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
307  return 1;
308 }
309 
310 
311 long
312 GNETLSEditorFrame::onUpdModified(FXObject* o, FXSelector, void*) {
313  bool enable = myHaveModifications;
314  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
315  return 1;
316 }
317 
318 
319 
320 long
321 GNETLSEditorFrame::onCmdDefOffset(FXObject*, FXSelector, void*) {
322  myHaveModifications = true;
324  return 1;
325 }
326 
327 
328 long
329 GNETLSEditorFrame::onCmdDefRename(FXObject*, FXSelector, void*) {
330  return 1;
331 }
332 
333 
334 long
335 GNETLSEditorFrame::onCmdDefSubRename(FXObject*, FXSelector, void*) {
336  return 1;
337 }
338 
339 
340 long
341 GNETLSEditorFrame::onCmdDefAddOff(FXObject*, FXSelector, void*) {
342  return 1;
343 }
344 
345 
346 long
347 GNETLSEditorFrame::onCmdGuess(FXObject*, FXSelector, void*) {
348  return 1;
349 }
350 
351 
352 long
353 GNETLSEditorFrame::onCmdPhaseSwitch(FXObject*, FXSelector, void*) {
354  const int index = myPhaseTable->getCurrentRow();
355  const NBTrafficLightLogic::PhaseDefinition& phase = getPhases()[index];
356  myPhaseTable->selectRow(index);
357  // need not hold since links could have been deleted somewhere else and indices may be reused
358  // assert(phase.state.size() == myInternalLanes.size());
359  for (auto it : myInternalLanes) {
360  int tlIndex = it.first;
361  std::vector<GNEInternalLane*> lanes = it.second;
362  assert(tlIndex >= 0);
363  assert(tlIndex < (int)phase.state.size());
364  for (auto it_lane : lanes) {
365  it_lane->setLinkState((LinkState)phase.state[tlIndex]);
366  }
367  }
368  myViewNet->update();
369  return 1;
370 }
371 
372 
373 long
374 GNETLSEditorFrame::onCmdPhaseCreate(FXObject*, FXSelector, void*) {
375  myHaveModifications = true;
376  // allows insertion at first position by deselecting via arrow keys
377  int newIndex = myPhaseTable->getSelStartRow() + 1;
378  int oldIndex = MAX2(0, myPhaseTable->getSelStartRow());
379  // copy current row
380  const bool fixed = myEditedDef->getType() == TLTYPE_STATIC;
381  const SUMOTime duration = getSUMOTime(myPhaseTable->getItemText(oldIndex, 0));
382  const std::string state = myPhaseTable->getItemText(oldIndex, fixed ? 1 : 3).text();
383  myEditedDef->getLogic()->addStep(duration, state, newIndex);
384  myPhaseTable->setCurrentItem(newIndex, 0);
385  initPhaseTable(newIndex);
386  myPhaseTable->setFocus();
387  return 1;
388 }
389 
390 
391 long
392 GNETLSEditorFrame::onCmdPhaseDelete(FXObject*, FXSelector, void*) {
393  myHaveModifications = true;
394  const int newRow = MAX2((int)0, (int)myPhaseTable->getCurrentRow() - 1);
395  myEditedDef->getLogic()->deletePhase(myPhaseTable->getCurrentRow());
396  initPhaseTable(newRow);
397  myPhaseTable->setFocus();
398  return 1;
399 }
400 
401 
402 long
403 GNETLSEditorFrame::onCmdPhaseEdit(FXObject*, FXSelector, void* ptr) {
404  /* @note: there is a bug when copying/pasting rows: when this handler is
405  * called the value of the cell is not yet updated. This means you have to
406  * click inside the cell and hit enter to actually update the value */
407  FXTablePos* tp = (FXTablePos*)ptr;
408  FXString value = myPhaseTable->getItemText(tp->row, tp->col);
409  const bool fixed = myEditedDef->getType() == TLTYPE_STATIC;
410  if (tp->col == 0) {
411  // duration edited
412  if (GNEAttributeCarrier::canParse<double>(value.text())) {
413  SUMOTime duration = getSUMOTime(value);
414  if (duration > 0) {
415  myEditedDef->getLogic()->setPhaseDuration(tp->row, duration);
416  myHaveModifications = true;
418  return 1;
419  }
420  }
421  // input error, reset value
422  myPhaseTable->setItemText(tp->row, 0, toString(STEPS2TIME(getPhases()[tp->row].duration)).c_str());
423  } else if (!fixed && tp->col == 1) {
424  // minDur edited
425  if (GNEAttributeCarrier::canParse<double>(value.text())) {
426  SUMOTime minDur = getSUMOTime(value);
427  if (minDur > 0) {
428  myEditedDef->getLogic()->setPhaseMinDuration(tp->row, minDur);
429  myHaveModifications = true;
430  return 1;
431  }
432  } else if (StringUtils::prune(value.text()).empty()) {
434  myHaveModifications = true;
435  return 1;
436  }
437  // input error, reset value
438  myPhaseTable->setItemText(tp->row, 1, varDurString(getPhases()[tp->row].minDur).c_str());
439  } else if (!fixed && tp->col == 2) {
440  // minDur edited
441  if (GNEAttributeCarrier::canParse<double>(value.text())) {
442  SUMOTime maxDur = getSUMOTime(value);
443  if (maxDur > 0) {
444  myEditedDef->getLogic()->setPhaseMaxDuration(tp->row, maxDur);
445  myHaveModifications = true;
446  return 1;
447  }
448  } else if (StringUtils::prune(value.text()).empty()) {
450  myHaveModifications = true;
451  return 1;
452  }
453  // input error, reset value
454  myPhaseTable->setItemText(tp->row, 2, varDurString(getPhases()[tp->row].maxDur).c_str());
455  } else {
456  // state edited
457  try {
458  // insert phase with new step and delete the old phase
459  myEditedDef->getLogic()->addStep(getPhases()[tp->row].duration, value.text(), tp->row);
460  myEditedDef->getLogic()->deletePhase(tp->row + 1);
461  myHaveModifications = true;
462  onCmdPhaseSwitch(0, 0, 0);
463  } catch (ProcessError) {
464  // input error, reset value
465  myPhaseTable->setItemText(tp->row, 1, getPhases()[tp->row].state.c_str());
466  }
467  }
468  return 1;
469 }
470 
471 
472 void
474  if (myCurrentJunction == 0) {
475  myTextFieldJunctionID->setText("");
476  myTextFieldJunctionStatus->setText("");
477  } else {
479  myTextFieldJunctionID->setText(nbn->getID().c_str());
480  if (!nbn->isTLControlled()) {
481  myTextFieldJunctionStatus->setText("uncontrolled");
482  } else {
483  myTextFieldJunctionStatus->setText(myHaveModifications ? "modified" : "unmodified");
484  }
485  }
486 }
487 
488 
489 void
491  if (myCurrentJunction) {
493  }
494  // clean data structures
495  myCurrentJunction = 0;
496  myHaveModifications = false;
497  delete myEditedDef;
498  myEditedDef = 0;
499  buildIinternalLanes(0); // only clears
500  // clean up controls
502  initPhaseTable(); // only clears when there are no definitions
503  myCycleDuration->hide();
505 }
506 
507 
508 void
511  // clean up previous objects
512  for (auto it : myInternalLanes) {
513  for (auto it_intLanes : it.second) {
514  rtree.removeAdditionalGLObject(it_intLanes);
515  delete it_intLanes;
516  }
517  }
518  myInternalLanes.clear();
519  // create new internal lanes
520  if (tlDef != 0) {
521  const int NUM_POINTS = 10;
522  assert(myCurrentJunction);
524  std::string innerID = ":" + nbn->getID(); // see NWWriter_SUMO::writeInternalEdges
525  const NBConnectionVector& links = tlDef->getControlledLinks();
526  for (auto it : links) {
527  int tlIndex = it.getTLIndex();
528  PositionVector shape = nbn->computeInternalLaneShape(it.getFrom(), NBEdge::Connection(it.getFromLane(),
529  it.getTo(), it.getToLane()), NUM_POINTS);
530  GNEInternalLane* ilane = new GNEInternalLane(this, innerID + '_' + toString(tlIndex), shape, tlIndex);
531  rtree.addAdditionalGLObject(ilane);
532  myInternalLanes[tlIndex].push_back(ilane);
533  }
534  for (auto c : nbn->getCrossings()) {
535  GNEInternalLane* ilane = new GNEInternalLane(this, c->id, c->shape, c->tlLinkNo);
536  rtree.addAdditionalGLObject(ilane);
537  myInternalLanes[c->tlLinkNo].push_back(ilane);
538  }
539  }
540 }
541 
542 
543 std::string
546 }
547 
548 void
550  myPhaseTable->setVisibleRows(1);
551  myPhaseTable->setVisibleColumns(2);
552  myPhaseTable->hide();
554  const bool fixed = myEditedDef->getType() == TLTYPE_STATIC;
555  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
556  myPhaseTable->setTableSize((int)phases.size(), fixed ? 2 : 4);
557  myPhaseTable->setVisibleRows((int)phases.size());
558  myPhaseTable->setVisibleColumns(fixed ? 2 : 4);
559  for (int row = 0; row < (int)phases.size(); row++) {
560  myPhaseTable->setItemText(row, 0, toString(STEPS2TIME(phases[row].duration)).c_str());
561  if (!fixed) {
562  myPhaseTable->setItemText(row, 1, varDurString(phases[row].minDur).c_str());
563  myPhaseTable->setItemText(row, 2, varDurString(phases[row].maxDur).c_str());
564  }
565  myPhaseTable->setItemText(row, fixed ? 1 : 3, phases[row].state.c_str());
566  myPhaseTable->getItem(row, 1)->setJustify(FXTableItem::LEFT);
567  }
568  myPhaseTable->fitColumnsToContents(0, fixed ? 2 : 4);
569  myPhaseTable->setHeight((int)phases.size() * 21); // experimental
570  myPhaseTable->setCurrentItem(index, 0);
571  myPhaseTable->selectRow(index, true);
572  myPhaseTable->show();
573  myPhaseTable->setFocus();
574 
575  myTableScroll->setHeight(myPhaseTable->getHeight() + 10);
576  }
577  update();
578 }
579 
580 
581 const std::vector<NBTrafficLightLogic::PhaseDefinition>&
583  return myEditedDef->getLogic()->getPhases();
584 }
585 
586 
587 void
589  myHaveModifications = true;
590  if (myViewNet->changeAllPhases()) {
591  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
592  for (int row = 0; row < (int)phases.size(); row++) {
593  myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
594  }
595  } else {
596  myEditedDef->getLogic()->setPhaseState(myPhaseTable->getCurrentRow(), lane->getTLIndex(), lane->getLinkState());
597  }
598  initPhaseTable(myPhaseTable->getCurrentRow());
599  myPhaseTable->setFocus();
600 }
601 
602 
603 void
604 GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* eventData) {
605  if (myEditedDef != 0) {
606  myHaveModifications = true;
608  std::set<std::string> fromIDs;
609  fromIDs.insert(lane->getMicrosimID());
610  GNEEdge& edge = lane->getParentEdge();
611  // if neither the lane nor its edge are selected, apply changes to the whole edge
613  for (auto it_lane : edge.getLanes()) {
614  fromIDs.insert(it_lane->getMicrosimID());
615  }
616  } else {
617  // if the edge is selected, apply changes to all lanes of all selected edges
618  if (gSelected.isSelected(GLO_EDGE, edge.getGlID())) {
619  std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(true);
620  for (auto it : edges) {
621  for (auto it_lane : it->getLanes()) {
622  fromIDs.insert(it_lane->getMicrosimID());
623  }
624  }
625  }
626  // if the lane is selected, apply changes to all selected lanes
627  if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
628  std::vector<GNELane*> lanes = myViewNet->getNet()->retrieveLanes(true);
629  for (auto it_lane : lanes) {
630  fromIDs.insert(it_lane->getMicrosimID());
631  }
632  }
633 
634  }
635  // set new state for all connections from the chosen lane IDs
636  for (auto it : links) {
637  if (fromIDs.count(it.getFrom()->getLaneID(it.getFromLane())) > 0) {
638  std::vector<GNEInternalLane*> lanes = myInternalLanes[it.getTLIndex()];
639  for (auto it_lane : lanes) {
640  it_lane->onDefault(obj, sel, eventData);
641  }
642  }
643  }
644  }
645 }
646 
647 
648 bool
650  if (myEditedDef != 0) {
652  for (auto it : links) {
653  if (it.getFrom()->getID() == edge.getMicrosimID()) {
654  return true;
655  }
656  }
657  }
658  return false;
659 }
660 
661 
662 SUMOTime
663 GNETLSEditorFrame::getSUMOTime(const FXString& string) {
664  assert(GNEAttributeCarrier::canParse<double>(string.text()));
665  return TIME2STEPS(GNEAttributeCarrier::parse<double>(string.text()));
666 }
667 
668 
669 void
671  SUMOTime cycleDuration = 0;
672  for (auto it : getPhases()) {
673  cycleDuration += it.duration;
674  }
675  std::string text = "Cycle time: " + toString(STEPS2TIME(cycleDuration));
676  myCycleDuration->setText(text.c_str());
677 }
678 
679 
680 // ---------------------------------------------------------------------------
681 // GNETLSEditorFrame::TLSAttributes - methods
682 // ---------------------------------------------------------------------------
683 
685  FXGroupBox(parent, "Traffic light Attributes", GUIDesignGroupBoxFrame),
686  myTLSEditorParent(TLSEditorParent) {
687 
688  // create frame, label and textfield for name (By default disabled)
689  FXHorizontalFrame* nameFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
690  myNameLabel = new FXLabel(nameFrame, "ID", 0, GUIDesignLabelAttribute);
692  myNameTextField->disable();
693 
694  // create frame, label and comboBox for Program (By default hidden)
695  FXHorizontalFrame* programFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
696  myProgramLabel = new FXLabel(programFrame, "Program", 0, GUIDesignLabelAttribute);
698  myProgramComboBox->disable();
699 
700  // create frame, label and TextField for Offset (By default disabled)
701  FXHorizontalFrame* offsetFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
702  myOffsetLabel = new FXLabel(offsetFrame, "Offset", 0, GUIDesignLabelAttribute);
704  myOffsetTextField->disable();
705 }
706 
707 
709 
710 
711 void
713  assert(junction);
714  myTLSDefinitions.clear();
715  // enable name TextField
716  myNameTextField->enable();
717  // enable Offset
718  myOffsetTextField->enable();
719  // obtain TLSs
720  for (auto it : junction->getNBNode()->getControllingTLS()) {
721  myTLSDefinitions.push_back(it);
722  myNameTextField->setText(it->getID().c_str());
723  myNameTextField->enable();
724  myProgramComboBox->appendItem(it->getProgramID().c_str());
725  }
726  if (myTLSDefinitions.size() > 0) {
727  myProgramComboBox->enable();
728  myProgramComboBox->setCurrentItem(0);
729  myProgramComboBox->setNumVisible(myProgramComboBox->getNumItems());
731  }
732 }
733 
734 
735 void
737  // clear definitions
738  myTLSDefinitions.clear();
739  // clear and disable name TextField
740  myNameTextField->setText("");
741  myNameTextField->disable();
742  // clear and disable myProgramComboBox
743  myProgramComboBox->clearItems();
744  myProgramComboBox->disable();
745  // clear and disable Offset TextField
746  myOffsetTextField->setText("");
747  myOffsetTextField->disable();
748 }
749 
750 
753  return myTLSDefinitions.at(myProgramComboBox->getCurrentItem());
754 }
755 
756 
757 int
759  return (int)myTLSDefinitions.size();
760 }
761 
762 
763 int
765  return myProgramComboBox->getNumItems();
766 }
767 
768 
769 SUMOTime
771  return getSUMOTime(myOffsetTextField->getText());
772 }
773 
774 
775 void
777  myOffsetTextField->setText(toString(STEPS2TIME(offset)).c_str());
778 }
779 
780 /****************************************************************************/
int NUM_POINTS
TLIndexMap myInternalLanes
long onCmdGuess(FXObject *, FXSelector, void *)
Called when the user presses the button Guess.
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:944
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
bool controlsEdge(GNEEdge &edge) const
whether the given edge is controlled by the currently edited tlDef
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:165
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:197
FXTable * myPhaseTable
table for selecting and rearranging phases and for changing duration
long onUpdNeedsDefAndPhase(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition an dphase.
long onCmdPhaseDelete(FXObject *, FXSelector, void *)
Called when the user deletes a Phase.
long onCmdDefCreate(FXObject *, FXSelector, void *)
Called when the user creates a TLS.
bool changeAllPhases() const
change all phases
Definition: GNEViewNet.cpp:334
void setPhaseMaxDuration(int phaseIndex, SUMOTime duration)
FXLabel * myOffsetLabel
offset label
void setOffset(SUMOTime offset)
Sets the offset of this tls.
A loaded (complete) traffic light logic.
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by NETEDIT)
A container for traffic light definitions and built programs.
A SUMO-compliant built logic for a traffic light.
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:291
#define GUIDesignTableLimitedHeight
design for table extended over frame but with limited Height
Definition: GUIDesigns.h:406
TLSAttributes * myTLSAttributes
TLS attributes.
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:193
TrafficLightType getType() const
get the algorithm type (static etc..)
long onCmdPhaseSwitch(FXObject *, FXSelector, void *)
Called when the user switchs a Phase.
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
void removeAdditionalGLObject(GUIGlObject *o)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition: SUMORTree.h:141
NBNode * getNBNode() const
Return net build node.
The base class for traffic light logic definitions.
FXScrollWindow * myTableScroll
window for oversized phase tables
void setPhaseMinDuration(int phaseIndex, SUMOTime duration)
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Definition: NBNode.cpp:617
FXComboBox * myProgramComboBox
the comboBox for selecting the tl-definition to edit
T MAX2(T a, T b)
Definition: StdDefs.h:74
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
static const SUMOTime UNSPECIFIED_DURATION
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
void editJunction(GNEJunction *junction)
edits the traffic light for the given junction
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:85
int getNumberOfPrograms() const
get number of programs
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
NBTrafficLightDefinition * getCurrentTLSDefinition() const
get current definition
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
The definition of a single phase of the logic.
int getNumberOfTLSDefinitions() const
get number of definitions
FXLabel * myProgramLabel
program label
long onUpdNeedsDef(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition.
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
FXFont * myTableFont
font for the phase table
GUIGlID getGlID() const
Returns the numerical id of the object.
long onCmdDefDelete(FXObject *, FXSelector, void *)
Called when the user deletes a TLS.
long onCmdDefOffset(FXObject *, FXSelector, void *)
Called when the user changes the offset of a TLS.
long onCmdDefSwitch(FXObject *, FXSelector, void *)
Called when the user switchs a TLS.
long onCmdDefAddOff(FXObject *, FXSelector, void *)
Called when the user adds a OFF.
GNEUndoList * getUndoList() const
get the undoList object
GNEViewNet * myViewNet
the window to inform when the tls is modfied
Definition: GNEFrame.h:95
void updateDescription() const
update descrition
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
SUMOTime getOffset() const
get current offset in SUMOTIme
const std::string & getID() const
Returns the id.
Definition: Named.h:66
void clearTLSAttributes()
clear TLS attributes
GNETLSEditorFrame * myTLSEditorParent
pointer to TLSEditorParent
definition related controls
Definition: GUIAppEnum.h:539
FXTextField * myNameTextField
name text field
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:296
#define GUIDesignTextField
Definition: GUIDesigns.h:41
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
void initTLSAttributes(GNEJunction *junction)
initializes the definitions and corresponding listbox
long onCmdCancel(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1085
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:92
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:886
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames ...
Definition: GUIDesigns.h:244
A list of positions.
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
long onUpdDefCreate(FXObject *, FXSelector, void *)
Called when occurs an update of create definition.
void buildIinternalLanes(NBTrafficLightDefinition *tlDef)
builds internal lanes for the given tlDef
bool myHaveModifications
whether the current tls was modified
Cancel-button pressed.
Definition: GUIAppEnum.h:65
long onCmdPhaseEdit(FXObject *, FXSelector, void *)
Called when the user edits a Phase.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
std::string state
The state definition.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
void computeJunction(GNEJunction *junction)
trigger recomputation of junction shape and logic param[in] window The window to inform about delay ...
Definition: GNENet.cpp:1216
~GNETLSEditorFrame()
Destructor.
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
NBTrafficLightLogic * getLogic()
Returns the internal logic.
FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[]
delete phase thable
Definition: GUIAppEnum.h:555
int getTLIndex() const
get Traffic Light index
void p_abort()
reverts and discards ALL active command groups
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
SUMORTree & getVisualisationSpeedUp()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.cpp:202
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
static SUMOTime getSUMOTime(const FXString &string)
converts to SUMOTime
SUMOTime getOffset() const
Returns the offset of first switch.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:58
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:50
NBTrafficLightLogic * getLogic(const std::string &id, const std::string &programID) const
Returns the computed logic for the given name.
long onUpdDefSwitch(FXObject *, FXSelector, void *)
Called when occurs an update of switch definition.
#define GUIDesignButton
Definition: GUIDesigns.h:57
void updateCycleDuration()
recomputes cycle duration and updates label
static std::string varDurString(SUMOTime dur)
convert duration (potentially undefined) to string
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:52
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:599
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:932
replace program with a newly guessed program
Definition: GUIAppEnum.h:537
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:219
TLSAttributes(FXComposite *parent, GNETLSEditorFrame *TLSEditorParent)
constructor
long onCmdOK(FXObject *, FXSelector, void *)
Ok-button pressed.
Definition: GUIAppEnum.h:63
long onCmdDefSubRename(FXObject *, FXSelector, void *)
Called when the user sub-renames a TLS.
an edge
void setOffset(SUMOTime offset)
set new offset
GNENet * getNet() const
get the net object
GNEJunction * myCurrentJunction
the junction of the tls is being modified
void text()
Definition: gl2psTest.c:260
const std::vector< NBTrafficLightLogic::PhaseDefinition > & getPhases()
the phase of the current traffic light
void setPhaseDuration(int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by NETEDIT)
#define GUIDesignTextFieldReal
text field extended over Frame with thick frame and limited to Doubles/doubles
Definition: GUIDesigns.h:47
long onCmdPhaseCreate(FXObject *, FXSelector, void *)
Called when the user creates a Phase.
create phase thable
Definition: GUIAppEnum.h:553
Represents a single node (junction) during network building.
Definition: NBNode.h:75
void setStatusBarText(const std::string &text)
set staturBar text
Definition: GNEViewNet.cpp:298
FXTextField * myTextFieldJunctionStatus
text field for junction status
long long int SUMOTime
Definition: TraCIDefs.h:52
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in allGNEAttributeCarrier.
#define GUIDesignLabelLeft
Definition: GUIDesigns.h:144
void addStep(SUMOTime duration, const std::string &state, int index=-1)
Adds a phase to the logic.
long onCmdDefRename(FXObject *, FXSelector, void *)
Called when the user renames a TLS.
long onUpdModified(FXObject *, FXSelector, void *)
Called when occurs an update of modified.
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.cpp:2047
#define GUIDesignLabelAttribute
label extended over the matrix column with thick frame
Definition: GUIDesigns.h:165
FXTextField * myOffsetTextField
the control for modifying offset
GUISelectedStorage gSelected
A global holder of selected objects.
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1525
NBLoadedSUMOTLDef * myEditedDef
the traffic light definition being edited
FXTextField * myTextFieldJunctionID
text field for junction ID
std::vector< NBTrafficLightDefinition * > myTLSDefinitions
the list of Definitions for the current junction
void cleanup()
cleans up previous lanes
FXLabel * myCycleDuration
label with the cycle duration
LinkState getLinkState() const
whether link state has been modfied
void initPhaseTable(int index=0)
initialies the phase table