SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // A class that allows to steer the visual output in dependence to 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 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <utils/geom/Boundary.h> 00034 #include <utils/geom/Position.h> 00035 #include <utils/gui/settings/GUICompleteSchemeStorage.h> 00036 #include "GUIPerspectiveChanger.h" 00037 #include "GUIDanielPerspectiveChanger.h" 00038 00039 #ifdef CHECK_MEMORY_LEAKS 00040 #include <foreign/nvwa/debug_new.h> 00041 #endif // CHECK_MEMORY_LEAKS 00042 00043 00044 // =========================================================================== 00045 // method definitions 00046 // =========================================================================== 00047 GUIDanielPerspectiveChanger::GUIDanielPerspectiveChanger( 00048 GUISUMOAbstractView& callBack, const Boundary& viewPort) : 00049 GUIPerspectiveChanger(callBack, viewPort), 00050 myOrigWidth(viewPort.getWidth()), 00051 myOrigHeight(viewPort.getHeight()), 00052 myRotation(0), 00053 myMouseButtonState(MOUSEBTN_NONE), 00054 myMoveOnClick(false), 00055 myDragDelay(0) {} 00056 00057 00058 GUIDanielPerspectiveChanger::~GUIDanielPerspectiveChanger() {} 00059 00060 00061 void 00062 GUIDanielPerspectiveChanger::move(int xdiff, int ydiff) { 00063 myViewPort.moveby(myCallback.p2m(xdiff), -myCallback.p2m(ydiff)); 00064 myCallback.update(); 00065 } 00066 00067 00068 void 00069 GUIDanielPerspectiveChanger::zoom(SUMOReal factor) { 00070 if (myCallback.getApp()->reg().readIntEntry("gui", "zoomAtCenter", 1)) { 00071 myZoomBase = myViewPort.getCenter(); 00072 } 00073 if (factor > 0) { 00074 myViewPort = Boundary( 00075 myZoomBase.x() - (myZoomBase.x() - myViewPort.xmin()) / factor, 00076 myZoomBase.y() - (myZoomBase.y() - myViewPort.ymin()) / factor, 00077 myZoomBase.x() - (myZoomBase.x() - myViewPort.xmax()) / factor, 00078 myZoomBase.y() - (myZoomBase.y() - myViewPort.ymax()) / factor); 00079 myCallback.update(); 00080 } 00081 } 00082 00083 00084 void 00085 GUIDanielPerspectiveChanger::rotate(int diff) { 00086 if (false) {//myCallback.allowRotation()) { 00087 myRotation += (SUMOReal) diff / (SUMOReal) 10.0; 00088 myCallback.update(); 00089 } 00090 } 00091 00092 00093 SUMOReal 00094 GUIDanielPerspectiveChanger::getRotation() const { 00095 return myRotation; 00096 } 00097 00098 00099 SUMOReal 00100 GUIDanielPerspectiveChanger::getXPos() const { 00101 return myViewPort.getCenter().x(); 00102 } 00103 00104 00105 SUMOReal 00106 GUIDanielPerspectiveChanger::getYPos() const { 00107 return myViewPort.getCenter().y(); 00108 } 00109 00110 00111 SUMOReal 00112 GUIDanielPerspectiveChanger::getZoom() const { 00113 return myOrigWidth / myViewPort.getWidth() * 100; 00114 } 00115 00116 00117 void 00118 GUIDanielPerspectiveChanger::centerTo(const Position& pos, SUMOReal radius, 00119 bool applyZoom) { 00120 if (applyZoom) { 00121 myViewPort = Boundary(); 00122 myViewPort.add(pos); 00123 myViewPort.grow(radius); 00124 } else { 00125 myViewPort.moveby(pos.x() - getXPos(), pos.y() - getYPos()); 00126 } 00127 } 00128 00129 00130 void 00131 GUIDanielPerspectiveChanger::onLeftBtnPress(void* data) { 00132 myMouseButtonState |= MOUSEBTN_LEFT; 00133 FXEvent* e = (FXEvent*) data; 00134 myMouseXPosition = e->win_x; 00135 myMouseYPosition = e->win_y; 00136 myMoveOnClick = false; 00137 myMouseDownTime = FXThread::time(); 00138 } 00139 00140 00141 bool 00142 GUIDanielPerspectiveChanger::onLeftBtnRelease(void* data) { 00143 myMouseButtonState &= !MOUSEBTN_LEFT; 00144 FXEvent* e = (FXEvent*) data; 00145 myMouseXPosition = e->win_x; 00146 myMouseYPosition = e->win_y; 00147 return myMoveOnClick; 00148 } 00149 00150 00151 void 00152 GUIDanielPerspectiveChanger::onRightBtnPress(void* data) { 00153 myMouseButtonState |= MOUSEBTN_RIGHT; 00154 FXEvent* e = (FXEvent*) data; 00155 myMouseXPosition = e->win_x; 00156 myMouseYPosition = e->win_y; 00157 myMoveOnClick = false; 00158 myMouseDownTime = FXThread::time(); 00159 myZoomBase = myCallback.getPositionInformation(); 00160 } 00161 00162 00163 bool 00164 GUIDanielPerspectiveChanger::onRightBtnRelease(void* data) { 00165 myMouseButtonState &= !MOUSEBTN_RIGHT; 00166 if (data != 0) { 00167 FXEvent* e = (FXEvent*) data; 00168 myMouseXPosition = e->win_x; 00169 myMouseYPosition = e->win_y; 00170 } 00171 return myMoveOnClick; 00172 } 00173 00174 00175 void 00176 GUIDanielPerspectiveChanger::onMouseWheel(void* data) { 00177 FXEvent* e = (FXEvent*) data; 00178 SUMOReal diff = 0.1; 00179 if (e->state & CONTROLMASK) { 00180 diff /= 2; 00181 } else if (e->state & SHIFTMASK) { 00182 diff *= 2; 00183 } 00184 if (e->code < 0) { 00185 diff = -diff; 00186 } 00187 myZoomBase = myCallback.getPositionInformation(); 00188 zoom(1.0 + diff); 00189 myCallback.updateToolTip(); 00190 } 00191 00192 00193 void 00194 GUIDanielPerspectiveChanger::onMouseMove(void* data) { 00195 FXEvent* e = (FXEvent*) data; 00196 myCallback.setWindowCursorPosition(e->win_x, e->win_y); 00197 const int xdiff = myMouseXPosition - e->win_x; 00198 const int ydiff = myMouseYPosition - e->win_y; 00199 const bool moved = xdiff != 0 || ydiff != 0; 00200 const bool pastDelay = FXThread::time() > (myMouseDownTime + myDragDelay); 00201 switch (myMouseButtonState) { 00202 case MOUSEBTN_LEFT: 00203 if (pastDelay) { 00204 move(xdiff, ydiff); 00205 if (moved) { 00206 myMoveOnClick = true; 00207 } 00208 } 00209 break; 00210 case MOUSEBTN_RIGHT: 00211 if (pastDelay) { 00212 zoom(1 + 10.0 * ydiff / myCallback.getWidth()); 00213 rotate(xdiff); 00214 if (moved) { 00215 myMoveOnClick = true; 00216 } 00217 } 00218 break; 00219 default: 00220 if (moved) { 00221 myCallback.updateToolTip(); 00222 } 00223 break; 00224 } 00225 myMouseXPosition = e->win_x; 00226 myMouseYPosition = e->win_y; 00227 } 00228 00229 00230 void 00231 GUIDanielPerspectiveChanger::setViewport(SUMOReal zoom, 00232 SUMOReal xPos, SUMOReal yPos) { 00233 const SUMOReal zoomFactor = zoom / 50; // /100 to normalize, *2 because growth is added on both sides 00234 myViewPort = Boundary(); 00235 myViewPort.add(Position(xPos, yPos)); 00236 myViewPort.growHeight(myOrigHeight / zoomFactor); 00237 myViewPort.growWidth(myOrigWidth / zoomFactor); 00238 myCallback.update(); 00239 } 00240 00241 00242 void 00243 GUIDanielPerspectiveChanger::changeCanvassLeft(int change) { 00244 myViewPort = Boundary( 00245 myViewPort.xmin() - myCallback.p2m(change), 00246 myViewPort.ymin(), 00247 myViewPort.xmax(), 00248 myViewPort.ymax()); 00249 } 00250 00251 /****************************************************************************/