SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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-2016 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 #ifdef HAVE_VERSION_H
32 #include <version.h>
33 #endif
34 
35 #include <iostream>
45 #include "GNETLSEditorFrame.h"
46 #include "GNEViewNet.h"
47 #include "GNEViewParent.h"
48 #include "GNENet.h"
49 #include "GNEJunction.h"
50 #include "GNEEdge.h"
51 #include "GNELane.h"
52 #include "GNEUndoList.h"
53 #include "GNEInternalLane.h"
54 #include "GNEChange_TLS.h"
55 
56 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 // ===========================================================================
61 // FOX callback mapping
62 // ===========================================================================
63 FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[] = {
64  FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GNETLSEditorFrame::onCmdCancel),
65  FXMAPFUNC(SEL_COMMAND, MID_OK, GNETLSEditorFrame::onCmdOK),
77  FXMAPFUNC(SEL_DESELECTED, MID_GNE_PHASE_TABLE, GNETLSEditorFrame::onCmdPhaseSwitch),
80 
87  FXMAPFUNC(SEL_UPDATE, MID_CANCEL, GNETLSEditorFrame::onUpdModified),
88  FXMAPFUNC(SEL_UPDATE, MID_OK, GNETLSEditorFrame::onUpdModified),
89 };
90 
91 
92 // Object implementation
93 FXIMPLEMENT(GNETLSEditorFrame, FXScrollWindow, GNETLSEditorFrameMap, ARRAYNUMBER(GNETLSEditorFrameMap))
94 
95 // ===========================================================================
96 // method definitions
97 // ===========================================================================
98 GNETLSEditorFrame::GNETLSEditorFrame(FXComposite* parent, GNEViewNet* viewNet):
99  GNEFrame(parent, viewNet, "Edit Traffic Light"),
100  myTableFont(new FXFont(getApp(), "Courier New", 9)),
101  myCurrentJunction(0),
102  myHaveModifications(false),
103  myEditedDef(0) {
104  // heading
105  myDescription = new FXLabel(myContentFrame, "", 0, JUSTIFY_LEFT);
106  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
107 
108  // create tlDef button
109  new FXButton(myContentFrame, "Create TLS\t\tCreate a new traffic light program", 0, this, MID_GNE_DEF_CREATE,
110  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
111  0, 0, 0, 0, 4, 4, 3, 3);
112 
113  // delete tlDef button
114  new FXButton(myContentFrame,
115  "Delete TLS\t\tDelete a traffic light program. If all programs are deleted the junction turns into a priority junction.",
116  0, this, MID_GNE_DEF_DELETE, ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
117  0, 0, 0, 0, 4, 4, 3, 3);
118 
119  // definitions list
120  new FXLabel(myContentFrame, "Name, Program");
121  myDefBox = new FXListBox(myContentFrame, this, MID_GNE_DEF_SWITCH,
122  FRAME_SUNKEN | FRAME_THICK | LISTBOX_NORMAL | LAYOUT_FIX_WIDTH);
123 
124  // offset control
125  new FXLabel(myContentFrame, "Offset");
126  myOffset = new FXTextField(myContentFrame, 6,
127  this, MID_GNE_DEF_OFFSET, TEXTFIELD_NORMAL | TEXTFIELD_REAL, 0, 0, 0, 0, 4, 2, 0, 2);
128 
129  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
130 
131  // phase table
132  new FXLabel(myContentFrame, "Phases");
133  myPhaseTable = new FXTable(myContentFrame, this, MID_GNE_PHASE_TABLE, LAYOUT_FIX_HEIGHT | LAYOUT_FIX_WIDTH);
134  myPhaseTable->setColumnHeaderMode(LAYOUT_FIX_HEIGHT);
135  myPhaseTable->setColumnHeaderHeight(0);
136  myPhaseTable->setRowHeaderMode(LAYOUT_FIX_WIDTH);
137  myPhaseTable->setRowHeaderWidth(0);
138  myPhaseTable->hide();
139  myPhaseTable->setFont(myTableFont);
140  myPhaseTable->setHelpText("phase duration in seconds | phase state");
141 
142  // total duration info
143  myCycleDuration = new FXLabel(myContentFrame, "");
144 
145  // insert new phase button
146  new FXButton(myContentFrame, "Copy Phase\t\tInsert duplicate phase after selected phase", 0, this, MID_GNE_PHASE_CREATE,
147  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
148  0, 0, 0, 0, 4, 4, 3, 3);
149 
150  // delete phase button
151  new FXButton(myContentFrame, "Delete Phase\t\tDelete selected phase", 0, this, MID_GNE_PHASE_DELETE,
152  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
153  0, 0, 0, 0, 4, 4, 3, 3);
154 
155  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
156  // buttons
157  // "Cancel"
158  new FXButton(myContentFrame, "Cancel\t\tDiscard program modifications (Esc)", 0, this, MID_CANCEL,
159  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
160  0, 0, 0, 0, 4, 4, 3, 3);
161  // "OK"
162  new FXButton(myContentFrame, "Save\t\tSave program modifications (Enter)", 0, this, MID_OK,
163  ICON_BEFORE_TEXT | LAYOUT_FILL_X | FRAME_THICK | FRAME_RAISED,
164  0, 0, 0, 0, 4, 4, 3, 3);
165  new FXHorizontalSeparator(myContentFrame, SEPARATOR_GROOVE | LAYOUT_FILL_X, 0, 0, 0, 2, 2, 2, 4, 4);
166  // "Add 'off' program"
167  /*
168  new FXButton(myContentFrame, "Add \"Off\"-Program\t\tAdds a program for switching off this traffic light",
169  0, this, MID_GNE_DEF_ADDOFF,
170  ICON_BEFORE_TEXT|LAYOUT_FILL_X|FRAME_THICK|FRAME_RAISED,
171  0, 0, 0, 0, 4, 4, 3, 3);
172  */
173 }
174 
175 
177  delete myTableFont;
178  cleanup();
179 }
180 
181 
182 void
184  // Show Scroll window
185  FXScrollWindow::show();
186  // Show and update Frame Area in which this GNEFrame is placed
188 }
189 
190 
191 void
193  // Hide ScrollWindow
194  FXScrollWindow::hide();
195  // Hide Frame Area in which this GNEFrame is placed
197 }
198 
199 void
201  if (myCurrentJunction == 0 || (!myHaveModifications && (junction != myCurrentJunction))) {
202  onCmdCancel(0, 0, 0);
203  myViewNet->getUndoList()->p_begin("modifying traffic light definition");
204  myCurrentJunction = junction;
206  initDefinitions();
207  } else {
208  myViewNet->setStatusBarText("Unsaved modifications. Abort or Save");
209  }
210 }
211 
212 
213 long
214 GNETLSEditorFrame::onCmdCancel(FXObject*, FXSelector, void*) {
215  if (myCurrentJunction != 0) {
217  cleanup();
218  myViewNet->update();
219  }
220  return 1;
221 }
222 
223 
224 long
225 GNETLSEditorFrame::onCmdOK(FXObject*, FXSelector, void*) {
226  if (myCurrentJunction != 0) {
227  if (myHaveModifications) {
228  NBTrafficLightDefinition* old = myDefinitions[myDefBox->getCurrentItem()];
229  std::vector<NBNode*> nodes = old->getNodes();
230  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
231  GNEJunction* junction = myViewNet->getNet()->retrieveJunction((*it)->getID());
232  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, old, false), true);
233  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, myEditedDef, true), true);
234  }
235  myEditedDef = 0;
237  cleanup();
238  myViewNet->update();
239  } else {
240  onCmdCancel(0, 0, 0);
241  }
242  }
243  return 1;
244 }
245 
246 
247 long
248 GNETLSEditorFrame::onCmdDefCreate(FXObject*, FXSelector, void*) {
249  GNEJunction* junction = myCurrentJunction;
250  onCmdCancel(0, 0, 0); // abort because we onCmdOk assumes we wish to save an edited definition
253  } else {
254  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, 0, true, true), true);
255  }
256  editJunction(junction);
257  return 1;
258 }
259 
260 
261 long
262 GNETLSEditorFrame::onCmdDefDelete(FXObject*, FXSelector, void*) {
263  GNEJunction* junction = myCurrentJunction;
264  const bool changeType = myDefinitions.size() == 1;
265  onCmdCancel(0, 0, 0); // abort because onCmdOk assumes we wish to save an edited definition
266  if (changeType) {
268  } else {
269  NBTrafficLightDefinition* tlDef = myDefinitions[myDefBox->getCurrentItem()];
270  myViewNet->getUndoList()->add(new GNEChange_TLS(junction, tlDef, false), true);
271  }
272  return 1;
273 }
274 
275 
276 long
277 GNETLSEditorFrame::onCmdDefSwitch(FXObject*, FXSelector, void*) {
278  assert(myCurrentJunction != 0);
279  assert((int)myDefinitions.size() == myDefBox->getNumItems());
280  NBTrafficLightDefinition* tlDef = myDefinitions[myDefBox->getCurrentItem()];
281  // logic may not have been recomputed yet. recompute to be sure
284  NBTrafficLightLogic* tllogic = tllCont.getLogic(tlDef->getID(), tlDef->getProgramID());
285  if (tllogic != 0) {
286  // now we can be sure that the tlDef is up to date (i.e. re-guessed)
287  buildIinternalLanes(tlDef);
288  // create working copy from original def
289  delete myEditedDef;
290  myEditedDef = new NBLoadedSUMOTLDef(tlDef, tllogic);
291  myOffset->setText(toString(STEPS2TIME(myEditedDef->getLogic()->getOffset())).c_str());
292  initPhaseTable();
294  } else {
295  // tlDef has no valid logic (probably because id does not control any links
296  onCmdCancel(0, 0, 0);
297  myViewNet->setStatusBarText("Traffic light does not control any links");
298  }
299  return 1;
300 }
301 
302 
303 long
304 GNETLSEditorFrame::onUpdDefSwitch(FXObject* o, FXSelector, void*) {
305  const bool enable = myDefinitions.size() > 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::onUpdNeedsDef(FXObject* o, FXSelector, void*) {
313  const bool enable = myDefinitions.size() > 0;
314  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
315  return 1;
316 }
317 
318 
319 long
320 GNETLSEditorFrame::onUpdNeedsDefAndPhase(FXObject* o, FXSelector, void*) {
321  // do not delete the last phase
322  const bool enable = myDefinitions.size() > 0 && myPhaseTable->getNumRows() > 1;
323  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
324  return 1;
325 }
326 
327 
328 long
329 GNETLSEditorFrame::onUpdDefCreate(FXObject* o, FXSelector, void*) {
330  const bool enable = myCurrentJunction != 0 && !myHaveModifications;
331  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
332  return 1;
333 }
334 
335 
336 long
337 GNETLSEditorFrame::onUpdModified(FXObject* o, FXSelector, void*) {
338  bool enable = myHaveModifications;
339  o->handle(this, FXSEL(SEL_COMMAND, enable ? FXWindow::ID_ENABLE : FXWindow::ID_DISABLE), 0);
340  return 1;
341 }
342 
343 
344 
345 long
346 GNETLSEditorFrame::onCmdDefOffset(FXObject*, FXSelector, void*) {
347  myHaveModifications = true;
349  return 1;
350 }
351 
352 
353 long
354 GNETLSEditorFrame::onCmdDefRename(FXObject*, FXSelector, void*) {
355  return 1;
356 }
357 
358 
359 long
360 GNETLSEditorFrame::onCmdDefSubRename(FXObject*, FXSelector, void*) {
361  return 1;
362 }
363 
364 
365 long
366 GNETLSEditorFrame::onCmdDefAddOff(FXObject*, FXSelector, void*) {
367  return 1;
368 }
369 
370 
371 long
372 GNETLSEditorFrame::onCmdGuess(FXObject*, FXSelector, void*) {
373  return 1;
374 }
375 
376 
377 long
378 GNETLSEditorFrame::onCmdPhaseSwitch(FXObject*, FXSelector, void*) {
379  const int index = myPhaseTable->getCurrentRow();
380  const NBTrafficLightLogic::PhaseDefinition& phase = getPhases()[index];
381  myPhaseTable->selectRow(index);
382  // need not hold since links could have been deleted somewhere else and indices may be reused
383  // assert(phase.state.size() == myInternalLanes.size());
384  for (TLIndexMap::iterator it = myInternalLanes.begin(); it != myInternalLanes.end(); it++) {
385  int tlIndex = it->first;
386  std::vector<GNEInternalLane*> lanes = it->second;
387  assert(tlIndex >= 0);
388  assert(tlIndex < (int)phase.state.size());
389  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
390  (*it_lane)->setLinkState((LinkState)phase.state[tlIndex]);
391  }
392  }
393  myViewNet->update();
394  return 1;
395 }
396 
397 
398 long
399 GNETLSEditorFrame::onCmdPhaseCreate(FXObject*, FXSelector, void*) {
400  myHaveModifications = true;
401  // allows insertion at first position by deselecting via arrow keys
402  int newIndex = myPhaseTable->getSelStartRow() + 1;
403  int oldIndex = MAX2(0, myPhaseTable->getSelStartRow());
404  // copy current row
405  const SUMOTime duration = getSUMOTime(myPhaseTable->getItemText(oldIndex, 0));
406  const std::string state = myPhaseTable->getItemText(oldIndex, 1).text();
407  myEditedDef->getLogic()->addStep(duration, state, newIndex);
408  myPhaseTable->setCurrentItem(newIndex, 0);
409  initPhaseTable(newIndex);
410  myPhaseTable->setFocus();
411  return 1;
412 }
413 
414 
415 long
416 GNETLSEditorFrame::onCmdPhaseDelete(FXObject*, FXSelector, void*) {
417  myHaveModifications = true;
418  const int newRow = MAX2((int)0, (int)myPhaseTable->getCurrentRow() - 1);
419  myEditedDef->getLogic()->deletePhase(myPhaseTable->getCurrentRow());
420  initPhaseTable(newRow);
421  myPhaseTable->setFocus();
422  return 1;
423 }
424 
425 
426 long
427 GNETLSEditorFrame::onCmdPhaseEdit(FXObject*, FXSelector, void* ptr) {
428  /* @note: there is a bug when copying/pasting rows: when this handler is
429  * called the value of the cell is not yet updated. This means you have to
430  * click inside the cell and hit enter to actually update the value */
431  FXTablePos* tp = (FXTablePos*)ptr;
432  FXString value = myPhaseTable->getItemText(tp->row, tp->col);
433  if (tp->col == 0) {
434  // duration edited
435  if (GNEAttributeCarrier::canParse<SUMOReal>(value.text())) {
436  SUMOTime duration = getSUMOTime(value);
437  if (duration > 0) {
438  myEditedDef->getLogic()->setPhaseDuration(tp->row, duration);
439  myHaveModifications = true;
441  return 1;
442  }
443  }
444  // input error, reset value
445  myPhaseTable->setItemText(tp->row, 0, toString(STEPS2TIME(getPhases()[tp->row].duration)).c_str());
446  } else {
447  // state edited
448  try {
449  // insert phase with new step and delete the old phase
450  myEditedDef->getLogic()->addStep(getPhases()[tp->row].duration, value.text(), tp->row);
451  myEditedDef->getLogic()->deletePhase(tp->row + 1);
452  myHaveModifications = true;
453  onCmdPhaseSwitch(0, 0, 0);
454  } catch (ProcessError) {
455  // input error, reset value
456  myPhaseTable->setItemText(tp->row, 1, getPhases()[tp->row].state.c_str());
457  }
458  }
459  return 1;
460 }
461 
462 
463 void
465  std::string description;
466  if (myCurrentJunction == 0) {
467  description = "No Junction Selected\n";
468  } else {
470  description = "Junction '" + nbn->getID() + "'\n(";
471  if (!nbn->isTLControlled()) {
472  description += "uncontrolled, ";
473  }
474  description += (myHaveModifications ? "modified)" : "unmodified)");
475  }
476  myDescription->setText(description.c_str());
477 }
478 
479 
480 void
482  if (myCurrentJunction) {
484  }
485  // clean data structures
486  myCurrentJunction = 0;
487  myHaveModifications = false;
488  delete myEditedDef;
489  myEditedDef = 0;
490  buildIinternalLanes(0); // only clears
491  // clean up controls
492  myOffset->setText("");
493  myDefinitions.clear();
494  myDefBox->hide();
495  initPhaseTable(); // only clears when there are no definitions
496  myCycleDuration->hide();
498 }
499 
500 
501 void
503  // clean up previous objects
505  for (TLIndexMap::iterator it = myInternalLanes.begin(); it != myInternalLanes.end(); it++) {
506  std::vector<GNEInternalLane*> lanes = it->second;
507  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
508  rtree.removeAdditionalGLObject(*it_lane);
509  delete *it_lane;
510  }
511  }
512  myInternalLanes.clear();
513  if (tlDef != 0) {
514  const int NUM_POINTS = 10;
515  assert(myCurrentJunction);
518  std::string innerID = ":" + nbn->getID(); // see NWWriter_SUMO::writeInternalEdges
519  const NBConnectionVector& links = tlDef->getControlledLinks();
520  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
521  int tlIndex = it->getTLIndex();
522  PositionVector shape = nbn->computeInternalLaneShape(it->getFrom(), NBEdge::Connection(it->getFromLane(),
523  it->getTo(), it->getToLane()), NUM_POINTS);
524  GNEInternalLane* ilane = new GNEInternalLane(this, innerID + '_' + toString(tlIndex), shape, tlIndex);
525  rtree.addAdditionalGLObject(ilane);
526  myInternalLanes[tlIndex].push_back(ilane);
527  }
528  const std::vector<NBNode::Crossing>& crossings = nbn->getCrossings();
529  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
530  const NBNode::Crossing& c = *it;
531  GNEInternalLane* ilane = new GNEInternalLane(this, c.id, c.shape, c.tlLinkNo);
532  rtree.addAdditionalGLObject(ilane);
533  myInternalLanes[c.tlLinkNo].push_back(ilane);
534  }
535  }
536 }
537 
538 
539 void
541  myDefinitions.clear();
542  myDefBox->clearItems();
543  assert(myCurrentJunction);
545  std::set<NBTrafficLightDefinition*> tldefs = nbn->getControllingTLS();
546  for (std::set<NBTrafficLightDefinition*>::iterator it = tldefs.begin(); it != tldefs.end(); it++) {
547  myDefinitions.push_back(*it);
548  std::string item = (*it)->getID() + ", " + (*it)->getProgramID();
549  myDefBox->appendItem(item.c_str());
550  }
551  if (myDefinitions.size() > 0) {
552  myDefBox->setCurrentItem(0);
553  myDefBox->setNumVisible(myDefBox->getNumItems());
554  myDefBox->show();
555  onCmdDefSwitch(0, 0, 0);
556  }
558 }
559 
560 
561 void
563  myPhaseTable->setVisibleRows(1);
564  myPhaseTable->setVisibleColumns(2);
565  myPhaseTable->hide();
566  if (myDefinitions.size() > 0) {
567  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
568  myPhaseTable->setTableSize((int)phases.size(), 2);
569  myPhaseTable->setVisibleRows((int)phases.size());
570  myPhaseTable->setVisibleColumns(2);
571  for (int row = 0; row < (int)phases.size(); row++) {
572  myPhaseTable->setItemText(row, 0, toString(STEPS2TIME(phases[row].duration)).c_str());
573  myPhaseTable->setItemText(row, 1, phases[row].state.c_str());
574  myPhaseTable->getItem(row, 1)->setJustify(FXTableItem::LEFT);
575  }
576  myPhaseTable->fitColumnsToContents(0, 2);
577  const int maxWidth = 140 - 4;
578  int desiredWidth = myPhaseTable->getColumnWidth(0) +
579  myPhaseTable->getColumnWidth(1) + 3;
580  int spaceForScrollBar = desiredWidth > maxWidth ? 15 : 0;
581  myPhaseTable->setHeight((int)phases.size() * 21 + spaceForScrollBar); // experimental
582  myPhaseTable->setWidth(MIN2(desiredWidth, maxWidth));
583  myPhaseTable->setCurrentItem(index, 0);
584  myPhaseTable->selectRow(index, true);
585  myPhaseTable->show();
586  myPhaseTable->setFocus();
587  }
588  update();
589 }
590 
591 
592 const std::vector<NBTrafficLightLogic::PhaseDefinition>&
594  return myEditedDef->getLogic()->getPhases();
595 }
596 
597 
598 void
600  myHaveModifications = true;
601  if (myViewNet->changeAllPhases()) {
602  const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = getPhases();
603  for (int row = 0; row < (int)phases.size(); row++) {
604  myEditedDef->getLogic()->setPhaseState(row, lane->getTLIndex(), lane->getLinkState());
605  }
606  } else {
607  myEditedDef->getLogic()->setPhaseState(myPhaseTable->getCurrentRow(), lane->getTLIndex(), lane->getLinkState());
608  }
609  initPhaseTable(myPhaseTable->getCurrentRow());
610  myPhaseTable->setFocus();
611 }
612 
613 
614 void
615 GNETLSEditorFrame::handleMultiChange(GNELane* lane, FXObject* obj, FXSelector sel, void* data) {
616  if (myEditedDef != 0) {
617  myHaveModifications = true;
619  std::set<std::string> fromIDs;
620  fromIDs.insert(lane->getMicrosimID());
621  GNEEdge& edge = lane->getParentEdge();
622  // if neither the lane nor its edge are selected, apply changes to the whole edge
624  for (GNEEdge::LaneVector::const_iterator it_lane = edge.getLanes().begin(); it_lane != edge.getLanes().end(); it_lane++) {
625  fromIDs.insert((*it_lane)->getMicrosimID());
626  }
627  } else {
628  // if the edge is selected, apply changes to all lanes of all selected edges
629  if (gSelected.isSelected(GLO_EDGE, edge.getGlID())) {
630  std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges(true);
631  for (std::vector<GNEEdge*>::iterator it = edges.begin(); it != edges.end(); it++) {
632  for (GNEEdge::LaneVector::const_iterator it_lane = (*it)->getLanes().begin(); it_lane != (*it)->getLanes().end(); it_lane++) {
633  fromIDs.insert((*it_lane)->getMicrosimID());
634  }
635  }
636  }
637  // if the lane is selected, apply changes to all selected lanes
638  if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
639  std::vector<GNELane*> lanes = myViewNet->getNet()->retrieveLanes(true);
640  for (std::vector<GNELane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
641  fromIDs.insert((*it_lane)->getMicrosimID());
642  }
643  }
644 
645  }
646  // set new state for all connections from the chosen lane IDs
647  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
648  const NBConnection& c = *it;
649  if (fromIDs.count(c.getFrom()->getLaneID(c.getFromLane())) > 0) {
650  std::vector<GNEInternalLane*> lanes = myInternalLanes[c.getTLIndex()];
651  for (std::vector<GNEInternalLane*>::iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
652  (*it_lane)->onDefault(obj, sel, data);
653  }
654  }
655  }
656  }
657 }
658 
659 
660 bool
662  if (myEditedDef != 0) {
664  for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
665  if ((*it).getFrom()->getID() == edge.getMicrosimID()) {
666  return true;
667  }
668  }
669  }
670  return false;
671 }
672 
673 
674 SUMOTime
675 GNETLSEditorFrame::getSUMOTime(const FXString& string) {
676  assert(GNEAttributeCarrier::canParse<SUMOReal>(string.text()));
677  return TIME2STEPS(GNEAttributeCarrier::parse<SUMOReal>(string.text()));
678 }
679 
680 
681 void
683  SUMOTime cycleDuration = 0;
684  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = getPhases().begin(); it != getPhases().end(); it++) {
685  cycleDuration += it->duration;
686  }
687  std::string text = "Cycle time: " + toString(STEPS2TIME(cycleDuration));
688  myCycleDuration->setText(text.c_str());
689 }
690 
691 
692 /****************************************************************************/
int NUM_POINTS
TLIndexMap myInternalLanes
long onCmdGuess(FXObject *, FXSelector, void *)
Called when the user presses the button Guess.
std::vector< NBTrafficLightDefinition * > myDefinitions
the list of Definitions for the current junction
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:729
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:157
FXLabel * myDescription
the label that shows the current editing state
void hideFramesArea()
hide frames area if all GNEFrames are hidden
long long int SUMOTime
Definition: SUMOTime.h:43
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.
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled ...
Definition: NBConnection.h:100
bool changeAllPhases() const
change all phases
Definition: GNEViewNet.cpp:352
std::string id
the (edge)-id of this crossing
Definition: NBNode.h:145
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:304
void show()
show Frame
long onCmdPhaseSwitch(FXObject *, FXSelector, void *)
Called when the user switchs a Phase.
FXListBox * myDefBox
the listbox for selecting the tl-definition to edit
void hide()
hide Frame
void showFramesArea()
show frames area if at least a GNEFrame is showed
int getFromLane() const
returns the from-lane
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.
const std::vector< Crossing > & getCrossings() const
return this junctions pedestrian crossings
Definition: NBNode.h:657
The base class for traffic light logic definitions.
PositionVector computeInternalLaneShape(NBEdge *fromE, const NBEdge::Connection &con, int numPoints, NBNode *recordError=0) const
Compute the shape for an internal lane.
Definition: NBNode.cpp:640
T MAX2(T a, T b)
Definition: StdDefs.h:75
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:55
PositionVector shape
The lane's shape.
Definition: NBNode.h:141
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:86
void selectTLS(bool selected)
notify the junction of being selected in tls-mode. (used to control drawing)
#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.
GNEViewParent * getViewParent() const
get the net object
Definition: GNEViewNet.cpp:906
long onUpdNeedsDef(FXObject *, FXSelector, void *)
Called when occurs an update of needs definition.
A RT-tree for efficient storing of SUMO's GL-objects.
Definition: SUMORTree.h:74
FXFont * myTableFont
font for the phase table
NBEdge * getFrom() const
returns the from-edge (start of the connection)
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
Definition: GNEViewNet.cpp:918
GNEViewNet * myViewNet
the window to inform when the tls is modfied
Definition: GNEFrame.h:85
void updateDescription() const
update descrition
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
#define new
Definition: debug_new.h:121
const std::string & getID() const
Returns the id.
Definition: Named.h:66
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node.
Definition: NBNode.h:318
long onCmdCancel(FXObject *, FXSelector, void *)
Called when the user presses the Cancel-button.
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1061
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:93
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:689
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)
Definition: GNENet.cpp:933
~GNETLSEditorFrame()
Destructor.
void handleChange(GNEInternalLane *lane)
update phase definition for the current traffic light and phase
T MIN2(T a, T b)
Definition: StdDefs.h:69
NBTrafficLightLogic * getLogic()
Returns the internal logic.
FXDEFMAP(GNETLSEditorFrame) GNETLSEditorFrameMap[]
int getTLIndex() const
get Traffic Light index
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
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:228
std::vector< NBConnection > NBConnectionVector
Definition of a connection vector.
FXTextField * myOffset
the control for modifying offset
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:55
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.
void updateCycleDuration()
recomputes cycle duration and updates label
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:485
void initDefinitions()
initializes the definitions and corresponding listbox
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:717
tls mode messages
Definition: GUIAppEnum.h:465
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
int tlLinkNo
the traffic light index of this crossing (if controlled)
Definition: NBNode.h:153
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
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:912
GNEJunction * myCurrentJunction
the junction of the tls is being modified
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)
long onCmdPhaseCreate(FXObject *, FXSelector, void *)
Called when the user creates a Phase.
Represents a single node (junction) during network building.
Definition: NBNode.h:74
A definition of a pedestrian crossing.
Definition: NBNode.h:132
void setStatusBarText(const std::string &text)
set staturBar text
Definition: GNEViewNet.cpp:316
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2499
std::string getAttribute(SumoXMLAttr key) const
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.
GUISelectedStorage gSelected
A global holder of selected objects.
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1088
NBLoadedSUMOTLDef * myEditedDef
the traffic light definition being edited
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