annotate widgets/Thumbwheel.cpp @ 1588:0f36e0eca6b0

Add right-button context menu to panner widget
author Chris Cannam
date Mon, 30 Mar 2020 11:29:16 +0100
parents bbc3f537564c
children 27ea5d61b402
rev   line source
Chris@132 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@132 2
Chris@132 3 /*
Chris@132 4 Sonic Visualiser
Chris@132 5 An audio file viewer and annotation editor.
Chris@132 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 QMUL.
Chris@132 8
Chris@132 9 This program is free software; you can redistribute it and/or
Chris@132 10 modify it under the terms of the GNU General Public License as
Chris@132 11 published by the Free Software Foundation; either version 2 of the
Chris@132 12 License, or (at your option) any later version. See the file
Chris@132 13 COPYING included with this distribution for more information.
Chris@132 14 */
Chris@132 15
Chris@132 16 #include "Thumbwheel.h"
Chris@132 17
Chris@187 18 #include "base/RangeMapper.h"
Chris@190 19 #include "base/Profiler.h"
Chris@187 20
Chris@132 21 #include <QMouseEvent>
Chris@132 22 #include <QPaintEvent>
Chris@132 23 #include <QWheelEvent>
Chris@187 24 #include <QInputDialog>
Chris@132 25 #include <QPainter>
Chris@190 26 #include <QPainterPath>
Chris@1586 27 #include <QMenu>
Chris@1586 28
Chris@1586 29 #include "MenuTitle.h"
Chris@132 30
Chris@132 31 #include <cmath>
Chris@132 32 #include <iostream>
Chris@132 33
Chris@133 34 Thumbwheel::Thumbwheel(Qt::Orientation orientation,
Chris@1266 35 QWidget *parent) :
Chris@132 36 QWidget(parent),
Chris@133 37 m_min(0),
Chris@133 38 m_max(100),
Chris@133 39 m_default(50),
Chris@133 40 m_value(50),
Chris@187 41 m_mappedValue(50),
Chris@187 42 m_noMappedUpdate(false),
Chris@165 43 m_rotation(0.5),
Chris@132 44 m_orientation(orientation),
Chris@165 45 m_speed(1.0),
Chris@132 46 m_tracking(true),
Chris@132 47 m_showScale(true),
Chris@132 48 m_clicked(false),
Chris@133 49 m_atDefault(true),
Chris@187 50 m_clickRotation(m_rotation),
Chris@187 51 m_showTooltip(true),
Chris@1586 52 m_provideContextMenu(true),
Chris@1586 53 m_lastContextMenu(nullptr),
Chris@1408 54 m_rangeMapper(nullptr)
Chris@132 55 {
Chris@1586 56 setContextMenuPolicy(Qt::CustomContextMenu);
Chris@1586 57 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
Chris@1586 58 this, SLOT(contextMenuRequested(const QPoint &)));
Chris@132 59 }
Chris@132 60
Chris@132 61 Thumbwheel::~Thumbwheel()
Chris@132 62 {
Chris@187 63 delete m_rangeMapper;
Chris@1586 64 delete m_lastContextMenu;
Chris@1586 65 }
Chris@1586 66
Chris@1586 67 void
Chris@1586 68 Thumbwheel::contextMenuRequested(const QPoint &pos)
Chris@1586 69 {
Chris@1586 70 if (!m_provideContextMenu) {
Chris@1586 71 return;
Chris@1586 72 }
Chris@1586 73
Chris@1586 74 if (m_lastContextMenu) {
Chris@1586 75 delete m_lastContextMenu;
Chris@1586 76 }
Chris@1586 77
Chris@1586 78 QMenu *m = new QMenu;
Chris@1586 79
Chris@1586 80 if (m_title == "") {
Chris@1586 81 MenuTitle::addTitle(m, tr("Thumbwheel"));
Chris@1586 82 } else {
Chris@1586 83 MenuTitle::addTitle(m, m_title);
Chris@1586 84 }
Chris@1586 85
Chris@1586 86 m->addAction(tr("&Edit..."),
Chris@1586 87 [=]() {
Chris@1586 88 edit();
Chris@1586 89 });
Chris@1586 90 m->addAction(tr("&Reset to Default"),
Chris@1586 91 [=]() {
Chris@1586 92 resetToDefault();
Chris@1586 93 });
Chris@1586 94
Chris@1586 95 m->popup(mapToGlobal(pos));
Chris@1586 96 m_lastContextMenu = m;
Chris@187 97 }
Chris@187 98
Chris@187 99 void
Chris@187 100 Thumbwheel::setRangeMapper(RangeMapper *mapper)
Chris@187 101 {
Chris@187 102 if (m_rangeMapper == mapper) return;
Chris@187 103
Chris@187 104 if (!m_rangeMapper && mapper) {
Chris@187 105 connect(this, SIGNAL(valueChanged(int)),
Chris@187 106 this, SLOT(updateMappedValue(int)));
Chris@187 107 }
Chris@187 108
Chris@187 109 delete m_rangeMapper;
Chris@187 110 m_rangeMapper = mapper;
Chris@187 111
Chris@187 112 updateMappedValue(getValue());
Chris@187 113 }
Chris@187 114
Chris@187 115 void
Chris@187 116 Thumbwheel::setShowToolTip(bool show)
Chris@187 117 {
Chris@187 118 m_showTooltip = show;
Chris@187 119 m_noMappedUpdate = true;
Chris@187 120 updateMappedValue(getValue());
Chris@187 121 m_noMappedUpdate = false;
Chris@132 122 }
Chris@132 123
Chris@132 124 void
Chris@133 125 Thumbwheel::setMinimumValue(int min)
Chris@133 126 {
Chris@133 127 if (m_min == min) return;
Chris@133 128
Chris@133 129 m_min = min;
Chris@133 130 if (m_max <= m_min) m_max = m_min + 1;
Chris@133 131 if (m_value < m_min) m_value = m_min;
Chris@133 132 if (m_value > m_max) m_value = m_max;
Chris@165 133
Chris@165 134 m_rotation = float(m_value - m_min) / float(m_max - m_min);
Chris@165 135 update();
Chris@133 136 }
Chris@133 137
Chris@133 138 int
Chris@133 139 Thumbwheel::getMinimumValue() const
Chris@133 140 {
Chris@133 141 return m_min;
Chris@133 142 }
Chris@133 143
Chris@133 144 void
Chris@133 145 Thumbwheel::setMaximumValue(int max)
Chris@133 146 {
Chris@133 147 if (m_max == max) return;
Chris@133 148
Chris@133 149 m_max = max;
Chris@133 150 if (m_min >= m_max) m_min = m_max - 1;
Chris@133 151 if (m_value < m_min) m_value = m_min;
Chris@133 152 if (m_value > m_max) m_value = m_max;
Chris@165 153
Chris@165 154 m_rotation = float(m_value - m_min) / float(m_max - m_min);
Chris@165 155 update();
Chris@133 156 }
Chris@133 157
Chris@133 158 int
Chris@133 159 Thumbwheel::getMaximumValue() const
Chris@133 160 {
Chris@133 161 return m_max;
Chris@133 162 }
Chris@133 163
Chris@133 164 void
Chris@133 165 Thumbwheel::setDefaultValue(int deft)
Chris@133 166 {
Chris@133 167 if (m_default == deft) return;
Chris@133 168
Chris@133 169 m_default = deft;
Chris@133 170 if (m_atDefault) {
Chris@133 171 setValue(m_default);
Chris@165 172 m_atDefault = true; // setValue unsets this
Chris@382 173 m_cache = QImage();
Chris@133 174 emit valueChanged(getValue());
Chris@133 175 }
Chris@133 176 }
Chris@133 177
Chris@187 178 void
Chris@908 179 Thumbwheel::setMappedValue(double mappedValue)
Chris@187 180 {
Chris@187 181 if (m_rangeMapper) {
Chris@187 182 int newValue = m_rangeMapper->getPositionForValue(mappedValue);
Chris@190 183 bool changed = (m_mappedValue != mappedValue);
Chris@187 184 m_mappedValue = mappedValue;
Chris@187 185 m_noMappedUpdate = true;
Chris@587 186 // SVDEBUG << "Thumbwheel::setMappedValue(" << mappedValue << "): new value is " << newValue << " (visible " << isVisible() << ")" << endl;
Chris@187 187 if (newValue != getValue()) {
Chris@187 188 setValue(newValue);
Chris@190 189 changed = true;
Chris@382 190 m_cache = QImage();
Chris@187 191 }
Chris@190 192 if (changed) emit valueChanged(newValue);
Chris@187 193 m_noMappedUpdate = false;
Chris@187 194 } else {
Chris@190 195 int v = int(mappedValue);
Chris@190 196 if (v != getValue()) {
Chris@190 197 setValue(v);
Chris@382 198 m_cache = QImage();
Chris@190 199 emit valueChanged(v);
Chris@190 200 }
Chris@187 201 }
Chris@187 202 }
Chris@187 203
Chris@133 204 int
Chris@133 205 Thumbwheel::getDefaultValue() const
Chris@133 206 {
Chris@133 207 return m_default;
Chris@133 208 }
Chris@133 209
Chris@133 210 void
Chris@132 211 Thumbwheel::setValue(int value)
Chris@132 212 {
Chris@587 213 // SVDEBUG << "Thumbwheel::setValue(" << value << ") (from " << m_value
Chris@585 214 // << ", rotation " << m_rotation << ")" << " (visible " << isVisible() << ")" << endl;
Chris@133 215
Chris@165 216 if (m_value != value) {
Chris@165 217
Chris@165 218 m_atDefault = false;
Chris@165 219
Chris@165 220 if (value < m_min) value = m_min;
Chris@165 221 if (value > m_max) value = m_max;
Chris@165 222 m_value = value;
Chris@165 223 }
Chris@165 224
Chris@165 225 m_rotation = float(m_value - m_min) / float(m_max - m_min);
Chris@382 226 m_cache = QImage();
Chris@1586 227
Chris@1586 228 if (isVisible()) {
Chris@1586 229 update();
Chris@1586 230 updateTitle();
Chris@1586 231 }
Chris@132 232 }
Chris@132 233
Chris@133 234 void
Chris@133 235 Thumbwheel::resetToDefault()
Chris@133 236 {
Chris@133 237 if (m_default == m_value) return;
Chris@133 238 setValue(m_default);
Chris@133 239 m_atDefault = true;
Chris@382 240 m_cache = QImage();
Chris@133 241 emit valueChanged(getValue());
Chris@133 242 }
Chris@133 243
Chris@132 244 int
Chris@132 245 Thumbwheel::getValue() const
Chris@132 246 {
Chris@132 247 return m_value;
Chris@132 248 }
Chris@132 249
Chris@908 250 double
Chris@187 251 Thumbwheel::getMappedValue() const
Chris@187 252 {
Chris@187 253 if (m_rangeMapper) {
Chris@587 254 // SVDEBUG << "Thumbwheel::getMappedValue(): value = " << getValue() << ", mappedValue = " << m_mappedValue << endl;
Chris@187 255 return m_mappedValue;
Chris@187 256 }
Chris@187 257 return getValue();
Chris@187 258 }
Chris@187 259
Chris@187 260 void
Chris@187 261 Thumbwheel::updateMappedValue(int value)
Chris@187 262 {
Chris@187 263 if (!m_noMappedUpdate) {
Chris@187 264 if (m_rangeMapper) {
Chris@187 265 m_mappedValue = m_rangeMapper->getValueForPosition(value);
Chris@187 266 } else {
Chris@187 267 m_mappedValue = value;
Chris@187 268 }
Chris@187 269 }
Chris@187 270
Chris@1586 271 updateTitle();
Chris@1586 272 }
Chris@1586 273
Chris@1586 274 void
Chris@1586 275 Thumbwheel::updateTitle()
Chris@1586 276 {
Chris@1586 277 QString name = objectName();
Chris@1586 278 QString unit = "";
Chris@1586 279 QString text;
Chris@1586 280 double mappedValue = getMappedValue();
Chris@1586 281
Chris@1586 282 if (m_rangeMapper) unit = m_rangeMapper->getUnit();
Chris@1586 283 if (name != "") {
Chris@1586 284 text = tr("%1: %2%3").arg(name).arg(mappedValue).arg(unit);
Chris@1586 285 } else {
Chris@1586 286 text = tr("%2%3").arg(mappedValue).arg(unit);
Chris@1586 287 }
Chris@1586 288
Chris@1586 289 m_title = text;
Chris@1586 290
Chris@187 291 if (m_showTooltip) {
Chris@187 292 setToolTip(text);
Chris@1586 293 } else {
Chris@1586 294 setToolTip("");
Chris@187 295 }
Chris@187 296 }
Chris@187 297
Chris@132 298 void
Chris@256 299 Thumbwheel::scroll(bool up)
Chris@256 300 {
Chris@908 301 int step = int(lrintf(m_speed));
Chris@256 302 if (step == 0) step = 1;
Chris@256 303
Chris@256 304 if (up) {
Chris@1266 305 setValue(m_value + step);
Chris@256 306 } else {
Chris@1266 307 setValue(m_value - step);
Chris@256 308 }
Chris@256 309
Chris@256 310 emit valueChanged(getValue());
Chris@256 311 }
Chris@256 312
Chris@256 313 void
Chris@132 314 Thumbwheel::setSpeed(float speed)
Chris@132 315 {
Chris@132 316 m_speed = speed;
Chris@132 317 }
Chris@132 318
Chris@132 319 float
Chris@132 320 Thumbwheel::getSpeed() const
Chris@132 321 {
Chris@132 322 return m_speed;
Chris@132 323 }
Chris@132 324
Chris@132 325 void
Chris@132 326 Thumbwheel::setTracking(bool tracking)
Chris@132 327 {
Chris@132 328 m_tracking = tracking;
Chris@132 329 }
Chris@132 330
Chris@132 331 bool
Chris@132 332 Thumbwheel::getTracking() const
Chris@132 333 {
Chris@132 334 return m_tracking;
Chris@132 335 }
Chris@132 336
Chris@132 337 void
Chris@132 338 Thumbwheel::setShowScale(bool showScale)
Chris@132 339 {
Chris@132 340 m_showScale = showScale;
Chris@132 341 }
Chris@132 342
Chris@132 343 bool
Chris@132 344 Thumbwheel::getShowScale() const
Chris@132 345 {
Chris@132 346 return m_showScale;
Chris@132 347 }
Chris@132 348
Chris@132 349 void
Chris@189 350 Thumbwheel::enterEvent(QEvent *)
Chris@189 351 {
Chris@189 352 emit mouseEntered();
Chris@189 353 }
Chris@189 354
Chris@189 355 void
Chris@189 356 Thumbwheel::leaveEvent(QEvent *)
Chris@189 357 {
Chris@189 358 emit mouseLeft();
Chris@189 359 }
Chris@189 360
Chris@189 361 void
Chris@132 362 Thumbwheel::mousePressEvent(QMouseEvent *e)
Chris@132 363 {
Chris@187 364 if (e->button() == Qt::MidButton ||
Chris@187 365 ((e->button() == Qt::LeftButton) &&
Chris@187 366 (e->modifiers() & Qt::ControlModifier))) {
Chris@187 367 resetToDefault();
Chris@187 368 } else if (e->button() == Qt::LeftButton) {
Chris@133 369 m_clicked = true;
Chris@133 370 m_clickPos = e->pos();
Chris@165 371 m_clickRotation = m_rotation;
Chris@133 372 }
Chris@132 373 }
Chris@132 374
Chris@132 375 void
Chris@187 376 Thumbwheel::mouseDoubleClickEvent(QMouseEvent *mouseEvent)
Chris@132 377 {
Chris@188 378 //!!! needs a common base class with AudioDial (and Panner?)
Chris@187 379
Chris@187 380 if (mouseEvent->button() != Qt::LeftButton) {
Chris@187 381 return;
Chris@187 382 }
Chris@187 383
Chris@1586 384 edit();
Chris@1586 385 }
Chris@1586 386
Chris@1586 387 void
Chris@1586 388 Thumbwheel::edit()
Chris@1586 389 {
Chris@187 390 bool ok = false;
Chris@187 391
Chris@187 392 if (m_rangeMapper) {
Chris@187 393
Chris@908 394 double min = m_rangeMapper->getValueForPosition(m_min);
Chris@908 395 double max = m_rangeMapper->getValueForPosition(m_max);
Chris@187 396
Chris@187 397 if (min > max) {
Chris@908 398 double tmp = min;
Chris@187 399 min = max;
Chris@187 400 max = tmp;
Chris@187 401 }
Chris@187 402
Chris@187 403 QString unit = m_rangeMapper->getUnit();
Chris@187 404
Chris@187 405 QString text;
Chris@187 406 if (objectName() != "") {
Chris@187 407 if (unit != "") {
Chris@187 408 text = tr("New value for %1, from %2 to %3 %4:")
Chris@187 409 .arg(objectName()).arg(min).arg(max).arg(unit);
Chris@187 410 } else {
Chris@187 411 text = tr("New value for %1, from %2 to %3:")
Chris@187 412 .arg(objectName()).arg(min).arg(max);
Chris@187 413 }
Chris@187 414 } else {
Chris@187 415 if (unit != "") {
Chris@187 416 text = tr("Enter a new value from %1 to %2 %3:")
Chris@187 417 .arg(min).arg(max).arg(unit);
Chris@187 418 } else {
Chris@187 419 text = tr("Enter a new value from %1 to %2:")
Chris@187 420 .arg(min).arg(max);
Chris@187 421 }
Chris@187 422 }
Chris@187 423
Chris@908 424 double newValue = QInputDialog::getDouble
Chris@187 425 (this,
Chris@187 426 tr("Enter new value"),
Chris@187 427 text,
Chris@187 428 m_mappedValue,
Chris@187 429 min,
Chris@187 430 max,
Chris@187 431 4,
Chris@187 432 &ok);
Chris@187 433
Chris@187 434 if (ok) {
Chris@187 435 setMappedValue(newValue);
Chris@187 436 }
Chris@187 437
Chris@187 438 } else {
Chris@187 439
Chris@616 440 int newValue = QInputDialog::getInt
Chris@187 441 (this,
Chris@187 442 tr("Enter new value"),
Chris@187 443 tr("Enter a new value from %1 to %2:")
Chris@187 444 .arg(m_min).arg(m_max),
Chris@187 445 getValue(), m_min, m_max, 1, &ok);
Chris@187 446
Chris@187 447 if (ok) {
Chris@187 448 setValue(newValue);
Chris@187 449 }
Chris@187 450 }
Chris@132 451 }
Chris@132 452
Chris@187 453
Chris@132 454 void
Chris@132 455 Thumbwheel::mouseMoveEvent(QMouseEvent *e)
Chris@132 456 {
Chris@133 457 if (!m_clicked) return;
Chris@132 458 int dist = 0;
Chris@132 459 if (m_orientation == Qt::Horizontal) {
Chris@132 460 dist = e->x() - m_clickPos.x();
Chris@132 461 } else {
Chris@132 462 dist = e->y() - m_clickPos.y();
Chris@132 463 }
Chris@165 464
Chris@908 465 float rotation = m_clickRotation + (m_speed * float(dist)) / 100;
Chris@165 466 if (rotation < 0.f) rotation = 0.f;
Chris@165 467 if (rotation > 1.f) rotation = 1.f;
Chris@908 468 int value = int(lrintf(float(m_min) + float(m_max - m_min) * m_rotation));
Chris@132 469 if (value != m_value) {
Chris@132 470 setValue(value);
Chris@132 471 if (m_tracking) emit valueChanged(getValue());
Chris@165 472 m_rotation = rotation;
Chris@165 473 } else if (fabsf(rotation - m_rotation) > 0.001) {
Chris@165 474 m_rotation = rotation;
Chris@165 475 repaint();
Chris@165 476 }
Chris@132 477 }
Chris@132 478
Chris@132 479 void
Chris@132 480 Thumbwheel::mouseReleaseEvent(QMouseEvent *e)
Chris@132 481 {
Chris@133 482 if (!m_clicked) return;
Chris@132 483 bool reallyTracking = m_tracking;
Chris@132 484 m_tracking = true;
Chris@132 485 mouseMoveEvent(e);
Chris@132 486 m_tracking = reallyTracking;
Chris@133 487 m_clicked = false;
Chris@132 488 }
Chris@132 489
Chris@132 490 void
Chris@132 491 Thumbwheel::wheelEvent(QWheelEvent *e)
Chris@132 492 {
Chris@1303 493 int delta = m_wheelCounter.count(e);
Chris@132 494
Chris@1303 495 if (delta == 0) {
Chris@1303 496 return;
Chris@132 497 }
Chris@1303 498
Chris@1303 499 setValue(m_value + delta);
Chris@132 500 emit valueChanged(getValue());
Chris@132 501 }
Chris@132 502
Chris@132 503 void
Chris@132 504 Thumbwheel::paintEvent(QPaintEvent *)
Chris@132 505 {
Chris@382 506 Profiler profiler("Thumbwheel::paintEvent");
Chris@382 507
Chris@382 508 if (!m_cache.isNull()) {
Chris@382 509 QPainter paint(this);
Chris@1192 510 paint.drawImage(rect(), m_cache, m_cache.rect());
Chris@382 511 return;
Chris@382 512 }
Chris@382 513
Chris@382 514 Profiler profiler2("Thumbwheel::paintEvent (no cache)");
Chris@382 515
Chris@1192 516 QSize imageSize = size() * devicePixelRatio();
Chris@1192 517 m_cache = QImage(imageSize, QImage::Format_ARGB32);
Chris@382 518 m_cache.fill(Qt::transparent);
Chris@190 519
Chris@1193 520 int w = m_cache.width();
Chris@1193 521 int h = m_cache.height();
Chris@1192 522 int bw = 3; // border width
Chris@191 523
Chris@191 524 QRect subclip;
Chris@191 525 if (m_orientation == Qt::Horizontal) {
Chris@1192 526 subclip = QRect(bw, bw+1, w - bw*2, h - bw*2 - 2);
Chris@191 527 } else {
Chris@1192 528 subclip = QRect(bw+1, bw, w - bw*2 - 2, h - bw*2);
Chris@191 529 }
Chris@191 530
Chris@382 531 QPainter paint(&m_cache);
Chris@1192 532 paint.setClipRect(m_cache.rect());
Chris@1478 533 paint.fillRect(subclip, palette().window().color());
Chris@190 534
Chris@190 535 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@133 536
Chris@908 537 double w0 = 0.5;
Chris@908 538 double w1 = w - 0.5;
Chris@190 539
Chris@908 540 double h0 = 0.5;
Chris@908 541 double h1 = h - 0.5;
Chris@190 542
Chris@190 543 for (int i = bw-1; i >= 0; --i) {
Chris@190 544
Chris@133 545 int grey = (i + 1) * (256 / (bw + 1));
Chris@133 546 QColor fc = QColor(grey, grey, grey);
Chris@133 547 paint.setPen(fc);
Chris@190 548
Chris@190 549 QPainterPath path;
Chris@190 550
Chris@190 551 if (m_orientation == Qt::Horizontal) {
Chris@190 552 path.moveTo(w0 + i, h0 + i + 2);
Chris@190 553 path.quadTo(w/2, i * 1.25, w1 - i, h0 + i + 2);
Chris@190 554 path.lineTo(w1 - i, h1 - i - 2);
Chris@190 555 path.quadTo(w/2, h - i * 1.25, w0 + i, h1 - i - 2);
Chris@190 556 path.closeSubpath();
Chris@190 557 } else {
Chris@190 558 path.moveTo(w0 + i + 2, h0 + i);
Chris@190 559 path.quadTo(i * 1.25, h/2, w0 + i + 2, h1 - i);
Chris@190 560 path.lineTo(w1 - i - 2, h1 - i);
Chris@190 561 path.quadTo(w - i * 1.25, h/2, w1 - i - 2, h0 + i);
Chris@190 562 path.closeSubpath();
Chris@190 563 }
Chris@190 564
Chris@190 565 paint.drawPath(path);
Chris@133 566 }
Chris@133 567
Chris@191 568 paint.setClipRect(subclip);
Chris@133 569
Chris@908 570 double radians = m_rotation * 1.5f * M_PI;
Chris@132 571
Chris@682 572 // cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << endl;
Chris@132 573
Chris@1192 574 int ww = (m_orientation == Qt::Horizontal ? w : h) - bw*2; // wheel width
Chris@132 575
Chris@132 576 // total number of notches on the entire wheel
Chris@132 577 int notches = 25;
Chris@132 578
Chris@132 579 // radius of the wheel including invisible part
Chris@1192 580 int radius = int(ww / 2 + 2);
Chris@132 581
Chris@132 582 for (int i = 0; i < notches; ++i) {
Chris@132 583
Chris@908 584 double a0 = (2.0 * M_PI * i) / notches + radians;
Chris@908 585 double a1 = a0 + M_PI / (notches * 2);
Chris@908 586 double a2 = (2.0 * M_PI * (i + 1)) / notches + radians;
Chris@132 587
Chris@908 588 double depth = cos((a0 + a2) / 2);
Chris@132 589 if (depth < 0) continue;
Chris@132 590
Chris@1192 591 double x0 = radius * sin(a0) + ww/2;
Chris@1192 592 double x1 = radius * sin(a1) + ww/2;
Chris@1192 593 double x2 = radius * sin(a2) + ww/2;
Chris@1192 594 if (x2 < 0 || x0 > ww) continue;
Chris@132 595
Chris@132 596 if (x0 < 0) x0 = 0;
Chris@1192 597 if (x2 > ww) x2 = ww;
Chris@132 598
Chris@133 599 x0 += bw;
Chris@133 600 x1 += bw;
Chris@133 601 x2 += bw;
Chris@133 602
Chris@908 603 int grey = int(lrint(120 * depth));
Chris@541 604
Chris@132 605 QColor fc = QColor(grey, grey, grey);
Chris@541 606 QColor oc = palette().highlight().color();
Chris@132 607
Chris@541 608 paint.setPen(fc);
Chris@132 609
Chris@132 610 if (m_showScale) {
Chris@132 611
Chris@132 612 paint.setBrush(oc);
Chris@132 613
Chris@908 614 double prop;
Chris@132 615 if (i >= notches / 4) {
Chris@908 616 prop = double(notches - (((i - double(notches) / 4.f) * 4.f) / 3.f))
Chris@132 617 / notches;
Chris@132 618 } else {
Chris@132 619 prop = 0.f;
Chris@132 620 }
Chris@132 621
Chris@132 622 if (m_orientation == Qt::Horizontal) {
Chris@1192 623 paint.drawRect(QRectF(x1, h - (h - bw*2) * prop - bw,
Chris@1192 624 x2 - x1, h * prop));
Chris@132 625 } else {
Chris@1192 626 paint.drawRect(QRectF(bw, x1, (w - bw*2) * prop, x2 - x1));
Chris@132 627 }
Chris@132 628 }
Chris@132 629
Chris@541 630 paint.setPen(fc);
Chris@1478 631 paint.setBrush(palette().window().color());
Chris@132 632
Chris@132 633 if (m_orientation == Qt::Horizontal) {
Chris@1192 634 paint.drawRect(QRectF(x0, bw, x1 - x0, h - bw*2));
Chris@132 635 } else {
Chris@1192 636 paint.drawRect(QRectF(bw, x0, w - bw*2, x1 - x0));
Chris@132 637 }
Chris@132 638 }
Chris@382 639
Chris@382 640 QPainter paint2(this);
Chris@1192 641 paint2.drawImage(rect(), m_cache, m_cache.rect());
Chris@132 642 }
Chris@132 643
Chris@132 644 QSize
Chris@132 645 Thumbwheel::sizeHint() const
Chris@132 646 {
Chris@132 647 if (m_orientation == Qt::Horizontal) {
Chris@132 648 return QSize(80, 12);
Chris@132 649 } else {
Chris@132 650 return QSize(12, 80);
Chris@132 651 }
Chris@132 652 }
Chris@132 653