annotate widgets/AudioDial.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@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@0 7
Chris@59 8 This program is free software; you can redistribute it and/or
Chris@59 9 modify it under the terms of the GNU General Public License as
Chris@59 10 published by the Free Software Foundation; either version 2 of the
Chris@59 11 License, or (at your option) any later version. See the file
Chris@59 12 COPYING included with this distribution for more information.
Chris@0 13 */
Chris@0 14
Chris@0 15 /**
Chris@0 16 * A rotary dial widget.
Chris@0 17 *
Chris@0 18 * Based on an original design by Thorsten Wilms.
Chris@0 19 *
Chris@0 20 * Implemented as a widget for the Rosegarden MIDI and audio sequencer
Chris@0 21 * and notation editor by Chris Cannam.
Chris@0 22 *
Chris@0 23 * Extracted into a standalone Qt3 widget by Pedro Lopez-Cabanillas
Chris@0 24 * and adapted for use in QSynth.
Chris@0 25 *
Chris@0 26 * Ported to Qt4 by Chris Cannam.
Chris@0 27 *
Chris@168 28 * This file copyright 2003-2006 Chris Cannam, copyright 2005 Pedro
Chris@182 29 * Lopez-Cabanillas, copyright 2006 Queen Mary, University of London.
Chris@0 30 *
Chris@0 31 * This program is free software; you can redistribute it and/or
Chris@0 32 * modify it under the terms of the GNU General Public License as
Chris@0 33 * published by the Free Software Foundation; either version 2 of the
Chris@0 34 * License, or (at your option) any later version. See the file
Chris@0 35 * COPYING included with this distribution for more information.
Chris@0 36 */
Chris@0 37
Chris@0 38 #include "AudioDial.h"
Chris@0 39
Chris@167 40 #include "base/RangeMapper.h"
Chris@167 41
Chris@0 42 #include <cmath>
Chris@0 43 #include <iostream>
Chris@0 44
Chris@0 45 #include <QTimer>
Chris@0 46 #include <QPainter>
Chris@0 47 #include <QPixmap>
Chris@0 48 #include <QColormap>
Chris@0 49 #include <QMouseEvent>
Chris@0 50 #include <QPaintEvent>
Chris@34 51 #include <QInputDialog>
Chris@1584 52 #include <QMenu>
Chris@0 53
Chris@382 54 #include "base/Profiler.h"
Chris@382 55
Chris@1584 56 #include "MenuTitle.h"
Chris@1584 57
Chris@682 58
Chris@682 59
Chris@0 60
Chris@0 61
Chris@0 62 //!!! Pedro updated his version to use my up/down response code from RG -- need to grab that code in preference to this version from Rui
Chris@0 63
Chris@0 64
Chris@0 65 //-------------------------------------------------------------------------
Chris@0 66 // AudioDial - Instance knob widget class.
Chris@0 67 //
Chris@0 68
Chris@0 69 #define AUDIO_DIAL_MIN (0.25 * M_PI)
Chris@0 70 #define AUDIO_DIAL_MAX (1.75 * M_PI)
Chris@0 71 #define AUDIO_DIAL_RANGE (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN)
Chris@0 72
Chris@0 73
Chris@189 74
Chris@0 75 // Constructor.
Chris@0 76 AudioDial::AudioDial(QWidget *parent) :
Chris@0 77 QDial(parent),
Chris@1443 78 m_knobColor(Qt::black), // shorthand for "background colour" in paint()
Chris@1443 79 m_meterColor(Qt::white), // shorthand for "foreground colour" in paint()
Chris@167 80 m_defaultValue(0),
Chris@344 81 m_defaultMappedValue(0),
Chris@168 82 m_mappedValue(0),
Chris@168 83 m_noMappedUpdate(false),
Chris@187 84 m_showTooltip(true),
Chris@1584 85 m_provideContextMenu(true),
Chris@1584 86 m_lastContextMenu(nullptr),
Chris@1408 87 m_rangeMapper(nullptr)
Chris@0 88 {
Chris@0 89 m_mouseDial = false;
Chris@0 90 m_mousePressed = false;
Chris@1584 91 setContextMenuPolicy(Qt::CustomContextMenu);
Chris@1584 92 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
Chris@1584 93 this, SLOT(contextMenuRequested(const QPoint &)));
Chris@0 94 }
Chris@0 95
Chris@0 96
Chris@0 97 // Destructor.
Chris@0 98 AudioDial::~AudioDial (void)
Chris@0 99 {
Chris@167 100 delete m_rangeMapper;
Chris@1584 101 delete m_lastContextMenu;
Chris@167 102 }
Chris@167 103
Chris@1584 104 void AudioDial::contextMenuRequested(const QPoint &pos)
Chris@1584 105 {
Chris@1584 106 if (!m_provideContextMenu) {
Chris@1584 107 return;
Chris@1584 108 }
Chris@1589 109
Chris@1589 110 delete m_lastContextMenu;
Chris@1589 111 m_lastContextMenu = new QMenu;
Chris@1589 112 auto m = m_lastContextMenu;
Chris@1584 113
Chris@1584 114 if (m_title == "") {
Chris@1584 115 MenuTitle::addTitle(m, tr("Dial"));
Chris@1584 116 } else {
Chris@1584 117 MenuTitle::addTitle(m, m_title);
Chris@1584 118 }
Chris@1584 119
Chris@1602 120 m->addAction(tr("&Edit..."), this, SLOT(edit()));
Chris@1602 121 m->addAction(tr("&Reset to Default"), this, SLOT(setToDefault()));
Chris@1584 122
Chris@1584 123 m->popup(mapToGlobal(pos));
Chris@1584 124 }
Chris@167 125
Chris@167 126 void AudioDial::setRangeMapper(RangeMapper *mapper)
Chris@167 127 {
Chris@187 128 if (m_rangeMapper == mapper) return;
Chris@187 129
Chris@170 130 if (!m_rangeMapper && mapper) {
Chris@168 131 connect(this, SIGNAL(valueChanged(int)),
Chris@168 132 this, SLOT(updateMappedValue(int)));
Chris@168 133 }
Chris@170 134
Chris@167 135 delete m_rangeMapper;
Chris@167 136 m_rangeMapper = mapper;
Chris@170 137
Chris@187 138 updateMappedValue(value());
Chris@0 139 }
Chris@0 140
Chris@0 141
Chris@0 142 void AudioDial::paintEvent(QPaintEvent *)
Chris@0 143 {
Chris@382 144 Profiler profiler("AudioDial::paintEvent");
Chris@382 145
Chris@0 146 QPainter paint;
Chris@0 147
Chris@908 148 double angle = AUDIO_DIAL_MIN // offset
Chris@1266 149 + (AUDIO_DIAL_RANGE *
Chris@1266 150 (double(QDial::value() - QDial::minimum()) /
Chris@1266 151 (double(QDial::maximum() - QDial::minimum()))));
Chris@0 152 int degrees = int(angle * 180.0 / M_PI);
Chris@0 153
Chris@0 154 int ns = notchSize();
Chris@0 155 int numTicks = 1 + (maximum() + ns - minimum()) / ns;
Chris@1266 156
Chris@0 157 QColor knobColor(m_knobColor);
Chris@1443 158 if (knobColor == Qt::black) {
Chris@1476 159 knobColor = palette().window().color().lighter(150);
Chris@1443 160 }
Chris@1443 161 bool knobIsDark =
Chris@1443 162 (knobColor.red() + knobColor.green() + knobColor.blue() <= 384);
Chris@0 163
Chris@0 164 QColor meterColor(m_meterColor);
Chris@1443 165 if (!isEnabled()) {
Chris@1266 166 meterColor = palette().mid().color();
Chris@1443 167 } else if (m_meterColor == Qt::white) {
Chris@1443 168 if (knobIsDark) {
Chris@1545 169 meterColor = palette().text().color();
Chris@1443 170 } else {
Chris@1443 171 meterColor = palette().highlight().color();
Chris@1443 172 }
Chris@1443 173 }
Chris@0 174
Chris@1443 175 QColor notchColor(palette().dark().color());
Chris@1443 176 if (knobIsDark) {
Chris@1545 177 notchColor = palette().text().color();
Chris@1443 178 }
Chris@1443 179
Chris@0 180 int m_size = width() < height() ? width() : height();
Chris@0 181 int scale = 1;
Chris@249 182 int width = m_size - 2*scale;
Chris@0 183
Chris@0 184 paint.begin(this);
Chris@0 185 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@0 186 paint.translate(1, 1);
Chris@0 187
Chris@0 188 QPen pen;
Chris@0 189 QColor c;
Chris@0 190
Chris@0 191 // Knob body and face...
Chris@0 192
Chris@0 193 c = knobColor;
Chris@0 194 pen.setColor(knobColor);
Chris@0 195 pen.setWidth(scale * 2);
Chris@0 196 pen.setCapStyle(Qt::FlatCap);
Chris@1266 197
Chris@0 198 paint.setPen(pen);
Chris@0 199 paint.setBrush(c);
Chris@0 200
Chris@0 201 int indent = (int)(width * 0.15 + 1);
Chris@0 202
Chris@0 203 paint.drawEllipse(indent-1, indent-1, width-2*indent, width-2*indent);
Chris@0 204
Chris@0 205 pen.setWidth(3 * scale);
Chris@0 206 int pos = indent-1 + (width-2*indent) / 20;
Chris@0 207 int darkWidth = (width-2*indent) * 3 / 4;
Chris@0 208 while (darkWidth) {
Chris@1443 209 if (knobIsDark) {
Chris@1476 210 c = c.darker(102);
Chris@1443 211 } else {
Chris@1476 212 c = c.lighter(102);
Chris@1443 213 }
Chris@1266 214 pen.setColor(c);
Chris@1266 215 paint.setPen(pen);
Chris@1266 216 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@1266 217 if (!--darkWidth) break;
Chris@1266 218 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@1266 219 if (!--darkWidth) break;
Chris@1266 220 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@1266 221 ++pos; --darkWidth;
Chris@0 222 }
Chris@0 223
Chris@0 224 // Tick notches...
Chris@0 225
Chris@34 226 if ( notchesVisible() ) {
Chris@1443 227 pen.setColor(notchColor);
Chris@1266 228 pen.setWidth(scale);
Chris@1266 229 paint.setPen(pen);
Chris@1266 230 for (int i = 0; i < numTicks; ++i) {
Chris@1266 231 int div = numTicks;
Chris@1266 232 if (div > 1) --div;
Chris@1266 233 drawTick(paint, AUDIO_DIAL_MIN + (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN) * i / div,
Chris@1266 234 width, true);
Chris@1266 235 }
Chris@0 236 }
Chris@0 237
Chris@0 238 // The bright metering bit...
Chris@0 239
Chris@0 240 c = meterColor;
Chris@0 241 pen.setColor(c);
Chris@0 242 pen.setWidth(indent);
Chris@0 243 paint.setPen(pen);
Chris@0 244
Chris@682 245 // cerr << "degrees " << degrees << ", gives us " << -(degrees - 45) * 16 << endl;
Chris@0 246
Chris@0 247 int arcLen = -(degrees - 45) * 16;
Chris@0 248 if (arcLen == 0) arcLen = -16;
Chris@0 249
Chris@0 250 paint.drawArc(indent/2, indent/2,
Chris@1266 251 width-indent, width-indent, (180 + 45) * 16, arcLen);
Chris@0 252
Chris@0 253 paint.setBrush(Qt::NoBrush);
Chris@0 254
Chris@0 255 // Shadowing...
Chris@0 256
Chris@0 257 pen.setWidth(scale);
Chris@0 258 paint.setPen(pen);
Chris@0 259
Chris@0 260 // Knob shadow...
Chris@0 261
Chris@0 262 int shadowAngle = -720;
Chris@1443 263 if (knobIsDark) {
Chris@1476 264 c = knobColor.lighter();
Chris@1443 265 } else {
Chris@1476 266 c = knobColor.darker();
Chris@1443 267 }
Chris@0 268 for (int arc = 120; arc < 2880; arc += 240) {
Chris@1266 269 pen.setColor(c);
Chris@1266 270 paint.setPen(pen);
Chris@1266 271 paint.drawArc(indent, indent,
Chris@1266 272 width-2*indent, width-2*indent, shadowAngle + arc, 240);
Chris@1266 273 paint.drawArc(indent, indent,
Chris@1266 274 width-2*indent, width-2*indent, shadowAngle - arc, 240);
Chris@1443 275 if (knobIsDark) {
Chris@1476 276 c = c.darker(110);
Chris@1443 277 } else {
Chris@1476 278 c = c.lighter(110);
Chris@1443 279 }
Chris@0 280 }
Chris@0 281
Chris@738 282 // Scale shadow, omitting the bottom part...
Chris@0 283
Chris@0 284 shadowAngle = 2160;
Chris@738 285 c = palette().shadow().color();
Chris@738 286 for (int i = 0; i < 5; ++i) {
Chris@1266 287 pen.setColor(c);
Chris@1266 288 paint.setPen(pen);
Chris@738 289 int arc = i * 240 + 120;
Chris@1266 290 paint.drawArc(scale/2, scale/2,
Chris@1266 291 width-scale, width-scale, shadowAngle + arc, 240);
Chris@1476 292 c = c.lighter(110);
Chris@738 293 }
Chris@738 294 c = palette().shadow().color();
Chris@738 295 for (int i = 0; i < 12; ++i) {
Chris@1266 296 pen.setColor(c);
Chris@1266 297 paint.setPen(pen);
Chris@738 298 int arc = i * 240 + 120;
Chris@1266 299 paint.drawArc(scale/2, scale/2,
Chris@1266 300 width-scale, width-scale, shadowAngle - arc, 240);
Chris@1476 301 c = c.lighter(110);
Chris@0 302 }
Chris@0 303
Chris@0 304 // Scale ends...
Chris@0 305
Chris@1443 306 if (knobIsDark) {
Chris@1443 307 pen.setColor(palette().mid().color());
Chris@1443 308 } else {
Chris@1443 309 pen.setColor(palette().shadow().color());
Chris@1443 310 }
Chris@0 311 pen.setWidth(scale);
Chris@0 312 paint.setPen(pen);
Chris@0 313 for (int i = 0; i < numTicks; ++i) {
Chris@1266 314 if (i != 0 && i != numTicks - 1) continue;
Chris@1266 315 int div = numTicks;
Chris@1266 316 if (div > 1) --div;
Chris@1266 317 drawTick(paint, AUDIO_DIAL_MIN + (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN) * i / div,
Chris@1266 318 width, false);
Chris@0 319 }
Chris@0 320
Chris@0 321 // Pointer notch...
Chris@0 322
Chris@908 323 double hyp = double(width) / 2.0;
Chris@908 324 double len = hyp - indent;
Chris@0 325 --len;
Chris@0 326
Chris@908 327 double x0 = hyp;
Chris@908 328 double y0 = hyp;
Chris@0 329
Chris@908 330 double x = hyp - len * sin(angle);
Chris@908 331 double y = hyp + len * cos(angle);
Chris@0 332
Chris@1443 333 c = notchColor;
Chris@1443 334 if (isEnabled()) {
Chris@1443 335 if (knobIsDark) {
Chris@1476 336 c = c.lighter(130);
Chris@1443 337 } else {
Chris@1476 338 c = c.darker(130);
Chris@1443 339 }
Chris@1443 340 }
Chris@1443 341 pen.setColor(c);
Chris@0 342 pen.setWidth(scale * 2);
Chris@0 343 paint.setPen(pen);
Chris@0 344 paint.drawLine(int(x0), int(y0), int(x), int(y));
Chris@0 345
Chris@0 346 paint.end();
Chris@0 347 }
Chris@0 348
Chris@0 349
Chris@0 350 void AudioDial::drawTick(QPainter &paint,
Chris@1266 351 double angle, int size, bool internal)
Chris@0 352 {
Chris@908 353 double hyp = double(size) / 2.0;
Chris@908 354 double x0 = hyp - (hyp - 1) * sin(angle);
Chris@908 355 double y0 = hyp + (hyp - 1) * cos(angle);
Chris@0 356
Chris@0 357 // cerr << "drawTick: angle " << angle << ", size " << size << ", internal " << internal << endl;
Chris@0 358
Chris@0 359 if (internal) {
Chris@0 360
Chris@1266 361 double len = hyp / 4;
Chris@1266 362 double x1 = hyp - (hyp - len) * sin(angle);
Chris@1266 363 double y1 = hyp + (hyp - len) * cos(angle);
Chris@1266 364
Chris@1266 365 paint.drawLine(int(x0), int(y0), int(x1), int(y1));
Chris@0 366
Chris@0 367 } else {
Chris@0 368
Chris@1266 369 double len = hyp / 4;
Chris@1266 370 double x1 = hyp - (hyp + len) * sin(angle);
Chris@1266 371 double y1 = hyp + (hyp + len) * cos(angle);
Chris@0 372
Chris@1266 373 paint.drawLine(int(x0), int(y0), int(x1), int(y1));
Chris@0 374 }
Chris@0 375 }
Chris@0 376
Chris@0 377
Chris@0 378 void AudioDial::setKnobColor(const QColor& color)
Chris@0 379 {
Chris@0 380 m_knobColor = color;
Chris@0 381 update();
Chris@0 382 }
Chris@0 383
Chris@0 384
Chris@0 385 void AudioDial::setMeterColor(const QColor& color)
Chris@0 386 {
Chris@0 387 m_meterColor = color;
Chris@0 388 update();
Chris@0 389 }
Chris@0 390
Chris@0 391
Chris@0 392 void AudioDial::setMouseDial(bool mouseDial)
Chris@0 393 {
Chris@0 394 m_mouseDial = mouseDial;
Chris@0 395 }
Chris@0 396
Chris@0 397
Chris@34 398 void AudioDial::setDefaultValue(int defaultValue)
Chris@34 399 {
Chris@34 400 m_defaultValue = defaultValue;
Chris@344 401 if (m_rangeMapper) {
Chris@344 402 m_defaultMappedValue = m_rangeMapper->getValueForPosition(defaultValue);
Chris@344 403 }
Chris@34 404 }
Chris@34 405
Chris@219 406 void AudioDial::setValue(int value)
Chris@219 407 {
Chris@219 408 QDial::setValue(value);
Chris@219 409 updateMappedValue(value);
Chris@219 410 }
Chris@219 411
Chris@908 412 void AudioDial::setDefaultMappedValue(double value)
Chris@344 413 {
Chris@344 414 m_defaultMappedValue = value;
Chris@344 415 if (m_rangeMapper) {
Chris@344 416 m_defaultValue = m_rangeMapper->getPositionForValue(value);
Chris@344 417 }
Chris@344 418 }
Chris@219 419
Chris@908 420 void AudioDial::setMappedValue(double mappedValue)
Chris@177 421 {
Chris@177 422 if (m_rangeMapper) {
Chris@177 423 int newPosition = m_rangeMapper->getPositionForValue(mappedValue);
Chris@190 424 bool changed = (m_mappedValue != mappedValue);
Chris@177 425 m_mappedValue = mappedValue;
Chris@177 426 m_noMappedUpdate = true;
Chris@587 427 SVDEBUG << "AudioDial::setMappedValue(" << mappedValue << "): new position is " << newPosition << endl;
Chris@177 428 if (newPosition != value()) {
Chris@177 429 setValue(newPosition);
Chris@190 430 } else if (changed) {
Chris@177 431 emit valueChanged(newPosition);
Chris@177 432 }
Chris@177 433 m_noMappedUpdate = false;
Chris@177 434 } else {
Chris@187 435 setValue(int(mappedValue));
Chris@177 436 }
Chris@177 437 }
Chris@177 438
Chris@177 439
Chris@168 440 void AudioDial::setShowToolTip(bool show)
Chris@168 441 {
Chris@168 442 m_showTooltip = show;
Chris@168 443 m_noMappedUpdate = true;
Chris@168 444 updateMappedValue(value());
Chris@168 445 m_noMappedUpdate = false;
Chris@168 446 }
Chris@168 447
Chris@168 448
Chris@1584 449 void AudioDial::setProvideContextMenu(bool provide)
Chris@1584 450 {
Chris@1584 451 m_provideContextMenu = provide;
Chris@1584 452 }
Chris@1584 453
Chris@1584 454
Chris@908 455 double AudioDial::mappedValue() const
Chris@167 456 {
Chris@168 457 if (m_rangeMapper) {
Chris@587 458 // SVDEBUG << "AudioDial::mappedValue(): value = " << value() << ", mappedValue = " << m_mappedValue << endl;
Chris@168 459 return m_mappedValue;
Chris@168 460 }
Chris@168 461 return value();
Chris@168 462 }
Chris@168 463
Chris@168 464
Chris@168 465 void AudioDial::updateMappedValue(int value)
Chris@168 466 {
Chris@170 467 if (!m_noMappedUpdate) {
Chris@170 468 if (m_rangeMapper) {
Chris@168 469 m_mappedValue = m_rangeMapper->getValueForPosition(value);
Chris@170 470 } else {
Chris@170 471 m_mappedValue = value;
Chris@168 472 }
Chris@168 473 }
Chris@168 474
Chris@1584 475 QString name = objectName();
Chris@1584 476 QString label;
Chris@1584 477 if (m_rangeMapper) {
Chris@1584 478 label = m_rangeMapper->getLabel(value);
Chris@1584 479 }
Chris@1584 480 QString text;
Chris@1584 481 if (label != "") {
Chris@1584 482 if (name != "") {
Chris@1584 483 text = tr("%1: %2").arg(name).arg(label);
Chris@1584 484 } else {
Chris@1584 485 text = label;
Chris@1584 486 }
Chris@1584 487 } else {
Chris@1584 488 QString unit = "";
Chris@1584 489 if (m_rangeMapper) {
Chris@1584 490 unit = m_rangeMapper->getUnit();
Chris@1584 491 }
Chris@1584 492 if (name != "") {
Chris@1584 493 text = tr("%1: %2%3").arg(name).arg(m_mappedValue).arg(unit);
Chris@1584 494 } else {
Chris@1584 495 text = tr("%2%3").arg(m_mappedValue).arg(unit);
Chris@1584 496 }
Chris@1584 497 }
Chris@1584 498
Chris@1584 499 m_title = text;
Chris@1584 500
Chris@168 501 if (m_showTooltip) {
Chris@168 502 setToolTip(text);
Chris@1584 503 } else {
Chris@1584 504 setToolTip("");
Chris@168 505 }
Chris@167 506 }
Chris@167 507
Chris@344 508 void
Chris@344 509 AudioDial::setToDefault()
Chris@344 510 {
Chris@344 511 if (m_rangeMapper) {
Chris@344 512 setMappedValue(m_defaultMappedValue);
Chris@344 513 return;
Chris@344 514 }
Chris@344 515 int dv = m_defaultValue;
Chris@344 516 if (dv < minimum()) dv = minimum();
Chris@344 517 if (dv > maximum()) dv = maximum();
Chris@344 518 setValue(m_defaultValue);
Chris@344 519 }
Chris@167 520
Chris@0 521 // Alternate mouse behavior event handlers.
Chris@0 522 void AudioDial::mousePressEvent(QMouseEvent *mouseEvent)
Chris@0 523 {
Chris@0 524 if (m_mouseDial) {
Chris@1266 525 QDial::mousePressEvent(mouseEvent);
Chris@187 526 } else if (mouseEvent->button() == Qt::MidButton ||
Chris@187 527 ((mouseEvent->button() == Qt::LeftButton) &&
Chris@187 528 (mouseEvent->modifiers() & Qt::ControlModifier))) {
Chris@344 529 setToDefault();
Chris@187 530 } else if (mouseEvent->button() == Qt::LeftButton) {
Chris@1266 531 m_mousePressed = true;
Chris@1266 532 m_posMouse = mouseEvent->pos();
Chris@34 533 }
Chris@34 534 }
Chris@34 535
Chris@34 536
Chris@34 537 void AudioDial::mouseDoubleClickEvent(QMouseEvent *mouseEvent)
Chris@34 538 {
Chris@187 539 //!!! needs a common base class with Thumbwheel
Chris@187 540
Chris@34 541 if (m_mouseDial) {
Chris@1266 542 QDial::mouseDoubleClickEvent(mouseEvent);
Chris@187 543 } else if (mouseEvent->button() != Qt::LeftButton) {
Chris@187 544 return;
Chris@187 545 }
Chris@167 546
Chris@1584 547 edit();
Chris@1584 548 }
Chris@1584 549
Chris@1584 550 void AudioDial::edit()
Chris@1584 551 {
Chris@187 552 bool ok = false;
Chris@167 553
Chris@187 554 if (m_rangeMapper) {
Chris@187 555
Chris@908 556 double min = m_rangeMapper->getValueForPosition(minimum());
Chris@908 557 double max = m_rangeMapper->getValueForPosition(maximum());
Chris@187 558
Chris@187 559 if (min > max) {
Chris@908 560 double tmp = min;
Chris@187 561 min = max;
Chris@187 562 max = tmp;
Chris@187 563 }
Chris@167 564
Chris@187 565 QString unit = m_rangeMapper->getUnit();
Chris@187 566
Chris@187 567 QString text;
Chris@187 568 if (objectName() != "") {
Chris@187 569 if (unit != "") {
Chris@187 570 text = tr("New value for %1, from %2 to %3 %4:")
Chris@187 571 .arg(objectName()).arg(min).arg(max).arg(unit);
Chris@167 572 } else {
Chris@187 573 text = tr("New value for %1, from %2 to %3:")
Chris@187 574 .arg(objectName()).arg(min).arg(max);
Chris@167 575 }
Chris@187 576 } else {
Chris@187 577 if (unit != "") {
Chris@187 578 text = tr("Enter a new value from %1 to %2 %3:")
Chris@187 579 .arg(min).arg(max).arg(unit);
Chris@187 580 } else {
Chris@187 581 text = tr("Enter a new value from %1 to %2:")
Chris@187 582 .arg(min).arg(max);
Chris@168 583 }
Chris@187 584 }
Chris@187 585
Chris@908 586 double newValue = QInputDialog::getDouble
Chris@187 587 (this,
Chris@187 588 tr("Enter new value"),
Chris@187 589 text,
Chris@187 590 m_mappedValue,
Chris@187 591 min,
Chris@187 592 max,
Chris@187 593 4,
Chris@187 594 &ok);
Chris@187 595
Chris@187 596 if (ok) {
Chris@187 597 setMappedValue(newValue);
Chris@187 598 }
Chris@187 599
Chris@187 600 } else {
Chris@187 601
Chris@616 602 int newPosition = QInputDialog::getInt
Chris@187 603 (this,
Chris@187 604 tr("Enter new value"),
Chris@187 605 tr("Enter a new value from %1 to %2:")
Chris@187 606 .arg(minimum()).arg(maximum()),
Chris@395 607 value(), minimum(), maximum(), singleStep(), &ok);
Chris@187 608
Chris@187 609 if (ok) {
Chris@187 610 setValue(newPosition);
Chris@167 611 }
Chris@0 612 }
Chris@0 613 }
Chris@0 614
Chris@0 615
Chris@0 616 void AudioDial::mouseMoveEvent(QMouseEvent *mouseEvent)
Chris@0 617 {
Chris@0 618 if (m_mouseDial) {
Chris@1266 619 QDial::mouseMoveEvent(mouseEvent);
Chris@0 620 } else if (m_mousePressed) {
Chris@1266 621 const QPoint& posMouse = mouseEvent->pos();
Chris@1266 622 int v = QDial::value()
Chris@1266 623 + (posMouse.x() - m_posMouse.x())
Chris@1266 624 + (m_posMouse.y() - posMouse.y());
Chris@1266 625 if (v > QDial::maximum())
Chris@1266 626 v = QDial::maximum();
Chris@1266 627 else
Chris@1266 628 if (v < QDial::minimum())
Chris@1266 629 v = QDial::minimum();
Chris@1266 630 m_posMouse = posMouse;
Chris@1266 631 QDial::setValue(v);
Chris@0 632 }
Chris@0 633 }
Chris@0 634
Chris@0 635
Chris@0 636 void AudioDial::mouseReleaseEvent(QMouseEvent *mouseEvent)
Chris@0 637 {
Chris@0 638 if (m_mouseDial) {
Chris@1266 639 QDial::mouseReleaseEvent(mouseEvent);
Chris@0 640 } else if (m_mousePressed) {
Chris@1266 641 m_mousePressed = false;
Chris@0 642 }
Chris@0 643 }
Chris@0 644
Chris@189 645 void
Chris@189 646 AudioDial::enterEvent(QEvent *e)
Chris@189 647 {
Chris@189 648 QDial::enterEvent(e);
Chris@189 649 emit mouseEntered();
Chris@189 650 }
Chris@189 651
Chris@189 652 void
Chris@189 653 AudioDial::leaveEvent(QEvent *e)
Chris@189 654 {
Chris@189 655 QDial::enterEvent(e);
Chris@189 656 emit mouseLeft();
Chris@189 657 }
Chris@189 658