annotate widgets/AudioDial.cpp @ 333:e74b56f07c73

* Some work on correct alignment when moving panes during playback * Overhaul alignment for playback frame values (view manager now always refers to reference-timeline values, only the play source deals in playback model timeline values) * When making a selection, ensure the selection regions shown in other panes (and used for playback constraints if appropriate) are aligned correctly. This may be the coolest feature ever implemented in any program ever.
author Chris Cannam
date Thu, 22 Nov 2007 14:17:19 +0000
parents cd2492c5fe45
children 832d246b327b
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@0 52
Chris@0 53 using std::endl;
Chris@0 54 using std::cerr;
Chris@0 55
Chris@0 56
Chris@0 57 //!!! 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 58
Chris@0 59
Chris@0 60 //-------------------------------------------------------------------------
Chris@0 61 // AudioDial - Instance knob widget class.
Chris@0 62 //
Chris@0 63
Chris@0 64 #define AUDIO_DIAL_MIN (0.25 * M_PI)
Chris@0 65 #define AUDIO_DIAL_MAX (1.75 * M_PI)
Chris@0 66 #define AUDIO_DIAL_RANGE (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN)
Chris@0 67
Chris@0 68
Chris@212 69 //static int dialsExtant = 0;
Chris@189 70
Chris@189 71
Chris@0 72 // Constructor.
Chris@0 73 AudioDial::AudioDial(QWidget *parent) :
Chris@0 74 QDial(parent),
Chris@170 75 m_knobColor(Qt::black),
Chris@170 76 m_meterColor(Qt::white),
Chris@167 77 m_defaultValue(0),
Chris@168 78 m_mappedValue(0),
Chris@168 79 m_noMappedUpdate(false),
Chris@187 80 m_showTooltip(true),
Chris@167 81 m_rangeMapper(0)
Chris@0 82 {
Chris@0 83 m_mouseDial = false;
Chris@0 84 m_mousePressed = false;
Chris@212 85 // ++dialsExtant;
Chris@0 86 }
Chris@0 87
Chris@0 88
Chris@0 89 // Destructor.
Chris@0 90 AudioDial::~AudioDial (void)
Chris@0 91 {
Chris@167 92 delete m_rangeMapper;
Chris@212 93 // --dialsExtant;
Chris@167 94 }
Chris@167 95
Chris@167 96
Chris@167 97 void AudioDial::setRangeMapper(RangeMapper *mapper)
Chris@167 98 {
Chris@212 99 // std::cerr << "AudioDial[" << this << "][\"" << objectName().toStdString() << "\"::setRangeMapper(" << mapper << ") [current is " << m_rangeMapper << "] (have " << dialsExtant << " dials extant)" << std::endl;
Chris@189 100
Chris@187 101 if (m_rangeMapper == mapper) return;
Chris@187 102
Chris@170 103 if (!m_rangeMapper && mapper) {
Chris@168 104 connect(this, SIGNAL(valueChanged(int)),
Chris@168 105 this, SLOT(updateMappedValue(int)));
Chris@168 106 }
Chris@170 107
Chris@167 108 delete m_rangeMapper;
Chris@167 109 m_rangeMapper = mapper;
Chris@170 110
Chris@187 111 updateMappedValue(value());
Chris@0 112 }
Chris@0 113
Chris@0 114
Chris@0 115 void AudioDial::paintEvent(QPaintEvent *)
Chris@0 116 {
Chris@0 117 QPainter paint;
Chris@0 118
Chris@0 119 float angle = AUDIO_DIAL_MIN // offset
Chris@0 120 + (AUDIO_DIAL_RANGE *
Chris@0 121 (float(QDial::value() - QDial::minimum()) /
Chris@0 122 (float(QDial::maximum() - QDial::minimum()))));
Chris@0 123 int degrees = int(angle * 180.0 / M_PI);
Chris@0 124
Chris@0 125 int ns = notchSize();
Chris@0 126 int numTicks = 1 + (maximum() + ns - minimum()) / ns;
Chris@0 127
Chris@0 128 QColor knobColor(m_knobColor);
Chris@0 129 if (knobColor == Qt::black)
Chris@287 130 knobColor = palette().window().color();
Chris@0 131
Chris@0 132 QColor meterColor(m_meterColor);
Chris@0 133 if (!isEnabled())
Chris@0 134 meterColor = palette().mid().color();
Chris@0 135 else if (m_meterColor == Qt::white)
Chris@0 136 meterColor = palette().highlight().color();
Chris@0 137
Chris@0 138 int m_size = width() < height() ? width() : height();
Chris@0 139 int scale = 1;
Chris@249 140 int width = m_size - 2*scale;
Chris@0 141
Chris@0 142 paint.begin(this);
Chris@0 143 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@0 144 paint.translate(1, 1);
Chris@0 145
Chris@0 146 QPen pen;
Chris@0 147 QColor c;
Chris@0 148
Chris@0 149 // Knob body and face...
Chris@0 150
Chris@0 151 c = knobColor;
Chris@0 152 pen.setColor(knobColor);
Chris@0 153 pen.setWidth(scale * 2);
Chris@0 154 pen.setCapStyle(Qt::FlatCap);
Chris@0 155
Chris@0 156 paint.setPen(pen);
Chris@0 157 paint.setBrush(c);
Chris@0 158
Chris@0 159 int indent = (int)(width * 0.15 + 1);
Chris@0 160
Chris@0 161 paint.drawEllipse(indent-1, indent-1, width-2*indent, width-2*indent);
Chris@0 162
Chris@0 163 pen.setWidth(3 * scale);
Chris@0 164 int pos = indent-1 + (width-2*indent) / 20;
Chris@0 165 int darkWidth = (width-2*indent) * 3 / 4;
Chris@0 166 while (darkWidth) {
Chris@0 167 c = c.light(102);
Chris@0 168 pen.setColor(c);
Chris@0 169 paint.setPen(pen);
Chris@0 170 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@0 171 if (!--darkWidth) break;
Chris@0 172 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@0 173 if (!--darkWidth) break;
Chris@0 174 paint.drawEllipse(pos, pos, darkWidth, darkWidth);
Chris@0 175 ++pos; --darkWidth;
Chris@0 176 }
Chris@0 177
Chris@0 178 // Tick notches...
Chris@0 179
Chris@34 180 if ( notchesVisible() ) {
Chris@0 181 // std::cerr << "Notches visible" << std::endl;
Chris@0 182 pen.setColor(palette().dark().color());
Chris@0 183 pen.setWidth(scale);
Chris@0 184 paint.setPen(pen);
Chris@0 185 for (int i = 0; i < numTicks; ++i) {
Chris@0 186 int div = numTicks;
Chris@0 187 if (div > 1) --div;
Chris@0 188 drawTick(paint, AUDIO_DIAL_MIN + (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN) * i / div,
Chris@0 189 width, true);
Chris@0 190 }
Chris@0 191 }
Chris@0 192
Chris@0 193 // The bright metering bit...
Chris@0 194
Chris@0 195 c = meterColor;
Chris@0 196 pen.setColor(c);
Chris@0 197 pen.setWidth(indent);
Chris@0 198 paint.setPen(pen);
Chris@0 199
Chris@0 200 // std::cerr << "degrees " << degrees << ", gives us " << -(degrees - 45) * 16 << std::endl;
Chris@0 201
Chris@0 202 int arcLen = -(degrees - 45) * 16;
Chris@0 203 if (arcLen == 0) arcLen = -16;
Chris@0 204
Chris@0 205 paint.drawArc(indent/2, indent/2,
Chris@0 206 width-indent, width-indent, (180 + 45) * 16, arcLen);
Chris@0 207
Chris@0 208 paint.setBrush(Qt::NoBrush);
Chris@0 209
Chris@0 210 // Shadowing...
Chris@0 211
Chris@0 212 pen.setWidth(scale);
Chris@0 213 paint.setPen(pen);
Chris@0 214
Chris@0 215 // Knob shadow...
Chris@0 216
Chris@0 217 int shadowAngle = -720;
Chris@0 218 c = knobColor.dark();
Chris@0 219 for (int arc = 120; arc < 2880; arc += 240) {
Chris@0 220 pen.setColor(c);
Chris@0 221 paint.setPen(pen);
Chris@0 222 paint.drawArc(indent, indent,
Chris@0 223 width-2*indent, width-2*indent, shadowAngle + arc, 240);
Chris@0 224 paint.drawArc(indent, indent,
Chris@0 225 width-2*indent, width-2*indent, shadowAngle - arc, 240);
Chris@0 226 c = c.light(110);
Chris@0 227 }
Chris@0 228
Chris@0 229 // Scale shadow...
Chris@0 230
Chris@0 231 shadowAngle = 2160;
Chris@0 232 c = palette().dark().color();
Chris@0 233 for (int arc = 120; arc < 2880; arc += 240) {
Chris@0 234 pen.setColor(c);
Chris@0 235 paint.setPen(pen);
Chris@0 236 paint.drawArc(scale/2, scale/2,
Chris@0 237 width-scale, width-scale, shadowAngle + arc, 240);
Chris@0 238 paint.drawArc(scale/2, scale/2,
Chris@0 239 width-scale, width-scale, shadowAngle - arc, 240);
Chris@0 240 c = c.light(108);
Chris@0 241 }
Chris@0 242
Chris@0 243 // Undraw the bottom part...
Chris@0 244
Chris@0 245 pen.setColor(palette().background().color());
Chris@0 246 pen.setWidth(scale * 4);
Chris@0 247 paint.setPen(pen);
Chris@0 248 paint.drawArc(scale/2, scale/2,
Chris@0 249 width-scale, width-scale, -45 * 16, -92 * 16);
Chris@0 250
Chris@0 251 // Scale ends...
Chris@0 252
Chris@0 253 pen.setColor(palette().dark().color());
Chris@0 254 pen.setWidth(scale);
Chris@0 255 paint.setPen(pen);
Chris@0 256 for (int i = 0; i < numTicks; ++i) {
Chris@0 257 if (i != 0 && i != numTicks - 1) continue;
Chris@0 258 int div = numTicks;
Chris@0 259 if (div > 1) --div;
Chris@0 260 drawTick(paint, AUDIO_DIAL_MIN + (AUDIO_DIAL_MAX - AUDIO_DIAL_MIN) * i / div,
Chris@0 261 width, false);
Chris@0 262 }
Chris@0 263
Chris@0 264 // Pointer notch...
Chris@0 265
Chris@0 266 float hyp = float(width) / 2.0;
Chris@0 267 float len = hyp - indent;
Chris@0 268 --len;
Chris@0 269
Chris@0 270 float x0 = hyp;
Chris@0 271 float y0 = hyp;
Chris@0 272
Chris@0 273 float x = hyp - len * sin(angle);
Chris@0 274 float y = hyp + len * cos(angle);
Chris@0 275
Chris@0 276 c = palette().dark().color();
Chris@0 277 pen.setColor(isEnabled() ? c.dark(130) : c);
Chris@0 278 pen.setWidth(scale * 2);
Chris@0 279 paint.setPen(pen);
Chris@0 280 paint.drawLine(int(x0), int(y0), int(x), int(y));
Chris@0 281
Chris@0 282 paint.end();
Chris@0 283 }
Chris@0 284
Chris@0 285
Chris@0 286 void AudioDial::drawTick(QPainter &paint,
Chris@0 287 float angle, int size, bool internal)
Chris@0 288 {
Chris@0 289 float hyp = float(size) / 2.0;
Chris@0 290 float x0 = hyp - (hyp - 1) * sin(angle);
Chris@0 291 float y0 = hyp + (hyp - 1) * cos(angle);
Chris@0 292
Chris@0 293 // cerr << "drawTick: angle " << angle << ", size " << size << ", internal " << internal << endl;
Chris@0 294
Chris@0 295 if (internal) {
Chris@0 296
Chris@0 297 float len = hyp / 4;
Chris@0 298 float x1 = hyp - (hyp - len) * sin(angle);
Chris@0 299 float y1 = hyp + (hyp - len) * cos(angle);
Chris@0 300
Chris@0 301 paint.drawLine(int(x0), int(y0), int(x1), int(y1));
Chris@0 302
Chris@0 303 } else {
Chris@0 304
Chris@0 305 float len = hyp / 4;
Chris@0 306 float x1 = hyp - (hyp + len) * sin(angle);
Chris@0 307 float y1 = hyp + (hyp + len) * cos(angle);
Chris@0 308
Chris@0 309 paint.drawLine(int(x0), int(y0), int(x1), int(y1));
Chris@0 310 }
Chris@0 311 }
Chris@0 312
Chris@0 313
Chris@0 314 void AudioDial::setKnobColor(const QColor& color)
Chris@0 315 {
Chris@0 316 m_knobColor = color;
Chris@0 317 update();
Chris@0 318 }
Chris@0 319
Chris@0 320
Chris@0 321 void AudioDial::setMeterColor(const QColor& color)
Chris@0 322 {
Chris@0 323 m_meterColor = color;
Chris@0 324 update();
Chris@0 325 }
Chris@0 326
Chris@0 327
Chris@0 328 void AudioDial::setMouseDial(bool mouseDial)
Chris@0 329 {
Chris@0 330 m_mouseDial = mouseDial;
Chris@0 331 }
Chris@0 332
Chris@0 333
Chris@34 334 void AudioDial::setDefaultValue(int defaultValue)
Chris@34 335 {
Chris@34 336 m_defaultValue = defaultValue;
Chris@34 337 }
Chris@34 338
Chris@34 339
Chris@219 340 void AudioDial::setValue(int value)
Chris@219 341 {
Chris@219 342 QDial::setValue(value);
Chris@219 343 updateMappedValue(value);
Chris@219 344 }
Chris@219 345
Chris@219 346
Chris@177 347 void AudioDial::setMappedValue(float mappedValue)
Chris@177 348 {
Chris@177 349 if (m_rangeMapper) {
Chris@177 350 int newPosition = m_rangeMapper->getPositionForValue(mappedValue);
Chris@190 351 bool changed = (m_mappedValue != mappedValue);
Chris@177 352 m_mappedValue = mappedValue;
Chris@177 353 m_noMappedUpdate = true;
Chris@177 354 std::cerr << "AudioDial::setMappedValue(" << mappedValue << "): new position is " << newPosition << std::endl;
Chris@177 355 if (newPosition != value()) {
Chris@177 356 setValue(newPosition);
Chris@190 357 } else if (changed) {
Chris@177 358 emit valueChanged(newPosition);
Chris@177 359 }
Chris@177 360 m_noMappedUpdate = false;
Chris@177 361 } else {
Chris@187 362 setValue(int(mappedValue));
Chris@177 363 }
Chris@177 364 }
Chris@177 365
Chris@177 366
Chris@168 367 void AudioDial::setShowToolTip(bool show)
Chris@168 368 {
Chris@168 369 m_showTooltip = show;
Chris@168 370 m_noMappedUpdate = true;
Chris@168 371 updateMappedValue(value());
Chris@168 372 m_noMappedUpdate = false;
Chris@168 373 }
Chris@168 374
Chris@168 375
Chris@167 376 float AudioDial::mappedValue() const
Chris@167 377 {
Chris@168 378 if (m_rangeMapper) {
Chris@252 379 // std::cerr << "AudioDial::mappedValue(): value = " << value() << ", mappedValue = " << m_mappedValue << std::endl;
Chris@168 380 return m_mappedValue;
Chris@168 381 }
Chris@168 382 return value();
Chris@168 383 }
Chris@168 384
Chris@168 385
Chris@168 386 void AudioDial::updateMappedValue(int value)
Chris@168 387 {
Chris@170 388 if (!m_noMappedUpdate) {
Chris@170 389 if (m_rangeMapper) {
Chris@168 390 m_mappedValue = m_rangeMapper->getValueForPosition(value);
Chris@170 391 } else {
Chris@170 392 m_mappedValue = value;
Chris@168 393 }
Chris@168 394 }
Chris@168 395
Chris@168 396 if (m_showTooltip) {
Chris@168 397 QString name = objectName();
Chris@168 398 QString unit = "";
Chris@168 399 QString text;
Chris@168 400 if (m_rangeMapper) unit = m_rangeMapper->getUnit();
Chris@168 401 if (name != "") {
Chris@168 402 text = tr("%1: %2%3").arg(name).arg(m_mappedValue).arg(unit);
Chris@168 403 } else {
Chris@168 404 text = tr("%2%3").arg(m_mappedValue).arg(unit);
Chris@168 405 }
Chris@168 406 setToolTip(text);
Chris@168 407 }
Chris@167 408 }
Chris@167 409
Chris@167 410
Chris@0 411 // Alternate mouse behavior event handlers.
Chris@0 412 void AudioDial::mousePressEvent(QMouseEvent *mouseEvent)
Chris@0 413 {
Chris@0 414 if (m_mouseDial) {
Chris@0 415 QDial::mousePressEvent(mouseEvent);
Chris@187 416 } else if (mouseEvent->button() == Qt::MidButton ||
Chris@187 417 ((mouseEvent->button() == Qt::LeftButton) &&
Chris@187 418 (mouseEvent->modifiers() & Qt::ControlModifier))) {
Chris@34 419 int dv = m_defaultValue;
Chris@34 420 if (dv < minimum()) dv = minimum();
Chris@34 421 if (dv > maximum()) dv = maximum();
Chris@34 422 setValue(m_defaultValue);
Chris@187 423 } else if (mouseEvent->button() == Qt::LeftButton) {
Chris@187 424 m_mousePressed = true;
Chris@187 425 m_posMouse = mouseEvent->pos();
Chris@34 426 }
Chris@34 427 }
Chris@34 428
Chris@34 429
Chris@34 430 void AudioDial::mouseDoubleClickEvent(QMouseEvent *mouseEvent)
Chris@34 431 {
Chris@187 432 //!!! needs a common base class with Thumbwheel
Chris@187 433
Chris@34 434 if (m_mouseDial) {
Chris@34 435 QDial::mouseDoubleClickEvent(mouseEvent);
Chris@187 436 } else if (mouseEvent->button() != Qt::LeftButton) {
Chris@187 437 return;
Chris@187 438 }
Chris@167 439
Chris@187 440 bool ok = false;
Chris@167 441
Chris@187 442 if (m_rangeMapper) {
Chris@187 443
Chris@187 444 float min = m_rangeMapper->getValueForPosition(minimum());
Chris@187 445 float max = m_rangeMapper->getValueForPosition(maximum());
Chris@187 446
Chris@187 447 if (min > max) {
Chris@187 448 float tmp = min;
Chris@187 449 min = max;
Chris@187 450 max = tmp;
Chris@187 451 }
Chris@167 452
Chris@187 453 QString unit = m_rangeMapper->getUnit();
Chris@187 454
Chris@187 455 QString text;
Chris@187 456 if (objectName() != "") {
Chris@187 457 if (unit != "") {
Chris@187 458 text = tr("New value for %1, from %2 to %3 %4:")
Chris@187 459 .arg(objectName()).arg(min).arg(max).arg(unit);
Chris@167 460 } else {
Chris@187 461 text = tr("New value for %1, from %2 to %3:")
Chris@187 462 .arg(objectName()).arg(min).arg(max);
Chris@167 463 }
Chris@187 464 } else {
Chris@187 465 if (unit != "") {
Chris@187 466 text = tr("Enter a new value from %1 to %2 %3:")
Chris@187 467 .arg(min).arg(max).arg(unit);
Chris@187 468 } else {
Chris@187 469 text = tr("Enter a new value from %1 to %2:")
Chris@187 470 .arg(min).arg(max);
Chris@168 471 }
Chris@187 472 }
Chris@187 473
Chris@187 474 float newValue = QInputDialog::getDouble
Chris@187 475 (this,
Chris@187 476 tr("Enter new value"),
Chris@187 477 text,
Chris@187 478 m_mappedValue,
Chris@187 479 min,
Chris@187 480 max,
Chris@187 481 4,
Chris@187 482 &ok);
Chris@187 483
Chris@187 484 if (ok) {
Chris@187 485 setMappedValue(newValue);
Chris@187 486 }
Chris@187 487
Chris@187 488 } else {
Chris@187 489
Chris@187 490 int newPosition = QInputDialog::getInteger
Chris@187 491 (this,
Chris@187 492 tr("Enter new value"),
Chris@187 493 tr("Enter a new value from %1 to %2:")
Chris@187 494 .arg(minimum()).arg(maximum()),
Chris@187 495 value(), minimum(), maximum(), pageStep(), &ok);
Chris@187 496
Chris@187 497 if (ok) {
Chris@187 498 setValue(newPosition);
Chris@167 499 }
Chris@0 500 }
Chris@0 501 }
Chris@0 502
Chris@0 503
Chris@0 504 void AudioDial::mouseMoveEvent(QMouseEvent *mouseEvent)
Chris@0 505 {
Chris@0 506 if (m_mouseDial) {
Chris@0 507 QDial::mouseMoveEvent(mouseEvent);
Chris@0 508 } else if (m_mousePressed) {
Chris@0 509 const QPoint& posMouse = mouseEvent->pos();
Chris@0 510 int v = QDial::value()
Chris@0 511 + (posMouse.x() - m_posMouse.x())
Chris@0 512 + (m_posMouse.y() - posMouse.y());
Chris@0 513 if (v > QDial::maximum())
Chris@0 514 v = QDial::maximum();
Chris@0 515 else
Chris@0 516 if (v < QDial::minimum())
Chris@0 517 v = QDial::minimum();
Chris@0 518 m_posMouse = posMouse;
Chris@0 519 QDial::setValue(v);
Chris@0 520 }
Chris@0 521 }
Chris@0 522
Chris@0 523
Chris@0 524 void AudioDial::mouseReleaseEvent(QMouseEvent *mouseEvent)
Chris@0 525 {
Chris@0 526 if (m_mouseDial) {
Chris@0 527 QDial::mouseReleaseEvent(mouseEvent);
Chris@0 528 } else if (m_mousePressed) {
Chris@0 529 m_mousePressed = false;
Chris@0 530 }
Chris@0 531 }
Chris@0 532
Chris@189 533 void
Chris@189 534 AudioDial::enterEvent(QEvent *e)
Chris@189 535 {
Chris@189 536 QDial::enterEvent(e);
Chris@189 537 emit mouseEntered();
Chris@189 538 }
Chris@189 539
Chris@189 540 void
Chris@189 541 AudioDial::leaveEvent(QEvent *e)
Chris@189 542 {
Chris@189 543 QDial::enterEvent(e);
Chris@189 544 emit mouseLeft();
Chris@189 545 }
Chris@189 546