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