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