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