1 #if defined(_MSC_VER) /* MSVC Compiler */ 2 #pragma warning ( disable : 4305 ) 3 #pragma warning ( disable : 4786 ) 4 #endif 5 6 #include "qwt3d_extglwidget.h" 7 8 using namespace std; 9 using namespace Qwt3D; 10 11 12 /** 13 Standard mouse button Function. Prepares the call to mouseMoveEvent 14 \see mouseMoveEvent() 15 */ 16 void ExtGLWidget::mousePressEvent( QMouseEvent *e ) 17 { 18 lastMouseMovePosition_ = e->pos(); 19 mpressed_ = true; 20 } 21 22 /** 23 Standard mouse button Function. Completes the call to mouseMoveEvent 24 \see mouseMoveEvent() 25 */ 26 void ExtGLWidget::mouseReleaseEvent( QMouseEvent* ) 27 { 28 mpressed_ = false; 29 } 30 31 /** 32 Standard mouse button Function 33 \see assignMouse() 34 */ 35 void ExtGLWidget::mouseMoveEvent( QMouseEvent *e ) 36 { 37 if (!mpressed_ || !mouseEnabled()) { 38 e->ignore(); 39 return; 40 } 41 42 #if QT_VERSION < 0x040000 43 MouseState bstate = e->state(); 44 #else 45 MouseState bstate(e->buttons(),e->modifiers()); 46 #endif 47 48 QPoint diff = e->pos() - lastMouseMovePosition_; 49 50 setRotationMouse(bstate, 3, diff); 51 setScaleMouse(bstate, 5, diff); 52 setShiftMouse(bstate, 2, diff); 53 54 lastMouseMovePosition_ = e->pos(); 55 } 56 57 void ExtGLWidget::setRotationMouse(MouseState bstate, double accel, QPoint diff) 58 { 59 // Rotation 60 double w = max(1,width()); 61 double h = max(1,height()); 62 63 double relx = accel*360 * diff.x() / w; 64 double relyz = accel*360 * diff.y() / h; 65 66 double new_xrot = xRotation(); 67 double new_yrot = yRotation(); 68 double new_zrot = zRotation(); 69 70 if ( bstate == xrot_mstate_ ) 71 new_xrot = round(xRotation() + relyz) % 360; 72 if ( bstate == yrot_mstate_ ) 73 new_yrot = round(yRotation() + relx) % 360; 74 if ( bstate == zrot_mstate_ ) 75 new_zrot = round(zRotation() + relx) % 360; 76 77 setRotation(new_xrot, new_yrot, new_zrot); 78 } 79 80 void ExtGLWidget::setScaleMouse(MouseState bstate, double accel, QPoint diff) 81 { 82 // Scale 83 double w = max(1,width()); 84 double h = max(1,height()); 85 86 double relx = diff.x() * accel / w; relx = exp(relx) - 1; 87 double relyz = diff.y() * accel / h; relyz = exp(relyz) - 1; 88 89 double new_xscale = xScale(); 90 double new_yscale = yScale(); 91 double new_zscale = zScale(); 92 93 if ( bstate == xscale_mstate_) 94 new_xscale = max(0.0,xScale() + relx); 95 if ( bstate == yscale_mstate_) 96 new_yscale = max(0.0,yScale() - relyz); 97 if ( bstate == zscale_mstate_) 98 new_zscale = max(0.0,zScale() - relyz); 99 100 setScale(new_xscale, new_yscale, new_zscale); 101 102 if ( bstate == zoom_mstate_) 103 setZoom(max(0.0,zoom() - relyz)); 104 } 105 106 void ExtGLWidget::setShiftMouse(MouseState bstate, double accel, QPoint diff) 107 { 108 // Shift 109 double w = max(1,width()); 110 double h = max(1,height()); 111 112 double relx = diff.x() * accel / w; 113 double relyz = diff.y() * accel / h; 114 115 double new_xshift = xViewportShift(); 116 double new_yshift = yViewportShift(); 117 118 if ( bstate == xshift_mstate_) 119 new_xshift = xViewportShift() + relx; 120 if ( bstate == yshift_mstate_) 121 new_yshift = yViewportShift() - relyz; 122 123 setViewportShift(new_xshift, new_yshift); 124 } 125 126 /** 127 Standard wheel Function - zoom (wheel only) or z-scale (shift+wheel) 128 */ 129 void ExtGLWidget::wheelEvent( QWheelEvent *e ) 130 { 131 if (!mouseEnabled()) return; 132 133 double accel = 0.05; 134 double step = accel * e->delta() / WHEEL_DELTA ; 135 step = exp(step)-1; 136 137 #if QT_VERSION < 0x040000 138 if ( e->state() & Qt::ShiftButton ) 139 #else 140 if ( e->modifiers() & Qt::ShiftModifier ) 141 #endif 142 setScale(xScale(),yScale(), max(0.0,zScale() + step)); 143 else 144 setZoom(max(0.0,zoom() + step )); 145 } 146 147 /** 148 Sets the key/mousebutton combination for data/coordinatesystem moves inside the widget\n\n 149 default behaviour:\n 150 151 \verbatim 152 rotate around x axis: Qt::LeftButton 153 rotate around y axis: Qt::LeftButton | Qt::ShiftButton 154 rotate around z axis: Qt::LeftButton 155 scale x: Qt::LeftButton | Qt::AltButton 156 scale y: Qt::LeftButton | Qt::AltButton 157 scale z: Qt::LeftButton | Qt::AltButton | Qt::ShiftButton 158 zoom: Qt::LeftButton | Qt::AltButton | Qt::ControlButton 159 shifting along x: Qt::LeftButton | Qt::ControlButton 160 shifting along y: Qt::LeftButton | Qt::ControlButton 161 \endverbatim 162 163 mouseMoveEvent() evaluates this function - if overridden, their usefulness becomes somehow limited 164 */ 165 void ExtGLWidget::assignMouse(MouseState xrot, MouseState yrot, MouseState zrot, 166 MouseState xscale, MouseState yscale, MouseState zscale, 167 MouseState zoom, MouseState xshift, MouseState yshift) 168 { 169 xrot_mstate_ = xrot; 170 yrot_mstate_ = yrot; 171 zrot_mstate_ = zrot; 172 xscale_mstate_ = xscale; 173 yscale_mstate_ = yscale; 174 zscale_mstate_ = zscale; 175 zoom_mstate_ = zoom; 176 xshift_mstate_ = xshift; 177 yshift_mstate_ = yshift; 178 } 179 180 /** 181 The function has no effect if you derive from ExtGLWidget and overrides the mouse Function too careless. 182 In this case check first against mouseEnabled() in your version of mouseMoveEvent() and wheelEvent(). 183 A more fine grained input control can be achieved by combining assignMouse() with enableMouse(). 184 */ 185 void ExtGLWidget::enableMouse(bool val) {mouse_input_enabled_ = val;} 186 187 /** 188 \see enableMouse() 189 */ 190 void ExtGLWidget::disableMouse(bool val) {mouse_input_enabled_ = !val;} 191 bool ExtGLWidget::mouseEnabled() const {return mouse_input_enabled_;} 192 193 194 void ExtGLWidget::keyPressEvent( QKeyEvent *e ) 195 { 196 if (!keyboardEnabled()) { 197 e->ignore(); 198 return; 199 } 200 201 #if QT_VERSION < 0x040000 202 int bstate = e->state() & Qt::KeyButtonMask; // filter kbd modifier only 203 KeyboardState keyseq = bstate + e->key(); 204 #else 205 KeyboardState keyseq(e->key(), e->modifiers()); 206 #endif 207 208 setRotationKeyboard(keyseq, kbd_rot_speed_); 209 setScaleKeyboard(keyseq, kbd_scale_speed_); 210 setShiftKeyboard(keyseq, kbd_shift_speed_); 211 } 212 213 void ExtGLWidget::setRotationKeyboard(KeyboardState kseq, double speed) 214 { 215 // Rotation 216 double w = max(1,width()); 217 double h = max(1,height()); 218 219 double relx = speed*360 / w; 220 double relyz = speed*360 / h; 221 222 double new_xrot = xRotation(); 223 double new_yrot = yRotation(); 224 double new_zrot = zRotation(); 225 226 if ( kseq == xrot_kstate_[0] ) 227 new_xrot = round(xRotation() + relyz) % 360; 228 if ( kseq == xrot_kstate_[1] ) 229 new_xrot = round(xRotation() - relyz) % 360; 230 if ( kseq == yrot_kstate_[0] ) 231 new_yrot = round(yRotation() + relx) % 360; 232 if ( kseq == yrot_kstate_[1] ) 233 new_yrot = round(yRotation() - relx) % 360; 234 if ( kseq == zrot_kstate_[0] ) 235 new_zrot = round(zRotation() + relx) % 360; 236 if ( kseq == zrot_kstate_[1] ) 237 new_zrot = round(zRotation() - relx) % 360; 238 239 setRotation(new_xrot, new_yrot, new_zrot); 240 } 241 242 void ExtGLWidget::setScaleKeyboard(KeyboardState kseq, double speed) 243 { 244 // Scale 245 double w = max(1,width()); 246 double h = max(1,height()); 247 248 double relx = speed / w; relx = exp(relx) - 1; 249 double relyz = speed / h; relyz = exp(relyz) - 1; 250 251 double new_xscale = xScale(); 252 double new_yscale = yScale(); 253 double new_zscale = zScale(); 254 255 if ( kseq == xscale_kstate_[0]) 256 new_xscale = max(0.0,xScale() + relx); 257 if ( kseq == xscale_kstate_[1]) 258 new_xscale = max(0.0,xScale() - relx); 259 if ( kseq == yscale_kstate_[0]) 260 new_yscale = max(0.0,yScale() - relyz); 261 if ( kseq == yscale_kstate_[1]) 262 new_yscale = max(0.0,yScale() + relyz); 263 if ( kseq == zscale_kstate_[0]) 264 new_zscale = max(0.0,zScale() - relyz); 265 if ( kseq == zscale_kstate_[1]) 266 new_zscale = max(0.0,zScale() + relyz); 267 268 setScale(new_xscale, new_yscale, new_zscale); 269 270 if ( kseq == zoom_kstate_[0]) 271 setZoom(max(0.0,zoom() - relyz)); 272 if ( kseq == zoom_kstate_[1]) 273 setZoom(max(0.0,zoom() + relyz)); 274 } 275 276 void ExtGLWidget::setShiftKeyboard(KeyboardState kseq, double speed) 277 { 278 // Shift 279 double w = max(1,width()); 280 double h = max(1,height()); 281 282 double relx = speed / w; 283 double relyz = speed / h; 284 285 double new_xshift = xViewportShift(); 286 double new_yshift = yViewportShift(); 287 288 if ( kseq == xshift_kstate_[0]) 289 new_xshift = xViewportShift() + relx; 290 if ( kseq == xshift_kstate_[1]) 291 new_xshift = xViewportShift() - relx; 292 if ( kseq == yshift_kstate_[0]) 293 new_yshift = yViewportShift() - relyz; 294 if ( kseq == yshift_kstate_[1]) 295 new_yshift = yViewportShift() + relyz; 296 297 setViewportShift(new_xshift, new_yshift); 298 } 299 300 /** 301 Sets the keybutton combination for data/coordinatesystem moves inside the widget\n\n 302 default behaviour:\n 303 304 \verbatim 305 rotate around x axis: [Key_Down, Key_Up] 306 rotate around y axis: SHIFT+[Key_Right, Key_Left] 307 rotate around z axis: [Key_Right, Key_Left] 308 scale x: ALT+[Key_Right, Key_Left] 309 scale y: ALT+[Key_Up, Key_Down] 310 scale z: ALT+SHIFT[Key_Down, Key_Up] 311 zoom: ALT+CTRL+[Key_Down, Key_Up] 312 shifting along x: CTRL+[Key_Right, Key_Left] 313 shifting along z: CTRL+[Key_Down, Key_Up] 314 \endverbatim 315 */ 316 void ExtGLWidget::assignKeyboard(KeyboardState xrot_n, KeyboardState xrot_p 317 ,KeyboardState yrot_n, KeyboardState yrot_p 318 ,KeyboardState zrot_n, KeyboardState zrot_p 319 ,KeyboardState xscale_n, KeyboardState xscale_p 320 ,KeyboardState yscale_n, KeyboardState yscale_p 321 ,KeyboardState zscale_n, KeyboardState zscale_p 322 ,KeyboardState zoom_n, KeyboardState zoom_p 323 ,KeyboardState xshift_n, KeyboardState xshift_p 324 ,KeyboardState yshift_n, KeyboardState yshift_p) 325 { 326 xrot_kstate_[0] = xrot_n; 327 yrot_kstate_[0] = yrot_n; 328 zrot_kstate_[0] = zrot_n; 329 xrot_kstate_[1] = xrot_p; 330 yrot_kstate_[1] = yrot_p; 331 zrot_kstate_[1] = zrot_p; 332 333 xscale_kstate_[0] = xscale_n; 334 yscale_kstate_[0] = yscale_n; 335 zscale_kstate_[0] = zscale_n; 336 xscale_kstate_[1] = xscale_p; 337 yscale_kstate_[1] = yscale_p; 338 zscale_kstate_[1] = zscale_p; 339 340 zoom_kstate_[0] = zoom_n; 341 xshift_kstate_[0] = xshift_n; 342 yshift_kstate_[0] = yshift_n; 343 zoom_kstate_[1] = zoom_p; 344 xshift_kstate_[1] = xshift_p; 345 yshift_kstate_[1] = yshift_p; 346 } 347 348 /** 349 The function has no effect if you derive from ExtGLWidget and overrides the keyboard Functions too careless. 350 In this case check first against keyboardEnabled() in your version of keyPressEvent() 351 A more fine grained input control can be achieved by combining assignKeyboard() with enableKeyboard(). 352 */ 353 void ExtGLWidget::enableKeyboard(bool val) {kbd_input_enabled_ = val;} 354 355 /** 356 \see enableKeyboard() 357 */ 358 void ExtGLWidget::disableKeyboard(bool val) {kbd_input_enabled_ = !val;} 359 bool ExtGLWidget::keyboardEnabled() const {return kbd_input_enabled_;} 360 361 /** 362 Values < 0 are ignored. Default is (3,5,5) 363 */ 364 void ExtGLWidget::setKeySpeed(double rot, double scale, double shift) 365 { 366 if (rot > 0) kbd_rot_speed_ = rot; 367 if (scale > 0) kbd_scale_speed_ = scale; 368 if (shift > 0) kbd_shift_speed_ = shift; 369 } 370 371 void ExtGLWidget::keySpeed(double& rot, double& scale, double& shift) const 372 { 373 rot = kbd_rot_speed_; 374 scale = kbd_scale_speed_; 375 shift = kbd_shift_speed_; 376 } 377