GUISUMOAbstractView.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The base class for a view
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
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 // member method definitions
00085 // ===========================================================================
00086 /* -------------------------------------------------------------------------
00087  * GUISUMOAbstractView - FOX callback mapping
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  * GUISUMOAbstractView - methods
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     // compute the net scale
00133     SUMOReal nw = myGrid->getWidth();
00134     SUMOReal nh = myGrid->getHeight();
00135     myNetScale = (nw < nh ? nh : nw);
00136     // show the middle at the beginning
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     // compute the offset
00180     SUMOReal cy = myChanger->getYPos();
00181     SUMOReal cx = myChanger->getXPos();
00182     // compute the visible area
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     // draw
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     // check whether the select mode /tooltips)
00259     //  shall be computed, too
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     // Prepare the selection mode
00283     static GLuint hits[NB_HITS_MAX];
00284     static GLint nb_hits = 0;
00285     glSelectBuffer(NB_HITS_MAX, hits);
00286     glInitNames();
00287     // compute new scale
00288     SUMOReal scale = SUMOReal(getWidth())/SUMOReal(SENSITIVITY);
00289     applyChanges(scale, myWindowCursorPositionX+myMouseHotspotX, myWindowCursorPositionY+myMouseHotspotY);
00290     // paint in select mode
00291     bool tmp = myUseToolTips;
00292     myUseToolTips = true;
00293     int hits2 = doPaintGL(GL_SELECT, scale);
00294     myUseToolTips = tmp;
00295     // Get the results
00296     nb_hits = glRenderMode(GL_RENDER);
00297     if (nb_hits==0||hits2==0) {
00298         applyChanges(1, 0, 0);
00299         return 0;
00300     }
00301     // Interpret results
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             // determine an "abstract" layer for shapes
00318             //  this "layer" resembles the layer of the shape
00319             //  taking into account the stac of other objects
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             // check whether the current object is above a previous one
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     // draw horizontal lines
00384     glBegin(GL_LINES);
00385     for (; ypos<yend;) {
00386         glVertex2d(xmin, ypos);
00387         glVertex2d(xend, ypos);
00388         ypos += myVisualizationSettings->gridYSize;
00389     }
00390     // draw vertical lines
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     // rotate first;
00410     //  This is quite unchecked, so it's meaning and position is quite
00411     //  unclear
00412     glRotated(myChanger->getRotation(), 0, 0, 1);
00413     // Fit the view's size to the size of the net
00414     myX1 /= (2.0/myNetScale);
00415     myY1 /= (2.0/myNetScale);
00416     glScaled(2.0/myNetScale, 2.0/myNetScale, 1);
00417     //myAddScl *= (2.0/myNetScale);
00418     // apply ratio between window width and height
00419     glScaled(1./myRatio, 1, 1);
00420     myX1 /= (1./myRatio);
00421     myY1 /= 1.;
00422     SUMOReal width = myGrid->getWidth();
00423     SUMOReal height = myGrid->getHeight();
00424     // initially (zoom=100), the net shall be completely visible on the screen
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     // initially, leave some room for the net
00439     glScaled(0.97, 0.97, 1.);
00440     myX1 /= 0.97;
00441     myY1 /= 0.97;
00442     myAddScl *= (SUMOReal) .97;
00443 
00444     // Apply the zoom and the scale
00445     SUMOReal zoom = (SUMOReal)(myChanger->getZoom() / 100.0 * scale);
00446     glScaled(zoom, zoom, 1);
00447     myX1 /= zoom;
00448     myY1 /= zoom;
00449     //myAddScl *= zoom;
00450     // Translate to the middle of the net
00451     Position2D center = myGrid->getCenter();
00452     glTranslated(-center.x(), -center.y(), 0);
00453     myCX = center.x();
00454     myCY = center.y();
00455     // Translate in dependence to the view position applied by the user
00456     glTranslated(myChanger->getXPos(), myChanger->getYPos(), 0);
00457     myCX -= myChanger->getXPos();
00458     myCY -= myChanger->getYPos();
00459     // Translate to the mouse pointer, when wished
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     // compute the scale bar length
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     // draw the scale bar
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     // vertical
00513     glVertex2d(-.98, -1.+o);
00514     glVertex2d(-.98+len, -1.+o);
00515     // tick at begin
00516     glVertex2d(-.98, -1.+o);
00517     glVertex2d(-.98, -1.+o2);
00518     // tick at end
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     // restore matrices
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 bool
00579 GUISUMOAbstractView::allowRotation() const
00580 {
00581     return myParent->allowRotation();
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     // check whether the selection-mode is activated
00641     if (e->state&CONTROLMASK) {
00642         // try to get the object-id if so
00643         if (makeCurrent()) {
00644             unsigned int id = getObjectUnderCursor();
00645             if (id!=0) {
00646                 gSelected.toggleSelection(id);
00647             }
00648             makeNonCurrent();
00649             if (id!=0) {
00650                 // possibly, the selection-colouring is used,
00651                 //  so we should update the screen again...
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 //        myChanger->onMouseLeft();
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         // initialise the select mode
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     switch(e->code) {
00774     case KEY_Left:
00775         myChanger->move((SUMOReal) -p2m((SUMOReal) getWidth()/10), 0);
00776         break;
00777     case KEY_Right:
00778         myChanger->move((SUMOReal) p2m((SUMOReal) getWidth()/10), 0);
00779         break;
00780     case KEY_Up:
00781         myChanger->move(0, (SUMOReal) -p2m((SUMOReal) getHeight()/10));
00782         break;
00783     case KEY_Down:
00784         myChanger->move(0, (SUMOReal) p2m((SUMOReal) getHeight()/10));
00785         break;
00786     default:
00787         break;
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     // draw
00832     // draw
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     // read from the back buffer
00868     glReadBuffer(GL_BACK);
00869     // Read the pixels
00870     glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)buf);
00871     // !!! flip orientation
00872     makeNonCurrent();
00873     update();
00874     // mirror
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 

Generated on Wed May 5 00:06:30 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6