Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QtWheel.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Author$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51
52 //=============================================================================
53 //
54 // CLASS QtWheel - IMPLEMENTATION
55 //
56 //=============================================================================
57
58 //== INCLUDES =================================================================
59
60 #include "QtWheel.hh"
61
62 #include <cmath>
63 #include <iostream>
64
65 //#include <QDrawutil>
66
67 #include <QPainter>
68 #include <QMenu>
69 #include <QTimer>
70 #include <qdrawutil.h>
71
72
73 //== NAMESPACES ===============================================================
74
75
76 namespace ACG {
77 namespace QtWidgets {
78
79
80 //== IMPLEMENTATION ==========================================================
81
82
83 QtWheel::QtWheel(QWidget* _parent,
84 const char* /* _name */ ,
85 Orientation _orientation)
86 : QFrame(_parent)
87 {
88 angle_ = 0.0;
89 lastAngle_ = 0.0;
90 gear_ = 1.0;
91 gearShift_ = 0;
92 // size_ will be set by redrawPixmap()
93
94 ticks_ = 36;
95 marker_ = false;
96 orientation_ = _orientation;
97 dragging_ = false;
98 tracking_ = true;
99
100 palette_ = palette();
101 palette_.setColor( QPalette::Dark, QColor(0,0,0));
102
103 setFrameStyle( QtWheel::Panel | QtWheel::Raised );
104 setLineWidth(2);
105
106 setContextMenuPolicy ( Qt::CustomContextMenu );
107
108 connect (this, SIGNAL (customContextMenuRequested ( const QPoint & ) ),
109 this, SLOT( slotCustomContextMenuRequested ( const QPoint & ) ));
110
111 }
112
113 QtWheel::~QtWheel() {
114 }
115
116 //----------------------------------------------------------------------------
117
118 void QtWheel::mousePressEvent(QMouseEvent* _e)
119 {
120 if (_e->button()==Qt::LeftButton) {
121 pos_=_e->pos();
122 dragging_=true;
123 lastAngle_=angle_;
124 }
125 }
126
127 void QtWheel::mouseReleaseEvent(QMouseEvent* _e)
128 {
129 if (_e->button()==Qt::LeftButton)
130 {
131 dragging_=false;
132
133 // turn(_e->pos());
134 // emit angleChangedTo(angle_);
135 // emit angleChangedBy(angle_-lastAngle_);
136 }
137 }
138
139
140 void QtWheel::mouseMoveEvent(QMouseEvent* _e)
141 {
142 if (_e->buttons()&Qt::LeftButton)
143 {
144 float dAngle=turn(_e->pos());
145
146 if (tracking_ && dAngle!=0.0) { // 0.0 is explicitly returned
147 lastAngle_=angle_-dAngle;
148
149 emit angleChangedTo(angle_);
150 emit angleChangedBy(dAngle);
151 }
152 }
153 }
154
155
156 double QtWheel::turn(const QPoint& _pos)
157 {
158 QPoint dPos=(_pos-pos_);
159 pos_=_pos;
160
161 int d = orientation_== Horizontal ? dPos.x() : dPos.y();
162
163 double dAngle=0.0;
164
165 if (d!=0) {
166 // full width/height = 180 deg for gear()==1
167 dAngle=double(d)/double(size_)*M_PI*gear_;
168 angle_+=dAngle;
169
170 redrawPixmap();
171 repaint();
172 }
173 return dAngle;
174 }
175
176 //----------------------------------------------------------------------------
177
178 void QtWheel::mouseDoubleClickEvent(QMouseEvent* _e) {
179 if (_e->button()==Qt::LeftButton) {
180 int sz,x;
181 if (orientation_== Horizontal) {
182 sz=width(); x=_e->x();
183 }
184 else {
185 sz=height(); x=_e->y();
186 }
187
188 if (x<sz/2) {
189 if (gearShift_<8) {
190 ++gearShift_;
191 gear_*=2.0;
192
193 redrawPixmap();
194 repaint();
195
196 emit gearUp();
197 }
198 }
199 else {
200 if (gearShift_>-8) {
201 --gearShift_;
202 gear_/=2.0;
203
204 redrawPixmap();
205 repaint();
206
207 emit gearDown();
208 }
209 }
210 }
211 }
212
213 //----------------------------------------------------------------------------
214
215 void QtWheel::keyPressEvent(QKeyEvent* _e) {
216
217 //
218 // This does not work! Do we really need/want keyboard input???
219 //
220
221 if (dragging_)
222 return;
223
224 double dAngle=0.0;
225
226 if (!_e->isAutoRepeat())
227 lastAngle_=angle_;
228
229 switch (_e->key()) {
230 case Qt::Key_Left:
231 case Qt::Key_Up: {
232 dAngle= -M_PI/double(ticks_)*gear_;
233 }
234 break;
235
236 case Qt::Key_Right:
237 case Qt::Key_Down: {
238 dAngle= +M_PI/double(ticks_)*gear_;
239 }
240 break;
241
242 default: return;
243 }
244
245 if (tracking_)
246 lastAngle_=angle_;
247
248 angle_+=dAngle;
249
250 redrawPixmap();
251 repaint();
252
253 if (tracking_) {
254 emit angleChangedTo(angle_);
255 emit angleChangedBy(angle_-lastAngle_);
256 }
257 }
258
259 void QtWheel::keyReleaseEvent(QKeyEvent* _e) {
260 switch (_e->key()) {
261 case Qt::Key_Left:
262 case Qt::Key_Up:
263 case Qt::Key_Right:
264 case Qt::Key_Down: {
265 if (!tracking_) {
266 emit angleChangedTo(angle_);
267 emit angleChangedBy(angle_-lastAngle_);
268 }
269 };
270 break;
271
272 default: return;
273 }
274 }
275
276 //----------------------------------------------------------------------------
277
278 void QtWheel::resizeEvent(QResizeEvent* _e) {
279 QFrame::resizeEvent(_e);
280 redrawPixmap();
281 }
282
283 void QtWheel::paintEvent(QPaintEvent* _e) {
284 if (isVisible()) {
285 QFrame::paintEvent(_e);
286
287
288 QPainter painter(this);
289 QRect r=contentsRect();
290
292 painter.drawPixmap( r.left(), r.top(), pixmap_ );
293
294 }
295 }
296
297 //----------------------------------------------------------------------------
298
299 void QtWheel::redrawPixmap() {
300 QRect r=contentsRect();
301
302 if (r.width()<=0 || r.height()<=0) {
303 pixmap_ = QPixmap( 0, 0 );
304 return;
305 }
306
307 if (pixmap_.size()!=r.size())
308 pixmap_ = QPixmap(r.size());
309
310 QPainter paint;
311
312 paint.begin( &pixmap_);
313 pixmap_.fill( palette().background().color() );
314
315 // coords of wheel frame
316 QRect contents = contentsRect();
317 contents.moveTopLeft(QPoint(0,0)); // transform to pixmap coord sys
318
319 QPen pen(Qt::black, 1);
320 paint.setPen(pen);
321
322 if (orientation_ == Horizontal) {
323
324 shrinkRect(contents, 3, 2);
325
326 // draw a black frame
327 paint.drawRect(contents);
328 shrinkRect(contents, 1, 0);
329 paint.drawRect(contents);
330 shrinkRect(contents, 3, 2);
331
332 int x0 = contents.left();
333 int y0 = contents.top();
334 int w0 = contents.width();
335 int h0 = contents.height();
336
337 size_=w0;
338
339 if (gearShift_>0) {
340 QBrush b; b.setColor(QColor(Qt::red)); b.setStyle(Qt::SolidPattern);
341 int w=std::min(4*gearShift_,w0-8);
342 paint.fillRect(x0+8,y0-1,w,h0+2,b);
343 }
344 else if (gearShift_<0) {
345 QBrush b; b.setColor(QColor(Qt::blue));
346 int w=std::min(-4*gearShift_,w0-8); b.setStyle(Qt::SolidPattern);
347 paint.fillRect(x0+w0-w-8,y0-1,w,h0+2,b);
348 }
349
350 // draw the wheel
351 double step = 2 * M_PI / (double) ticks_;
352 for (int i = 0; i < ticks_; i++) {
353 double x = sin(angle_ + i * step);
354 double y = cos(angle_ + i * step);
355 if (y>0) {
356 qDrawShadeLine( &paint,
357 (int) (x0+(w0+x*w0)/2.0f), y0,
358 (int) (x0+(w0+x*w0)/2.0f), y0+h0,
359 palette_, false, 1, 1);
360 }
361 }
362 }
363
364 else if (orientation_ == Vertical) {
365
366 shrinkRect(contents, 2, 3);
367
368 // draw a black frame
369 paint.drawRect(contents);
370 shrinkRect(contents, 0, 1);
371 paint.drawRect(contents);
372 shrinkRect(contents, 2, 3);
373
374
375 int x0 = contents.left();
376 int y0 = contents.top();
377 int w0 = contents.width();
378 int h0 = contents.height();
379
380 size_=h0;
381
382 if (gearShift_>0) {
383 QBrush b; b.setColor(QColor(Qt::red)); b.setStyle(Qt::SolidPattern);
384 int h=-std::min(-4*gearShift_,h0-8);
385 paint.fillRect(x0-1,y0+8,w0+2,h,b);
386 }
387 else if (gearShift_<0) {
388 QBrush b; b.setColor(QColor(Qt::blue)); b.setStyle(Qt::SolidPattern);
389 int h=-std::min(4*gearShift_,h0-8);
390 paint.fillRect(x0-1,y0+h0-h-8,w0+2,h,b);
391 }
392
393 // draw the wheel
394 double step = 2 * M_PI / (double) ticks_;
395 for (int i = 0; i < ticks_; i++) {
396 double x = sin(angle_ + i * step);
397 double y = cos(angle_ + i * step);
398 if (y>0) {
399 qDrawShadeLine( &paint,
400 x0, (int) (y0+(h0+x*h0)/2.0f),
401 x0+w0, (int) (y0+(h0+x*h0)/2.0f),
402 palette_, false, 1, 1);
403 } // if y
404 } // for ticks_
405 } // if Vertical
406 paint.end();
407 }
408
409 //-----------------------------------------------------------------------------
410
411 void QtWheel::shrinkRect(QRect& _rect, int _dx, int _dy) {
412 _rect.setLeft(_rect.left()+_dx);
413 _rect.setRight(_rect.right()-_dx);
414 _rect.setTop(_rect.top()+_dy); // dy -> -dy
415 _rect.setBottom(_rect.bottom()-_dy);
416 }
417
418 //-----------------------------------------------------------------------------
419
420 QSizePolicy QtWheel::sizePolicy() const
421 {
422 if (orientation_== Horizontal)
423 return QSizePolicy(QSizePolicy::Preferred,
424 QSizePolicy::Minimum);
425 else
426 return QSizePolicy(QSizePolicy::Minimum,
427 QSizePolicy::Preferred);
428 }
429
430 //-----------------------------------------------------------------------------
431
432 QSize QtWheel::sizeHint() const
433 {
434 if (orientation_==Horizontal)
435 return QSize(120,20);
436 else
437 return QSize(20,120);
438 }
439
440 //-----------------------------------------------------------------------------
441
442
443 double QtWheel::clip(double _angle) {
444 return fmod(_angle,2*M_PI);
445 }
446
447 double QtWheel::deg(double _angle) {
448 return _angle*180.0/M_PI;
449 }
450
451 //-----------------------------------------------------------------------------
452
453 void QtWheel::slotCustomContextMenuRequested ( const QPoint & pos ) {
454
455 QMenu* menu = new QMenu(this);
456 QAction *hide = menu->addAction("Hide wheel");
457 connect( hide, SIGNAL(triggered()) , this, SIGNAL(hideWheel()) );
458 menu->popup( mapToGlobal(pos) );
459
460 }
461
462
463 //=============================================================================
464 } // namespace QtWidgets
465 } // namespace ACG
466 //=============================================================================
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::QtWidgets::QtWheel::angle_
double angle_
current angle of the wheel
Definition: QtWheel.hh:276
ACG::QtWidgets::QtWheel::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *)
reimplemented
Definition: QtWheel.cc:127
ACG::QtWidgets::QtWheel::pixmap_
QPixmap pixmap_
pixmap of the wheel
Definition: QtWheel.hh:293
ACG::QtWidgets::QtWheel::ticks_
int ticks_
number of ticks on the wheel
Definition: QtWheel.hh:285
ACG::QtWidgets::QtWheel::sizeHint
virtual QSize sizeHint() const
reimplemented
Definition: QtWheel.cc:432
ACG::QtWidgets::QtWheel::gearShift_
int gearShift_
click-shifted gear by 2^gearShift_
Definition: QtWheel.hh:281
ACG::QtWidgets::QtWheel::mouseDoubleClickEvent
virtual void mouseDoubleClickEvent(QMouseEvent *)
reimplemented
Definition: QtWheel.cc:178
ACG::QtWidgets::QtWheel::gearDown
void gearDown()
Like gearUp() but the value of gear() halves.
ACG::QtWidgets::QtWheel::keyPressEvent
virtual void keyPressEvent(QKeyEvent *)
reimplemented
Definition: QtWheel.cc:215
ACG::QtWidgets::QtWheel::resizeEvent
virtual void resizeEvent(QResizeEvent *)
reimplemented
Definition: QtWheel.cc:278
ACG::QtWidgets::QtWheel::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *)
reimplemented
Definition: QtWheel.cc:140
ACG::QtWidgets::QtWheel::gear_
double gear_
speed of revolution
Definition: QtWheel.hh:280
ACG::QtWidgets::QtWheel::~QtWheel
virtual ~QtWheel()
Destructor.
Definition: QtWheel.cc:113
ACG::QtWidgets::QtWheel::angleChangedBy
void angleChangedBy(double _angle)
ACG::QtWidgets::QtWheel::size_
int size_
size of wheel in pixels
Definition: QtWheel.hh:278
ACG::QtWidgets::QtWheel::keyReleaseEvent
virtual void keyReleaseEvent(QKeyEvent *)
reimplemented
Definition: QtWheel.cc:259
ACG::QtWidgets::QtWheel::gearUp
void gearUp()
ACG::QtWidgets::QtWheel::dragging_
bool dragging_
currently dragging the slider?
Definition: QtWheel.hh:289
ACG::QtWidgets::QtWheel::palette_
QPalette palette_
color group
Definition: QtWheel.hh:292
ACG::QtWidgets::QtWheel::orientation_
Orientation orientation_
orientation of the widget
Definition: QtWheel.hh:283
ACG::QtWidgets::QtWheel::paintEvent
virtual void paintEvent(QPaintEvent *)
reimplemented
Definition: QtWheel.cc:283
ACG::QtWidgets::QtWheel::marker_
bool marker_
should ticks be marked by colors?
Definition: QtWheel.hh:286
ACG::QtWidgets::QtWheel::angleChangedTo
void angleChangedTo(double _angle)
ACG::QtWidgets::QtWheel::redrawPixmap
virtual void redrawPixmap()
draw wheel to pixmap (double buffering)
Definition: QtWheel.cc:299
ACG::QtWidgets::QtWheel::deg
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
Definition: QtWheel.cc:447
ACG::QtWidgets::QtWheel::QtWheel
QtWheel(QWidget *_parent=0, const char *_name=0, Orientation _orientation=Horizontal)
Constructor.
Definition: QtWheel.cc:83
ACG::QtWidgets::QtWheel::tracking_
bool tracking_
tracking on?
Definition: QtWheel.hh:290
ACG::QtWidgets::QtWheel::pos_
QPoint pos_
recent mouse position
Definition: QtWheel.hh:288
ACG::QtWidgets::QtWheel::lastAngle_
double lastAngle_
last angle, depends on tracking_
Definition: QtWheel.hh:277
ACG::QtWidgets::QtWheel::shrinkRect
void shrinkRect(QRect &, int, int)
expands a rectangle in x/y direction
Definition: QtWheel.cc:411
ACG::QtWidgets::QtWheel::sizePolicy
virtual QSizePolicy sizePolicy() const
reimplemented
Definition: QtWheel.cc:420
ACG::QtWidgets::QtWheel::mousePressEvent
virtual void mousePressEvent(QMouseEvent *)
reimplemented
Definition: QtWheel.cc:118
ACG::QtWidgets::QtWheel::hideWheel
void hideWheel()
Emitted when the wheel will be hidden by the context menu.
ACG::QtWidgets::QtWheel::clip
static double clip(double _angle)
Definition: QtWheel.cc:443
ACG::QtWidgets::QtWheel::Orientation
Orientation
Orientation of the widget.
Definition: QtWheel.hh:113