00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <iostream>
00031 #include <utility>
00032 #include <cmath>
00033 #include <cassert>
00034 #include <utils/common/RGBColor.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/common/StringUtils.h>
00037 #include <utils/common/MsgHandler.h>
00038 #include <utils/gui/globjects/GUIGLObjectToolTip.h>
00039 #include <utils/gui/windows/GUIAppEnum.h>
00040 #include "GUIDanielPerspectiveChanger.h"
00041 #include "GUISUMOAbstractView.h"
00042 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
00043 #include <utils/foxtools/MFXCheckableButton.h>
00044 #include <utils/gui/images/GUITexturesHelper.h>
00045 #include <utils/gui/div/GUIGlobalSelection.h>
00046 #include <utils/gui/div/GLHelper.h>
00047 #include "GUIMainWindow.h"
00048 #include "GUIGlChildWindow.h"
00049 #include <utils/gui/globjects/GUIGlObjectStorage.h>
00050 #include <utils/gui/globjects/GUIGlObject.h>
00051 #include <utils/gui/globjects/GUIGlObjectStorage.h>
00052 #include "GUIDialog_EditViewport.h"
00053 #include <foreign/polyfonts/polyfonts.h>
00054 #include <utils/shapes/PointOfInterest.h>
00055 #include <utils/shapes/ShapeContainer.h>
00056 #include <utils/gui/globjects/GUIPointOfInterest.h>
00057 #include <utils/gui/globjects/GUIPolygon2D.h>
00058 #include <utils/gui/windows/GUIDialog_ViewSettings.h>
00059 #include <utils/geom/GeoConvHelper.h>
00060 #include <utils/gui/settings/GUIVisualizationSettings.h>
00061 #include <utils/gui/settings/GUICompleteSchemeStorage.h>
00062 #include <fxkeys.h>
00063 #include <utils/foxtools/MFXImageHelper.h>
00064
00065 #include <guisim/GUINet.h>
00066 #include <microsim/MSNet.h>
00067
00068
00069 #ifdef WIN32
00070 #include <windows.h>
00071 #else
00072 #define APIENTRY
00073 #endif
00074
00075 #include <GL/gl.h>
00076 #include <GL/glu.h>
00077
00078 #ifdef CHECK_MEMORY_LEAKS
00079 #include <foreign/nvwa/debug_new.h>
00080 #endif // CHECK_MEMORY_LEAKS
00081
00082
00083
00084
00085
00086
00087
00088
00089 FXDEFMAP(GUISUMOAbstractView) GUISUMOAbstractViewMap[]= {
00090 FXMAPFUNC(SEL_CONFIGURE, 0, GUISUMOAbstractView::onConfigure),
00091 FXMAPFUNC(SEL_PAINT, 0, GUISUMOAbstractView::onPaint),
00092 FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, GUISUMOAbstractView::onLeftBtnPress),
00093 FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, GUISUMOAbstractView::onLeftBtnRelease),
00094 FXMAPFUNC(SEL_RIGHTBUTTONPRESS, 0, GUISUMOAbstractView::onRightBtnPress),
00095 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, 0, GUISUMOAbstractView::onRightBtnRelease),
00096 FXMAPFUNC(SEL_MOUSEWHEEL, 0, GUISUMOAbstractView::onMouseWheel),
00097 FXMAPFUNC(SEL_MOTION, 0, GUISUMOAbstractView::onMouseMove),
00098 FXMAPFUNC(SEL_LEAVE, 0, GUISUMOAbstractView::onMouseLeft),
00099 FXMAPFUNC(SEL_KEYPRESS, 0, GUISUMOAbstractView::onKeyPress),
00100 FXMAPFUNC(SEL_KEYRELEASE, 0, GUISUMOAbstractView::onKeyRelease),
00101
00102 };
00103
00104
00105 FXIMPLEMENT_ABSTRACT(GUISUMOAbstractView,FXGLCanvas,GUISUMOAbstractViewMap,ARRAYNUMBER(GUISUMOAbstractViewMap))
00106
00107
00108
00109
00110
00111 GUISUMOAbstractView::GUISUMOAbstractView(FXComposite *p,
00112 GUIMainWindow &app,
00113 GUIGlChildWindow *parent,
00114 const SUMORTree &grid,
00115 FXGLVisual *glVis, FXGLCanvas *share)
00116 : FXGLCanvas(p, glVis, share, p, MID_GLCANVAS,
00117 LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 300, 200),
00118 myApp(&app),
00119 myParent(parent),
00120 myGrid(&((SUMORTree&)grid)),
00121 myChanger(0),
00122 myMouseHotspotX(app.getDefaultCursor()->getHotX()),
00123 myMouseHotspotY(app.getDefaultCursor()->getHotY()),
00124 myPopup(0),
00125 myAmInitialised(false),
00126 myViewportChooser(0), myVisualizationChanger(0),
00127 myUseToolTips(false) {
00128 setTarget(this);
00129 enable();
00130 flags|=FLAG_ENABLED;
00131 myInEditMode=false;
00132
00133 SUMOReal nw = myGrid->getWidth();
00134 SUMOReal nh = myGrid->getHeight();
00135 myNetScale = (nw < nh ? nh : nw);
00136
00137 myChanger = new GUIDanielPerspectiveChanger(*this);
00138 myChanger->setNetSizes((size_t) nw, (size_t) nh);
00139 gSchemeStorage.setViewport(this);
00140 myToolTip = new GUIGLObjectToolTip(myApp);
00141 myVisualizationSettings = &gSchemeStorage.getDefault();
00142 }
00143
00144
00145 GUISUMOAbstractView::~GUISUMOAbstractView() {
00146 gSchemeStorage.setDefault(myVisualizationSettings->name);
00147 gSchemeStorage.saveViewport(myChanger->getXPos(), myChanger->getYPos(), myChanger->getZoom());
00148 delete myChanger;
00149 delete myToolTip;
00150 delete myViewportChooser;
00151 delete myVisualizationChanger;
00152 }
00153
00154
00155 bool
00156 GUISUMOAbstractView::isInEditMode() {
00157 return myInEditMode;
00158 }
00159
00160
00161 void
00162 GUISUMOAbstractView::updateToolTip() {
00163 if (!myUseToolTips) {
00164 return;
00165 }
00166 update();
00167 }
00168
00169
00170 Position2D
00171 GUISUMOAbstractView::getPositionInformation() const {
00172 return getPositionInformation(myWindowCursorPositionX, myWindowCursorPositionY);
00173 }
00174
00175
00176 Position2D
00177 GUISUMOAbstractView::getPositionInformation(int mx, int my) const {
00178 SUMOReal mzoom = myChanger->getZoom();
00179
00180 SUMOReal cy = myChanger->getYPos();
00181 SUMOReal cx = myChanger->getXPos();
00182
00183 GLdouble sxmin = myGrid->getCenter().x() - cx - myX1;
00184 GLdouble sxmax = myGrid->getCenter().x() - cx + myX1;
00185 GLdouble symin = myGrid->getCenter().y() - cy - myY1;
00186 GLdouble symax = myGrid->getCenter().y() - cy + myY1;
00187 SUMOReal sx = sxmin + (sxmax-sxmin) * (SUMOReal) mx / (SUMOReal) myWidthInPixels;
00188 SUMOReal sy = symin + (symax-symin) * ((SUMOReal) myHeightInPixels - (SUMOReal) my) / (SUMOReal) myHeightInPixels;
00189 return Position2D(sx, sy);
00190 }
00191
00192
00193 void
00194 GUISUMOAbstractView::updatePositionInformation() const {
00195 Position2D pos = getPositionInformation();
00196 std::string text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
00197 myApp->getCartesianLabel().setText(text.c_str());
00198 GeoConvHelper::cartesian2geo(pos);
00199 if (GeoConvHelper::usingGeoProjection()) {
00200 text = "lat:" + toString(pos.y(), GEO_OUTPUT_ACCURACY) + ", lon:" + toString(pos.x(), GEO_OUTPUT_ACCURACY);
00201 } else {
00202 text = "x:" + toString(pos.x()) + ", y:" + toString(pos.y());
00203 }
00204 myApp->getGeoLabel().setText(text.c_str());
00205 }
00206
00207
00208 void
00209 GUISUMOAbstractView::paintGL() {
00210 myWidthInPixels = getWidth();
00211 myHeightInPixels = getHeight();
00212 if (myWidthInPixels==0||myHeightInPixels==0) {
00213 return;
00214 }
00215
00216 if (getTrackedID()>0) {
00217 GUIGlObject *o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(getTrackedID());
00218 if (o!=0) {
00219 Boundary b = o->getCenteringBoundary();
00220 myChanger->centerTo(*myGrid, b, false);
00221 }
00222 }
00223
00224 unsigned int id = 0;
00225 if (myUseToolTips) {
00226 id = getObjectUnderCursor();
00227 }
00228
00229
00230 glClearColor(
00231 myVisualizationSettings->backgroundColor.red(),
00232 myVisualizationSettings->backgroundColor.green(),
00233 myVisualizationSettings->backgroundColor.blue(),
00234 1);
00235 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00236 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00237
00238 if (myVisualizationSettings->dither) {
00239 glEnable(GL_DITHER);
00240 } else {
00241 glDisable(GL_DITHER);
00242 }
00243 if (myVisualizationSettings->antialiase) {
00244 glEnable(GL_BLEND);
00245 glEnable(GL_POLYGON_SMOOTH);
00246 glEnable(GL_LINE_SMOOTH);
00247 } else {
00248 glDisable(GL_BLEND);
00249 glDisable(GL_POLYGON_SMOOTH);
00250 glDisable(GL_LINE_SMOOTH);
00251 }
00252
00253 applyChanges(1.0, 0, 0);
00254 doPaintGL(GL_RENDER, 1.0);
00255 if (myVisualizationSettings->showSizeLegend) {
00256 displayLegend();
00257 }
00258
00259
00260 glFlush();
00261 swapBuffers();
00262 if (myUseToolTips&&id!=0) {
00263 showToolTipFor(id);
00264 }
00265 }
00266
00267
00268 unsigned int
00269 GUISUMOAbstractView::getObjectUnderCursor() {
00270 int xpos = myWindowCursorPositionX+myMouseHotspotX;
00271 int ypos = myWindowCursorPositionY+myMouseHotspotY;
00272 if (xpos<0||xpos>=myWidthInPixels) {
00273 return 0;
00274 }
00275 if (ypos<0||ypos>=myHeightInPixels) {
00276 return 0;
00277 }
00278
00279
00280 const int SENSITIVITY = 4;
00281 const int NB_HITS_MAX = 1000;
00282
00283 static GLuint hits[NB_HITS_MAX];
00284 static GLint nb_hits = 0;
00285 glSelectBuffer(NB_HITS_MAX, hits);
00286 glInitNames();
00287
00288 SUMOReal scale = SUMOReal(getWidth())/SUMOReal(SENSITIVITY);
00289 applyChanges(scale, myWindowCursorPositionX+myMouseHotspotX, myWindowCursorPositionY+myMouseHotspotY);
00290
00291 bool tmp = myUseToolTips;
00292 myUseToolTips = true;
00293 int hits2 = doPaintGL(GL_SELECT, scale);
00294 myUseToolTips = tmp;
00295
00296 nb_hits = glRenderMode(GL_RENDER);
00297 if (nb_hits==0||hits2==0) {
00298 applyChanges(1, 0, 0);
00299 return 0;
00300 }
00301
00302 unsigned int idMax = 0;
00303 int prevLayer = -1000;
00304 for (int i=0; i<nb_hits; ++i) {
00305 assert(i*4+3<NB_HITS_MAX);
00306 unsigned int id = hits[i*4+3];
00307 GUIGlObject *o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
00308 if (o==0) {
00309 continue;
00310 }
00311 if (o->getGlID()==0) {
00312 continue;
00313 }
00314 GUIGlObjectType type = o->getType();
00315 if (type!=0) {
00316 int clayer = (int) type;
00317
00318
00319
00320 if (type==GLO_SHAPE) {
00321 if (dynamic_cast<GUIPolygon2D*>(o)!=0) {
00322 if (dynamic_cast<GUIPolygon2D*>(o)->getLayer()>0) {
00323 clayer = GLO_MAX + dynamic_cast<GUIPolygon2D*>(o)->getLayer();
00324 }
00325 if (dynamic_cast<GUIPolygon2D*>(o)->getLayer()<0) {
00326 clayer = dynamic_cast<GUIPolygon2D*>(o)->getLayer();
00327 }
00328 }
00329 if (dynamic_cast<GUIPointOfInterest*>(o)!=0) {
00330 if (dynamic_cast<GUIPointOfInterest*>(o)->getLayer()>0) {
00331 clayer = GLO_MAX + dynamic_cast<GUIPointOfInterest*>(o)->getLayer();
00332 }
00333 if (dynamic_cast<GUIPointOfInterest*>(o)->getLayer()<0) {
00334 clayer = dynamic_cast<GUIPointOfInterest*>(o)->getLayer();
00335 }
00336 }
00337 }
00338
00339 if (prevLayer==-1000||prevLayer<clayer) {
00340 idMax = id;
00341 prevLayer = clayer;
00342 }
00343 }
00344 GUIGlObjectStorage::gIDStorage.unblockObject(id);
00345 assert(i*4+3<NB_HITS_MAX);
00346 }
00347 applyChanges(1, 0, 0);
00348 return idMax;
00349 }
00350
00351
00352 void
00353 GUISUMOAbstractView::showToolTipFor(unsigned int id) {
00354 if (id!=0) {
00355 GUIGlObject *object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
00356 int x, y;
00357 FXuint b;
00358 myApp->getCursorPosition(x, y, b);
00359 myToolTip->setObjectTip(object, x + myApp->getX(), y + myApp->getY());
00360 if (object!=0) {
00361 GUIGlObjectStorage::gIDStorage.unblockObject(id);
00362 }
00363 } else {
00364 myToolTip->hide();
00365 }
00366 }
00367
00368
00369 void
00370 GUISUMOAbstractView::paintGLGrid() {
00371 glEnable(GL_DEPTH_TEST);
00372 glLineWidth(1);
00373
00374 SUMOReal xmin = myGrid->xmin();
00375 SUMOReal ymin = myGrid->ymin();
00376 SUMOReal ypos = ymin;
00377 SUMOReal xpos = xmin;
00378 SUMOReal xend = myGrid->xmax();
00379 SUMOReal yend = myGrid->ymax();
00380
00381 glTranslated(0, 0, .55);
00382 glColor3d(0.5, 0.5, 0.5);
00383
00384 glBegin(GL_LINES);
00385 for (; ypos<yend;) {
00386 glVertex2d(xmin, ypos);
00387 glVertex2d(xend, ypos);
00388 ypos += myVisualizationSettings->gridYSize;
00389 }
00390
00391 for (; xpos<xend;) {
00392 glVertex2d(xpos, ymin);
00393 glVertex2d(xpos, yend);
00394 xpos += myVisualizationSettings->gridXSize;
00395 }
00396 glEnd();
00397 glTranslated(0, 0, -.55);
00398 }
00399
00400
00401 void
00402 GUISUMOAbstractView::applyChanges(SUMOReal scale, size_t xoff, size_t yoff) {
00403 myWidthInPixels = getWidth();
00404 myHeightInPixels = getHeight();
00405 glMatrixMode(GL_MODELVIEW);
00406 glLoadIdentity();
00407 myX1 = myY1 = 1;
00408 myAddScl = 1.;
00409
00410
00411
00412 glRotated(myChanger->getRotation(), 0, 0, 1);
00413
00414 myX1 /= (2.0/myNetScale);
00415 myY1 /= (2.0/myNetScale);
00416 glScaled(2.0/myNetScale, 2.0/myNetScale, 1);
00417
00418
00419 glScaled(1./myRatio, 1, 1);
00420 myX1 /= (1./myRatio);
00421 myY1 /= 1.;
00422 SUMOReal width = myGrid->getWidth();
00423 SUMOReal height = myGrid->getHeight();
00424
00425 SUMOReal xs = (SUMOReal)(1. / (width / myNetScale) * myRatio);
00426 SUMOReal ys = (SUMOReal)(1. / (height / myNetScale));
00427 if (xs<ys) {
00428 glScaled(xs, xs, 1);
00429 myX1 /= xs;
00430 myY1 /= xs;
00431 myAddScl *= xs;
00432 } else {
00433 glScaled(ys, ys, 1);
00434 myX1 /= ys;
00435 myY1 /= ys;
00436 myAddScl *= ys;
00437 }
00438
00439 glScaled(0.97, 0.97, 1.);
00440 myX1 /= 0.97;
00441 myY1 /= 0.97;
00442 myAddScl *= (SUMOReal) .97;
00443
00444
00445 SUMOReal zoom = (SUMOReal)(myChanger->getZoom() / 100.0 * scale);
00446 glScaled(zoom, zoom, 1);
00447 myX1 /= zoom;
00448 myY1 /= zoom;
00449
00450
00451 Position2D center = myGrid->getCenter();
00452 glTranslated(-center.x(), -center.y(), 0);
00453 myCX = center.x();
00454 myCY = center.y();
00455
00456 glTranslated(myChanger->getXPos(), myChanger->getYPos(), 0);
00457 myCX -= myChanger->getXPos();
00458 myCY -= myChanger->getYPos();
00459
00460 if (xoff!=0||yoff!=0) {
00461 SUMOReal absX = (SUMOReal)((SUMOReal)xoff-(((SUMOReal) myWidthInPixels)/2.0));
00462 SUMOReal absY = (SUMOReal)((SUMOReal)yoff-(((SUMOReal) myHeightInPixels)/2.0));
00463 glTranslated(-p2m(absX), p2m(absY), 0);
00464 myCX += p2m(absX);
00465 myCY -= p2m(absY);
00466 }
00467 glMatrixMode(GL_PROJECTION);
00468 glLoadIdentity();
00469 }
00470
00471
00472 void
00473 GUISUMOAbstractView::displayLegend() throw() {
00474
00475 size_t length = 1;
00476 const std::string text("10000000000");
00477 size_t noDigits = 1;
00478 size_t pixelSize = 0;
00479 while (true) {
00480 pixelSize = (size_t) m2p((SUMOReal) length);
00481 if (pixelSize>20) {
00482 break;
00483 }
00484 length *= 10;
00485 noDigits++;
00486 if (noDigits>text.length()) {
00487 return;
00488 }
00489 }
00490 SUMOReal lineWidth = 1.0;
00491 glLineWidth((SUMOReal) lineWidth);
00492
00493 glMatrixMode(GL_PROJECTION);
00494 glPushMatrix();
00495 glLoadIdentity();
00496 glMatrixMode(GL_MODELVIEW);
00497 glPushMatrix();
00498 glLoadIdentity();
00499
00500
00501 glDisable(GL_TEXTURE_2D);
00502 glDisable(GL_ALPHA_TEST);
00503 glDisable(GL_BLEND);
00504 glEnable(GL_DEPTH_TEST);
00505
00506 SUMOReal len = (SUMOReal) pixelSize / (SUMOReal)(myWidthInPixels-1) * (SUMOReal) 2.0;
00507 glColor3d(0, 0, 0);
00508 double o = double(15) / double(myHeightInPixels);
00509 double o2 = o + o;
00510 double oo = double(5) / double(myHeightInPixels);
00511 glBegin(GL_LINES);
00512
00513 glVertex2d(-.98, -1.+o);
00514 glVertex2d(-.98+len, -1.+o);
00515
00516 glVertex2d(-.98, -1.+o);
00517 glVertex2d(-.98, -1.+o2);
00518
00519 glVertex2d(-.98+len, -1.+o);
00520 glVertex2d(-.98+len, -1.+o2);
00521 glEnd();
00522
00523 SUMOReal w = SUMOReal(35) / SUMOReal(myWidthInPixels);
00524 SUMOReal h = SUMOReal(35) / SUMOReal(myHeightInPixels);
00525 pfSetPosition(SUMOReal(-0.99), SUMOReal(1.-o2-oo));
00526 pfSetScaleXY(w, h);
00527 glRotated(180, 1, 0, 0);
00528 pfDrawString("0m");
00529 glRotated(-180, 1, 0, 0);
00530
00531 pfSetPosition(SUMOReal(-.99+len), SUMOReal(1.-o2-oo));
00532 glRotated(180, 1, 0, 0);
00533 pfDrawString((text.substr(0, noDigits) + "m").c_str());
00534 glRotated(-180, 1, 0, 0);
00535
00536
00537 glMatrixMode(GL_PROJECTION);
00538 glPopMatrix();
00539 glMatrixMode(GL_MODELVIEW);
00540 glPopMatrix();
00541 }
00542
00543
00544 SUMOReal
00545 GUISUMOAbstractView::m2p(SUMOReal meter) {
00546 return (SUMOReal)(meter / myNetScale
00547 *(myWidthInPixels/myRatio)
00548 * myAddScl * myChanger->getZoom() / (SUMOReal) 100.0);
00549 }
00550
00551
00552 SUMOReal
00553 GUISUMOAbstractView::p2m(SUMOReal pixel) {
00554 return (SUMOReal) pixel * myNetScale /
00555 ((myWidthInPixels/myRatio) * myAddScl * myChanger->getZoom() / (SUMOReal) 100.0);
00556 }
00557
00558
00559 void
00560 GUISUMOAbstractView::recenterView() {
00561 myChanger->recenterView();
00562 }
00563
00564
00565 void
00566 GUISUMOAbstractView::centerTo(const GUIGlObject * const o) throw() {
00567 centerTo(o->getCenteringBoundary());
00568 update();
00569 }
00570
00571
00572 void
00573 GUISUMOAbstractView::centerTo(Boundary bound) {
00574 myChanger->centerTo(*myGrid, bound);
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 void
00586 GUISUMOAbstractView::setWindowCursorPosition(FXint x, FXint y) {
00587 myWindowCursorPositionX = x;
00588 myWindowCursorPositionY = y;
00589 }
00590
00591
00592 FXbool
00593 GUISUMOAbstractView::makeCurrent() {
00594 FXbool ret = FXGLCanvas::makeCurrent();
00595 return ret;
00596 }
00597
00598
00599
00600 long
00601 GUISUMOAbstractView::onConfigure(FXObject*,FXSelector,void*) {
00602 if (makeCurrent()) {
00603 myWidthInPixels = getWidth();
00604 myHeightInPixels = getHeight();
00605 myRatio = (SUMOReal) myWidthInPixels / (SUMOReal) myHeightInPixels;
00606 glViewport(0, 0, myWidthInPixels-1, myHeightInPixels-1);
00607 glClearColor(
00608 myVisualizationSettings->backgroundColor.red(),
00609 myVisualizationSettings->backgroundColor.green(),
00610 myVisualizationSettings->backgroundColor.blue(),
00611 1);
00612 myChanger->applyCanvasSize(width, height);
00613 doInit();
00614 myAmInitialised = true;
00615 makeNonCurrent();
00616 checkSnapshots();
00617 }
00618 return 1;
00619 }
00620
00621
00622 long
00623 GUISUMOAbstractView::onPaint(FXObject*,FXSelector,void*) {
00624 if (!isEnabled()||!myAmInitialised) {
00625 return 1;
00626 }
00627 if (makeCurrent()) {
00628 paintGL();
00629 makeNonCurrent();
00630 }
00631 return 1;
00632 }
00633
00634
00635 long
00636 GUISUMOAbstractView::onLeftBtnPress(FXObject *,FXSelector ,void *data) {
00637 delete myPopup;
00638 myPopup = 0;
00639 FXEvent *e = (FXEvent*) data;
00640
00641 if (e->state&CONTROLMASK) {
00642
00643 if (makeCurrent()) {
00644 unsigned int id = getObjectUnderCursor();
00645 if (id!=0) {
00646 gSelected.toggleSelection(id);
00647 }
00648 makeNonCurrent();
00649 if (id!=0) {
00650
00651
00652 update();
00653 }
00654 }
00655 }
00656 myChanger->onLeftBtnPress(data);
00657 grab();
00658 return 1;
00659 }
00660
00661
00662 long
00663 GUISUMOAbstractView::onLeftBtnRelease(FXObject *,FXSelector ,void *data) {
00664 delete myPopup;
00665 myPopup = 0;
00666 myChanger->onLeftBtnRelease(data);
00667 if (myApp->isGaming()) {
00668 onGamingClick(getPositionInformation());
00669 }
00670 ungrab();
00671 return 1;
00672 }
00673
00674
00675 long
00676 GUISUMOAbstractView::onRightBtnPress(FXObject *,FXSelector ,void *data) {
00677 delete myPopup;
00678 myPopup = 0;
00679 myChanger->onRightBtnPress(data);
00680 grab();
00681 return 1;
00682 }
00683
00684
00685 long
00686 GUISUMOAbstractView::onRightBtnRelease(FXObject *,FXSelector ,void *data) {
00687 delete myPopup;
00688 myPopup = 0;
00689 if (!myChanger->onRightBtnRelease(data)) {
00690 openObjectDialog();
00691 }
00692 ungrab();
00693 return 1;
00694 }
00695
00696
00697 long
00698 GUISUMOAbstractView::onMouseWheel(FXObject *,FXSelector ,void *data) {
00699 myChanger->onMouseWheel(data);
00700 return 1;
00701 }
00702
00703
00704 long
00705 GUISUMOAbstractView::onMouseMove(FXObject *,FXSelector ,void *data) {
00706 SUMOReal xpos = myChanger->getXPos();
00707 SUMOReal ypos = myChanger->getYPos();
00708 SUMOReal zoom = myChanger->getZoom();
00709 if (myViewportChooser==0||!myViewportChooser->haveGrabbed()) {
00710 myChanger->onMouseMove(data);
00711 }
00712 if (myViewportChooser!=0 &&
00713 (xpos!=myChanger->getXPos()||ypos!=myChanger->getYPos()||zoom!=myChanger->getZoom())) {
00714
00715 myViewportChooser->setValues(
00716 myChanger->getZoom(), myChanger->getXPos(), myChanger->getYPos());
00717
00718 }
00719 updatePositionInformation();
00720 return 1;
00721 }
00722
00723
00724 long
00725 GUISUMOAbstractView::onMouseLeft(FXObject *,FXSelector ,void *data) {
00726 if (myViewportChooser==0||!myViewportChooser->haveGrabbed()) {
00727
00728 myToolTip->setObjectTip(0, -1, -1);
00729 }
00730 return 1;
00731 }
00732
00733
00734 void
00735 GUISUMOAbstractView::openObjectDialog() {
00736 ungrab();
00737 if (!isEnabled()||!myAmInitialised) {
00738 return;
00739 }
00740 if (makeCurrent()) {
00741
00742 unsigned int id = getObjectUnderCursor();
00743 GUIGlObject *o = 0;
00744 if (id!=0) {
00745 o = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
00746 } else {
00747 o = GUIGlObjectStorage::gIDStorage.getNetObject();
00748 }
00749 if (o!=0) {
00750 myPopup = o->getPopUpMenu(*myApp, *this);
00751 int x, y;
00752 FXuint b;
00753 myApp->getCursorPosition(x, y, b);
00754 myPopup->setX(x + myApp->getX());
00755 myPopup->setY(y + myApp->getY());
00756 myPopup->create();
00757 myPopup->show();
00758 myChanger->onRightBtnRelease(0);
00759 }
00760 makeNonCurrent();
00761 }
00762 }
00763
00764
00765 long
00766 GUISUMOAbstractView::onKeyPress(FXObject *o,FXSelector sel,void *data) {
00767 FXEvent *e = (FXEvent*) data;
00768 if ((e->state&ALTMASK)!=0) {
00769 setDefaultCursor(getApp()->getDefaultCursor(DEF_CROSSHAIR_CURSOR));
00770 grabKeyboard();
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 return FXGLCanvas::onKeyPress(o, sel, data);
00791 }
00792
00793
00794 long
00795 GUISUMOAbstractView::onKeyRelease(FXObject *o,FXSelector sel,void *data) {
00796 FXEvent *e = (FXEvent*) data;
00797 if ((e->state&ALTMASK)==0) {
00798 ungrabKeyboard();
00799 setDefaultCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
00800 }
00801 return FXGLCanvas::onKeyRelease(o, sel, data);
00802 }
00803
00804
00805 void
00806 GUISUMOAbstractView::checkSnapshots() {
00807 std::map<SUMOTime, std::string>::iterator snapIt = mySnapshots.find(MSNet::getInstance()->getCurrentTimeStep());
00808 if (snapIt != mySnapshots.end()) {
00809 FXColor *buf = getSnapshot();
00810 try {
00811 if (!MFXImageHelper::saveImage(snapIt->second, getWidth(), getHeight(), buf)) {
00812 MsgHandler::getWarningInstance()->inform("Could not save '" + snapIt->second + "'.");
00813 }
00814 } catch (InvalidArgument e) {
00815 MsgHandler::getWarningInstance()->inform("Could not save '" + snapIt->second + "'.\n" + e.what());
00816 }
00817 FXFREE(&buf);
00818 }
00819 }
00820
00821
00822 void
00823 GUISUMOAbstractView::setSnapshots(std::map<SUMOTime, std::string> snaps) {
00824 mySnapshots.insert(snaps.begin(), snaps.end());
00825 }
00826
00827
00828 FXColor *
00829 GUISUMOAbstractView::getSnapshot() {
00830 makeCurrent();
00831
00832
00833 glClearColor(
00834 myVisualizationSettings->backgroundColor.red(),
00835 myVisualizationSettings->backgroundColor.green(),
00836 myVisualizationSettings->backgroundColor.blue(),
00837 1);
00838 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00839 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00840
00841 if (myVisualizationSettings->dither) {
00842 glEnable(GL_DITHER);
00843 } else {
00844 glDisable(GL_DITHER);
00845 }
00846 if (myVisualizationSettings->antialiase) {
00847 glEnable(GL_BLEND);
00848 glEnable(GL_POLYGON_SMOOTH);
00849 glEnable(GL_LINE_SMOOTH);
00850 } else {
00851 glDisable(GL_BLEND);
00852 glDisable(GL_POLYGON_SMOOTH);
00853 glDisable(GL_LINE_SMOOTH);
00854 }
00855
00856 applyChanges(1.0, 0, 0);
00857 doPaintGL(GL_RENDER, 1.0);
00858 if (myVisualizationSettings->showSizeLegend) {
00859 displayLegend();
00860 }
00861
00862 glFlush();
00863 swapBuffers();
00864 glFinish();
00865 FXColor *buf;
00866 FXMALLOC(&buf, FXColor, getWidth()*getHeight());
00867
00868 glReadBuffer(GL_BACK);
00869
00870 glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
00871
00872 makeNonCurrent();
00873 update();
00874
00875 size_t mwidth = getWidth();
00876 size_t mheight = getHeight();
00877 FXColor *paa = buf;
00878 FXColor *pbb = buf + mwidth * (mheight-1);
00879 do {
00880 FXColor *pa=paa;
00881 paa+=mwidth;
00882 FXColor *pb=pbb;
00883 pbb-=mwidth;
00884 do {
00885 FXColor t=*pa;
00886 *pa++=*pb;
00887 *pb++=t;
00888 } while (pa<paa);
00889 } while (paa<pbb);
00890 return buf;
00891 }
00892
00893
00894 void
00895 GUISUMOAbstractView::showViewportEditor() {
00896 if (myViewportChooser==0) {
00897 myViewportChooser =
00898 new GUIDialog_EditViewport(this, "Edit Viewport...",
00899 myChanger->getZoom(), myChanger->getXPos(), myChanger->getYPos(),
00900 0, 0);
00901 myViewportChooser->create();
00902 }
00903 myViewportChooser->setOldValues(
00904 myChanger->getZoom(), myChanger->getXPos(), myChanger->getYPos());
00905 myViewportChooser->show();
00906 }
00907
00908
00909 void
00910 GUISUMOAbstractView::setViewport(SUMOReal zoom, SUMOReal xPos, SUMOReal yPos) {
00911 myChanger->setViewport(zoom, xPos, yPos);
00912 update();
00913 }
00914
00915
00916 void
00917 GUISUMOAbstractView::showToolTips(bool val) {
00918 myUseToolTips = val;
00919 }
00920
00921
00922
00923 SUMOReal
00924 GUISUMOAbstractView::getGridWidth() const {
00925 return myGrid->getWidth();
00926 }
00927
00928
00929 SUMOReal
00930 GUISUMOAbstractView::getGridHeight() const {
00931 return myGrid->getHeight();
00932 }
00933
00934
00935 FXComboBox &
00936 GUISUMOAbstractView::getColoringSchemesCombo() {
00937 return myParent->getColoringSchemesCombo();
00938 }
00939
00940
00941 void
00942 GUISUMOAbstractView::drawDecals() throw() {
00943 glTranslated(0, 0, .99);
00944 myDecalsLock.lock();
00945 for (std::vector<GUISUMOAbstractView::Decal>::iterator l=myDecals.begin(); l!=myDecals.end();) {
00946 GUISUMOAbstractView::Decal &d = *l;
00947 if (!d.initialised) {
00948 try {
00949 FXImage *i = MFXImageHelper::loadImage(getApp(), d.filename);
00950 if (MFXImageHelper::scalePower2(i)) {
00951 MsgHandler::getWarningInstance()->inform("Scaling '" + d.filename + "'.");
00952 }
00953 d.glID = GUITexturesHelper::add(i);
00954 d.initialised = true;
00955 } catch (InvalidArgument e) {
00956 MsgHandler::getErrorInstance()->inform("Could not load '" + d.filename + "'.\n" + e.what());
00957 l = myDecals.erase(l);
00958 continue;
00959 }
00960 }
00961 glPushMatrix();
00962 glTranslated(d.centerX, d.centerY, 0);
00963 glRotated(d.rot, 0, 0, 1);
00964 glColor3d(1,1,1);
00965 SUMOReal halfWidth((d.width / 2.));
00966 SUMOReal halfHeight((d.height / 2.));
00967 GUITexturesHelper::drawTexturedBox(d.glID, -halfWidth, -halfHeight, halfWidth, halfHeight);
00968 glPopMatrix();
00969 ++l;
00970 }
00971 myDecalsLock.unlock();
00972 glTranslated(0, 0, -.99);
00973 }
00974
00975
00976
00977
00978