00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "QtWheel.hh"
00054
00055 #include <math.h>
00056 #include <float.h>
00057 #include <iostream>
00058 #include <algorithm>
00059
00060
00061
00062 #include <QEvent>
00063 #include <QPainter>
00064 #include <QMenu>
00065 #include <QPixmap>
00066 #include <QTimer>
00067 #include <QCursor>
00068 #include <QBrush>
00069 #include <QPaintEvent>
00070 #include <QKeyEvent>
00071 #include <QResizeEvent>
00072 #include <QMouseEvent>
00073
00074
00075
00076
00077
00078 namespace ACG {
00079 namespace QtWidgets {
00080
00081
00082
00083
00084
00085 QtWheel::QtWheel(QWidget* _parent,
00086 const char* ,
00087 Orientation _orientation)
00088 : QFrame(_parent)
00089 {
00090 angle_ = 0.0;
00091 lastAngle_ = 0.0;
00092 gear_ = 1.0;
00093 gearShift_ = 0;
00094
00095
00096 ticks_ = 36;
00097 marker_ = false;
00098 orientation_ = _orientation;
00099 dragging_ = false;
00100 tracking_ = true;
00101
00102 palette_ = palette();
00103 palette_.setColor( QPalette::Dark, QColor(0,0,0));
00104
00105 setFrameStyle( QtWheel::Panel | QtWheel::Raised );
00106 setLineWidth(2);
00107
00108 setContextMenuPolicy ( Qt::CustomContextMenu );
00109
00110 connect (this, SIGNAL (customContextMenuRequested ( const QPoint & ) ),
00111 this, SLOT( slotCustomContextMenuRequested ( const QPoint & ) ));
00112
00113 }
00114
00115 QtWheel::~QtWheel() {
00116 }
00117
00118
00119
00120 void QtWheel::mousePressEvent(QMouseEvent* _e)
00121 {
00122 if (_e->button()==Qt::LeftButton) {
00123 pos_=_e->pos();
00124 dragging_=true;
00125 lastAngle_=angle_;
00126 }
00127 }
00128
00129 void QtWheel::mouseReleaseEvent(QMouseEvent* _e)
00130 {
00131 if (_e->button()==Qt::LeftButton)
00132 {
00133 dragging_=false;
00134
00135
00136
00137
00138 }
00139 }
00140
00141
00142 void QtWheel::mouseMoveEvent(QMouseEvent* _e)
00143 {
00144 if (_e->buttons()&Qt::LeftButton)
00145 {
00146 float dAngle=turn(_e->pos());
00147
00148 if (tracking_ && dAngle!=0.0) {
00149 lastAngle_=angle_-dAngle;
00150
00151 emit angleChangedTo(angle_);
00152 emit angleChangedBy(dAngle);
00153 }
00154 }
00155 }
00156
00157
00158 double QtWheel::turn(const QPoint& _pos)
00159 {
00160 QPoint dPos=(_pos-pos_);
00161 pos_=_pos;
00162
00163 int d = orientation_== Horizontal ? dPos.x() : dPos.y();
00164
00165 double dAngle=0.0;
00166
00167 if (d!=0) {
00168
00169 dAngle=double(d)/double(size_)*M_PI*gear_;
00170 angle_+=dAngle;
00171
00172 redrawPixmap();
00173 repaint();
00174 }
00175 return dAngle;
00176 }
00177
00178
00179
00180 void QtWheel::mouseDoubleClickEvent(QMouseEvent* _e) {
00181 if (_e->button()==Qt::LeftButton) {
00182 int sz,x;
00183 if (orientation_== Horizontal) {
00184 sz=width(); x=_e->x();
00185 }
00186 else {
00187 sz=height(); x=_e->y();
00188 }
00189
00190 if (x<sz/2) {
00191 if (gearShift_<8) {
00192 ++gearShift_;
00193 gear_*=2.0;
00194
00195 redrawPixmap();
00196 repaint();
00197
00198 emit gearUp();
00199 }
00200 }
00201 else {
00202 if (gearShift_>-8) {
00203 --gearShift_;
00204 gear_/=2.0;
00205
00206 redrawPixmap();
00207 repaint();
00208
00209 emit gearDown();
00210 }
00211 }
00212 }
00213 }
00214
00215
00216
00217 void QtWheel::keyPressEvent(QKeyEvent* _e) {
00218
00219
00220
00221
00222
00223 if (dragging_)
00224 return;
00225
00226 double dAngle=0.0;
00227
00228 if (!_e->isAutoRepeat())
00229 lastAngle_=angle_;
00230
00231 switch (_e->key()) {
00232 case Qt::Key_Left:
00233 case Qt::Key_Up: {
00234 dAngle= -M_PI/double(ticks_)*gear_;
00235 }
00236 break;
00237
00238 case Qt::Key_Right:
00239 case Qt::Key_Down: {
00240 dAngle= +M_PI/double(ticks_)*gear_;
00241 }
00242 break;
00243
00244 default: return;
00245 }
00246
00247 if (tracking_)
00248 lastAngle_=angle_;
00249
00250 angle_+=dAngle;
00251
00252 redrawPixmap();
00253 repaint();
00254
00255 if (tracking_) {
00256 emit angleChangedTo(angle_);
00257 emit angleChangedBy(angle_-lastAngle_);
00258 }
00259 }
00260
00261 void QtWheel::keyReleaseEvent(QKeyEvent* _e) {
00262 switch (_e->key()) {
00263 case Qt::Key_Left:
00264 case Qt::Key_Up:
00265 case Qt::Key_Right:
00266 case Qt::Key_Down: {
00267 if (!tracking_) {
00268 emit angleChangedTo(angle_);
00269 emit angleChangedBy(angle_-lastAngle_);
00270 }
00271 };
00272 break;
00273
00274 default: return;
00275 }
00276 }
00277
00278
00279
00280 void QtWheel::resizeEvent(QResizeEvent* _e) {
00281 QFrame::resizeEvent(_e);
00282 redrawPixmap();
00283 }
00284
00285 void QtWheel::paintEvent(QPaintEvent* _e) {
00286 if (isVisible()) {
00287 QFrame::paintEvent(_e);
00288
00289
00290 QPainter painter(this);
00291 QRect r=contentsRect();
00292
00294 painter.drawPixmap( r.left(), r.top(), pixmap_ );
00295
00296 }
00297 }
00298
00299
00300
00301 void QtWheel::redrawPixmap() {
00302 QRect r=contentsRect();
00303
00304 if (r.width()<=0 || r.height()<=0) {
00305 pixmap_ = QPixmap( 0, 0 );
00306 return;
00307 }
00308
00309 if (pixmap_.size()!=r.size())
00310 pixmap_ = QPixmap(r.size());
00311
00312 QPainter paint;
00313
00314 paint.begin( &pixmap_);
00315 pixmap_.fill( palette().background().color() );
00316
00317
00318 QRect contents = contentsRect();
00319 contents.moveTopLeft(QPoint(0,0));
00320
00321 QPen pen(Qt::black, 1);
00322 paint.setPen(pen);
00323
00324 if (orientation_ == Horizontal) {
00325
00326 shrinkRect(contents, 3, 2);
00327
00328
00329 paint.drawRect(contents);
00330 shrinkRect(contents, 1, 0);
00331 paint.drawRect(contents);
00332 shrinkRect(contents, 3, 2);
00333
00334 int x0 = contents.left();
00335 int y0 = contents.top();
00336 int w0 = contents.width();
00337 int h0 = contents.height();
00338
00339 size_=w0;
00340
00341 if (gearShift_>0) {
00342 QBrush b; b.setColor(QColor(Qt::red)); b.setStyle(Qt::SolidPattern);
00343 int w=std::min(4*gearShift_,w0-8);
00344 paint.fillRect(x0+8,y0-1,w,h0+2,b);
00345 }
00346 else if (gearShift_<0) {
00347 QBrush b; b.setColor(QColor(Qt::blue));
00348 int w=std::min(-4*gearShift_,w0-8); b.setStyle(Qt::SolidPattern);
00349 paint.fillRect(x0+w0-w-8,y0-1,w,h0+2,b);
00350 }
00351
00352
00353 double step = 2 * M_PI / (double) ticks_;
00354 for (int i = 0; i < ticks_; i++) {
00355 double x = sin(angle_ + i * step);
00356 double y = cos(angle_ + i * step);
00357 if (y>0) {
00358 qDrawShadeLine( &paint,
00359 (int) (x0+(w0+x*w0)/2.0f), y0,
00360 (int) (x0+(w0+x*w0)/2.0f), y0+h0,
00361 palette_, false, 1, 1);
00362 }
00363 }
00364 }
00365
00366 else if (orientation_ == Vertical) {
00367
00368 shrinkRect(contents, 2, 3);
00369
00370
00371 paint.drawRect(contents);
00372 shrinkRect(contents, 0, 1);
00373 paint.drawRect(contents);
00374 shrinkRect(contents, 2, 3);
00375
00376
00377 int x0 = contents.left();
00378 int y0 = contents.top();
00379 int w0 = contents.width();
00380 int h0 = contents.height();
00381
00382 size_=h0;
00383
00384 if (gearShift_>0) {
00385 QBrush b; b.setColor(QColor(Qt::red)); b.setStyle(Qt::SolidPattern);
00386 int h=-std::min(-4*gearShift_,h0-8);
00387 paint.fillRect(x0-1,y0+8,w0+2,h,b);
00388 }
00389 else if (gearShift_<0) {
00390 QBrush b; b.setColor(QColor(Qt::blue)); b.setStyle(Qt::SolidPattern);
00391 int h=-std::min(4*gearShift_,h0-8);
00392 paint.fillRect(x0-1,y0+h0-h-8,w0+2,h,b);
00393 }
00394
00395
00396 double step = 2 * M_PI / (double) ticks_;
00397 for (int i = 0; i < ticks_; i++) {
00398 double x = sin(angle_ + i * step);
00399 double y = cos(angle_ + i * step);
00400 if (y>0) {
00401 qDrawShadeLine( &paint,
00402 x0, (int) (y0+(h0+x*h0)/2.0f),
00403 x0+w0, (int) (y0+(h0+x*h0)/2.0f),
00404 palette_, false, 1, 1);
00405 }
00406 }
00407 }
00408 paint.end();
00409 }
00410
00411
00412
00413 void QtWheel::shrinkRect(QRect& _rect, int _dx, int _dy) {
00414 _rect.setLeft(_rect.left()+_dx);
00415 _rect.setRight(_rect.right()-_dx);
00416 _rect.setTop(_rect.top()+_dy);
00417 _rect.setBottom(_rect.bottom()-_dy);
00418 }
00419
00420
00421
00422 QSizePolicy QtWheel::sizePolicy() const
00423 {
00424 if (orientation_== Horizontal)
00425 return QSizePolicy(QSizePolicy::Preferred,
00426 QSizePolicy::Minimum);
00427 else
00428 return QSizePolicy(QSizePolicy::Minimum,
00429 QSizePolicy::Preferred);
00430 }
00431
00432
00433
00434 QSize QtWheel::sizeHint() const
00435 {
00436 if (orientation_==Horizontal)
00437 return QSize(120,20);
00438 else
00439 return QSize(20,120);
00440 }
00441
00442
00443
00444
00445 double QtWheel::clip(double _angle) {
00446 return fmod(_angle,2*M_PI);
00447 }
00448
00449 double QtWheel::deg(double _angle) {
00450 return _angle*180.0/M_PI;
00451 }
00452
00453
00454
00455 void QtWheel::slotCustomContextMenuRequested ( const QPoint & pos ) {
00456
00457 QMenu* menu = new QMenu(this);
00458 QAction *hide = menu->addAction("Hide wheel");
00459 connect( hide, SIGNAL(triggered()) , this, SIGNAL(hideWheel()) );
00460 menu->popup( mapToGlobal(pos) );
00461
00462 }
00463
00464
00465
00466 }
00467 }
00468