SUMO - Simulation of Urban MObility
GUILaneSpeedTrigger.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Changes the speed allowed on a set of lanes (gui version)
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 // ===========================================================================
00023 // included modules
00024 // ===========================================================================
00025 #ifdef _MSC_VER
00026 #include <windows_config.h>
00027 #else
00028 #include <config.h>
00029 #endif
00030 
00031 #ifdef _WIN32
00032 #include <windows.h>
00033 #endif
00034 
00035 #include <GL/gl.h>
00036 
00037 #include <string>
00038 #include <utils/common/MsgHandler.h>
00039 #include <utils/geom/PositionVector.h>
00040 #include <utils/geom/Line.h>
00041 #include <utils/geom/Boundary.h>
00042 #include <utils/gui/div/GLHelper.h>
00043 #include <utils/common/ToString.h>
00044 #include <utils/common/Command.h>
00045 #include <microsim/MSNet.h>
00046 #include <microsim/MSLane.h>
00047 #include <microsim/MSEdge.h>
00048 #include <guisim/GUINet.h>
00049 #include <guisim/GUIEdge.h>
00050 #include "GUILaneSpeedTrigger.h"
00051 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
00052 #include <utils/gui/windows/GUIAppEnum.h>
00053 #include <gui/GUIGlobals.h>
00054 #include <utils/gui/div/GUIParameterTableWindow.h>
00055 #include <gui/GUIApplicationWindow.h>
00056 #include <utils/gui/images/GUITexturesHelper.h>
00057 #include <microsim/logging/FunctionBinding.h>
00058 #include <utils/gui/div/GUIGlobalSelection.h>
00059 #include <foreign/polyfonts/polyfonts.h>
00060 #include <utils/gui/images/GUIIconSubSys.h>
00061 #include <gui/GUIApplicationWindow.h>
00062 #include <guisim/GUILaneSpeedTrigger.h>
00063 
00064 #ifdef CHECK_MEMORY_LEAKS
00065 #include <foreign/nvwa/debug_new.h>
00066 #endif // CHECK_MEMORY_LEAKS
00067 
00068 
00069 // ===========================================================================
00070 // FOX callback mapping
00071 // ===========================================================================
00072 /* -------------------------------------------------------------------------
00073  * GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - mapping
00074  * ----------------------------------------------------------------------- */
00075 FXDEFMAP(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu)
00076 GUILaneSpeedTriggerPopupMenuMap[] = {
00077     FXMAPFUNC(SEL_COMMAND,  MID_MANIP,         GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip),
00078 
00079 };
00080 
00081 // Object implementation
00082 FXIMPLEMENT(GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu, GUIGLObjectPopupMenu, GUILaneSpeedTriggerPopupMenuMap, ARRAYNUMBER(GUILaneSpeedTriggerPopupMenuMap))
00083 
00084 
00085 /* -------------------------------------------------------------------------
00086  * GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - mapping
00087  * ----------------------------------------------------------------------- */
00088 FXDEFMAP(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger) GUIManip_LaneSpeedTriggerMap[] = {
00089     FXMAPFUNC(SEL_COMMAND,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef),
00090     FXMAPFUNC(SEL_UPDATE,   GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_USER_DEF, GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef),
00091     FXMAPFUNC(SEL_COMMAND,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef),
00092     FXMAPFUNC(SEL_UPDATE,   GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_PRE_DEF,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef),
00093     FXMAPFUNC(SEL_COMMAND,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_OPTION,   GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption),
00094     FXMAPFUNC(SEL_COMMAND,  GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::MID_CLOSE,    GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose),
00095 };
00096 
00097 FXIMPLEMENT(GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger, GUIManipulator, GUIManip_LaneSpeedTriggerMap, ARRAYNUMBER(GUIManip_LaneSpeedTriggerMap))
00098 
00099 
00100 // ===========================================================================
00101 // method definitions
00102 // ===========================================================================
00103 /* -------------------------------------------------------------------------
00104  * GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger - methods
00105  * ----------------------------------------------------------------------- */
00106 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::GUIManip_LaneSpeedTrigger(
00107     GUIMainWindow& app,
00108     const std::string& name, GUILaneSpeedTrigger& o,
00109     int /*xpos*/, int /*ypos*/)
00110     : GUIManipulator(app, name, 0, 0),
00111       myParent(&app), myChosenValue(0), myChosenTarget(myChosenValue, NULL, MID_OPTION),
00112       mySpeed(o.getDefaultSpeed()), mySpeedTarget(mySpeed),
00113       myObject(&o) {
00114     myChosenTarget.setTarget(this);
00115     FXVerticalFrame* f1 =
00116         new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
00117 
00118     FXGroupBox* gp = new FXGroupBox(f1, "Change Speed",
00119                                     GROUPBOX_TITLE_LEFT | FRAME_RIDGE,
00120                                     0, 0, 0, 0,  4, 4, 1, 1, 2, 0);
00121     {
00122         // default
00123         FXHorizontalFrame* gf1 =
00124             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
00125         new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
00126                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
00127                           0, 0, 0, 0,   2, 2, 0, 0);
00128     }
00129     {
00130         // loaded
00131         FXHorizontalFrame* gf0 =
00132             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
00133         new FXRadioButton(gf0, "Loaded", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
00134                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
00135                           0, 0, 0, 0,   2, 2, 0, 0);
00136     }
00137     {
00138         // predefined
00139         FXHorizontalFrame* gf2 =
00140             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
00141         new FXRadioButton(gf2, "Predefined: ", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
00142                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
00143                           0, 0, 0, 0,   2, 2, 0, 0);
00144         myPredefinedValues =
00145             new FXComboBox(gf2, 10, this, MID_PRE_DEF,
00146                            ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y | COMBOBOX_STATIC);
00147         myPredefinedValues->appendItem("20 km/h");
00148         myPredefinedValues->appendItem("40 km/h");
00149         myPredefinedValues->appendItem("60 km/h");
00150         myPredefinedValues->appendItem("80 km/h");
00151         myPredefinedValues->appendItem("100 km/h");
00152         myPredefinedValues->appendItem("120 km/h");
00153         myPredefinedValues->appendItem("140 km/h");
00154         myPredefinedValues->appendItem("160 km/h");
00155         myPredefinedValues->appendItem("180 km/h");
00156         myPredefinedValues->appendItem("200 km/h");
00157         myPredefinedValues->setNumVisible(5);
00158     }
00159     {
00160         // free
00161         FXHorizontalFrame* gf12 =
00162             new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
00163         new FXRadioButton(gf12, "Free Entry: ", &myChosenTarget, FXDataTarget::ID_OPTION + 3,
00164                           ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
00165                           0, 0, 0, 0,   2, 2, 0, 0);
00166         myUserDefinedSpeed =
00167             new FXRealSpinDial(gf12, 10, this, MID_USER_DEF,
00168                                LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
00169         myUserDefinedSpeed->setFormatString("%.0f km/h");
00170         myUserDefinedSpeed->setIncrements(1, 10, 10);
00171         myUserDefinedSpeed->setRange(0, 300);
00172         myUserDefinedSpeed->setValue(
00173             static_cast<GUILaneSpeedTrigger*>(myObject)->getDefaultSpeed() * 3.6);
00174     }
00175     new FXButton(f1, "Close", NULL, this, MID_CLOSE,
00176                  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
00177     static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(true);
00178 }
00179 
00180 
00181 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::~GUIManip_LaneSpeedTrigger() {}
00182 
00183 
00184 long
00185 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdClose(FXObject*, FXSelector, void*) {
00186     destroy();
00187     return 1;
00188 }
00189 
00190 
00191 long
00192 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdUserDef(FXObject*, FXSelector, void*) {
00193     mySpeed = (SUMOReal)(myUserDefinedSpeed->getValue() / 3.6);
00194     static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed);
00195     myParent->updateChildren();
00196     return 1;
00197 }
00198 
00199 
00200 long
00201 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
00202     sender->handle(this,
00203                    myChosenValue != 3 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
00204                    ptr);
00205     myParent->updateChildren();
00206     return 1;
00207 }
00208 
00209 
00210 long
00211 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdPreDef(FXObject*, FXSelector, void*) {
00212     mySpeed = (SUMOReal)(SUMOReal)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
00213     static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed);
00214     myParent->updateChildren();
00215     return 1;
00216 }
00217 
00218 
00219 long
00220 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onUpdPreDef(FXObject* sender, FXSelector, void* ptr) {
00221     sender->handle(this,
00222                    myChosenValue != 2 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
00223                    ptr);
00224     myParent->updateChildren();
00225     return 1;
00226 }
00227 
00228 
00229 long
00230 GUILaneSpeedTrigger::GUIManip_LaneSpeedTrigger::onCmdChangeOption(FXObject*, FXSelector, void*) {
00231     static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(true);
00232     switch (myChosenValue) {
00233         case 0:
00234             mySpeed = (SUMOReal) static_cast<GUILaneSpeedTrigger*>(myObject)->getDefaultSpeed();
00235             break;
00236         case 1:
00237             mySpeed = (SUMOReal) static_cast<GUILaneSpeedTrigger*>(myObject)->getLoadedSpeed();
00238             break;
00239         case 2:
00240             mySpeed = (SUMOReal)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
00241             break;
00242         case 3:
00243             mySpeed = (SUMOReal)(myUserDefinedSpeed->getValue() / 3.6);
00244             break;
00245         default:
00246             // hmmm, should not happen
00247             break;
00248     }
00249     static_cast<GUILaneSpeedTrigger*>(myObject)->setOverridingValue(mySpeed);
00250     myParent->updateChildren();
00251     if (myChosenValue == 1) {
00252         // !!! lock in between
00253         static_cast<GUILaneSpeedTrigger*>(myObject)->setOverriding(false);
00254     }
00255     return 1;
00256 }
00257 
00258 
00259 
00260 /* -------------------------------------------------------------------------
00261  * GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu - methods
00262  * ----------------------------------------------------------------------- */
00263 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::GUILaneSpeedTriggerPopupMenu(
00264     GUIMainWindow& app, GUISUMOAbstractView& parent,
00265     GUIGlObject& o)
00266     : GUIGLObjectPopupMenu(app, parent, o) {}
00267 
00268 
00269 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::~GUILaneSpeedTriggerPopupMenu() {}
00270 
00271 
00272 long
00273 GUILaneSpeedTrigger::GUILaneSpeedTriggerPopupMenu::onCmdOpenManip(FXObject*,
00274         FXSelector,
00275         void*) {
00276     static_cast<GUILaneSpeedTrigger*>(myObject)->openManipulator(
00277         *myApplication, *myParent);
00278     return 1;
00279 }
00280 
00281 
00282 /* -------------------------------------------------------------------------
00283  * GUILaneSpeedTrigger - methods
00284  * ----------------------------------------------------------------------- */
00285 GUILaneSpeedTrigger::GUILaneSpeedTrigger(
00286     const std::string& id, const std::vector<MSLane*> &destLanes,
00287     const std::string& aXMLFilename)
00288     : MSLaneSpeedTrigger(id, destLanes, aXMLFilename),
00289       GUIGlObject_AbstractAdd("speedtrigger", GLO_TRIGGER, id),
00290       myShowAsKMH(true), myLastValue(-1) {
00291     myFGPositions.reserve(destLanes.size());
00292     myFGRotations.reserve(destLanes.size());
00293     std::vector<MSLane*>::const_iterator i;
00294     for (i = destLanes.begin(); i != destLanes.end(); ++i) {
00295         const PositionVector& v = (*i)->getShape();
00296         myFGPositions.push_back(v.positionAtLengthPosition(0));
00297         myBoundary.add(v.positionAtLengthPosition(0));
00298         Line l(v.getBegin(), v.getEnd());
00299         myFGRotations.push_back(-v.rotationDegreeAtLengthPosition(0));
00300         myDefaultSpeed = (*i)->getMaxSpeed();
00301         mySpeedOverrideValue = (*i)->getMaxSpeed();
00302     }
00303 }
00304 
00305 
00306 GUILaneSpeedTrigger::~GUILaneSpeedTrigger() {}
00307 
00308 
00309 GUIGLObjectPopupMenu*
00310 GUILaneSpeedTrigger::getPopUpMenu(GUIMainWindow& app,
00311                                   GUISUMOAbstractView& parent) {
00312     GUIGLObjectPopupMenu* ret = new GUILaneSpeedTriggerPopupMenu(app, parent, *this);
00313     buildPopupHeader(ret, app);
00314     buildCenterPopupEntry(ret);
00315     buildShowManipulatorPopupEntry(ret);
00316     buildNameCopyPopupEntry(ret);
00317     buildSelectionPopupEntry(ret);
00318     buildShowParamsPopupEntry(ret);
00319     buildPositionCopyEntry(ret, false);
00320     return ret;
00321 }
00322 
00323 
00324 GUIParameterTableWindow*
00325 GUILaneSpeedTrigger::getParameterWindow(GUIMainWindow& app,
00326                                         GUISUMOAbstractView&) {
00327     GUIParameterTableWindow* ret =
00328         new GUIParameterTableWindow(app, *this, 1);
00329     // add items
00330     ret->mkItem("speed [m/s]", true,
00331                 new FunctionBinding<GUILaneSpeedTrigger, SUMOReal>(this, &GUILaneSpeedTrigger::getCurrentSpeed));
00332     // close building
00333     ret->closeBuilding();
00334     return ret;
00335 }
00336 
00337 
00338 void
00339 GUILaneSpeedTrigger::drawGL(const GUIVisualizationSettings& s) const {
00340     glPushName(getGlID());
00341     glPushMatrix();
00342     glTranslated(0, 0, getType());
00343     for (size_t i = 0; i < myFGPositions.size(); ++i) {
00344         const Position& pos = myFGPositions[i];
00345         SUMOReal rot = myFGRotations[i];
00346         glPushMatrix();
00347         glScaled(s.addExaggeration, s.addExaggeration, 1);
00348         glTranslated(pos.x(), pos.y(), 0);
00349         glRotated(rot, 0, 0, 1);
00350         glTranslated(0, -1.5, 0);
00351 
00352         int noPoints = 9;
00353         if (s.scale > 25) {
00354             noPoints = (int)(9.0 + s.scale / 10.0);
00355             if (noPoints > 36) {
00356                 noPoints = 36;
00357             }
00358         }
00359         glColor3d(1, 0, 0);
00360         GLHelper::drawFilledCircle((SUMOReal) 1.3, noPoints);
00361         if (s.scale >= 5) {
00362             glTranslated(0, 0, .1);
00363             glColor3d(0, 0, 0);
00364             GLHelper::drawFilledCircle((SUMOReal) 1.1, noPoints);
00365             // draw the speed string
00366             // not if scale to low
00367             // compute
00368             SUMOReal value = (SUMOReal) getCurrentSpeed();
00369             if (myShowAsKMH) {
00370                 value *= 3.6f;
00371                 if (((int) value + 1) % 10 == 0) {
00372                     value = (SUMOReal)(((int) value + 1) / 10 * 10);
00373                 }
00374             }
00375             if (value != myLastValue) {
00376                 myLastValue = value;
00377                 myLastValueString = toString<SUMOReal>(myLastValue);
00378                 size_t idx = myLastValueString.find('.');
00379                 if (idx != std::string::npos) {
00380                     if (idx > myLastValueString.length()) {
00381                         idx = myLastValueString.length();
00382                     }
00383                     myLastValueString = myLastValueString.substr(0, idx);
00384                 }
00385             }
00386             //draw
00387             glColor3d(1, 1, 0);
00388             glTranslated(0, 0, .1);
00389             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00390             pfSetPosition(0, 0);
00391             pfSetScale(1.2f);
00392             SUMOReal w = pfdkGetStringWidth(myLastValueString.c_str());
00393             glRotated(180, 0, 1, 0);
00394             glTranslated(-w / 2., 0.3, 0);
00395             pfDrawString(myLastValueString.c_str());
00396         }
00397         glPopMatrix();
00398     }
00399     glPopMatrix();
00400     drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
00401     glPopName();
00402 }
00403 
00404 
00405 Boundary
00406 GUILaneSpeedTrigger::getCenteringBoundary() const {
00407     Boundary b(myBoundary);
00408     b.grow(20);
00409     return b;
00410 }
00411 
00412 
00413 GUIManipulator*
00414 GUILaneSpeedTrigger::openManipulator(GUIMainWindow& app,
00415                                      GUISUMOAbstractView&) {
00416     GUIManip_LaneSpeedTrigger* gui =
00417         new GUIManip_LaneSpeedTrigger(app, getFullName(), *this, 0, 0);
00418     gui->create();
00419     gui->show();
00420     return gui;
00421 }
00422 
00423 
00424 
00425 /****************************************************************************/
00426 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines