annotate widgets/Thumbwheel.cpp @ 1605:ae2d5f8ff005

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