annotate widgets/Panner.cpp @ 738:d26545a2a02d tonioni

Rather than undrawing the bottom bit of the dial, don't draw it in the first place (necessary on shaded background)
author Chris Cannam
date Thu, 06 Mar 2014 13:52:33 +0000
parents 4806715f7a19
children ae4f58d9db84
rev   line source
Chris@172 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@172 2
Chris@172 3 /*
Chris@172 4 Sonic Visualiser
Chris@172 5 An audio file viewer and annotation editor.
Chris@172 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 QMUL.
Chris@172 8
Chris@172 9 This program is free software; you can redistribute it and/or
Chris@172 10 modify it under the terms of the GNU General Public License as
Chris@172 11 published by the Free Software Foundation; either version 2 of the
Chris@172 12 License, or (at your option) any later version. See the file
Chris@172 13 COPYING included with this distribution for more information.
Chris@172 14 */
Chris@172 15
Chris@172 16 #include "Panner.h"
Chris@172 17
Chris@172 18 #include <QMouseEvent>
Chris@172 19 #include <QPaintEvent>
Chris@172 20 #include <QWheelEvent>
Chris@172 21 #include <QPainter>
Chris@172 22
Chris@172 23 #include <iostream>
Chris@181 24 #include <cmath>
Martin@175 25
Chris@172 26 Panner::Panner(QWidget *parent) :
Chris@172 27 QWidget(parent),
Chris@172 28 m_rectX(0),
Chris@172 29 m_rectY(0),
Chris@172 30 m_rectWidth(1),
Chris@173 31 m_rectHeight(1),
Chris@256 32 m_scrollUnit(0),
Chris@173 33 m_defaultCentreX(0),
Chris@173 34 m_defaultCentreY(0),
Chris@173 35 m_defaultsSet(false),
Chris@174 36 m_thumbColour(palette().highlightedText().color()),
Chris@174 37 m_backgroundAlpha(255),
Chris@174 38 m_thumbAlpha(255),
Chris@173 39 m_clicked(false)
Chris@172 40 {
Chris@172 41 }
Chris@172 42
Chris@172 43 Panner::~Panner()
Chris@172 44 {
Chris@172 45 }
Chris@172 46
Chris@172 47 void
Chris@174 48 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
Chris@174 49 {
Chris@174 50 m_backgroundAlpha = backgroundAlpha;
Chris@174 51 m_thumbAlpha = thumbAlpha;
Chris@174 52 }
Chris@174 53
Chris@174 54 void
Chris@256 55 Panner::setScrollUnit(float unit)
Chris@256 56 {
Chris@256 57 m_scrollUnit = unit;
Chris@256 58 }
Chris@256 59
Chris@256 60 void
Chris@256 61 Panner::scroll(bool up)
Chris@256 62 {
Chris@256 63 float unit = m_scrollUnit;
Chris@256 64 if (unit == 0.f) {
Chris@256 65 unit = float(m_rectHeight) / (6 * float(height()));
Chris@256 66 if (unit < 0.01) unit = 0.01;
Chris@256 67 }
Chris@256 68
Chris@256 69 if (!up) {
Chris@256 70 m_rectY += unit;
Chris@256 71 } else {
Chris@256 72 m_rectY -= unit;
Chris@256 73 }
Chris@256 74
Chris@256 75 normalise();
Chris@256 76 emitAndUpdate();
Chris@256 77 }
Chris@256 78
Chris@256 79 void
Chris@172 80 Panner::mousePressEvent(QMouseEvent *e)
Chris@172 81 {
Chris@188 82 if (e->button() == Qt::MidButton ||
Chris@188 83 ((e->button() == Qt::LeftButton) &&
Chris@188 84 (e->modifiers() & Qt::ControlModifier))) {
Chris@188 85 resetToDefault();
Chris@188 86 } else if (e->button() == Qt::LeftButton) {
Chris@173 87 m_clicked = true;
Chris@173 88 m_clickPos = e->pos();
Chris@173 89 m_dragStartX = m_rectX;
Chris@173 90 m_dragStartY = m_rectY;
Chris@173 91 }
Chris@172 92 }
Chris@172 93
Chris@172 94 void
Chris@172 95 Panner::mouseDoubleClickEvent(QMouseEvent *e)
Chris@172 96 {
Chris@188 97 if (e->button() != Qt::LeftButton) {
Chris@188 98 return;
Chris@188 99 }
Chris@188 100
Chris@188 101 emit doubleClicked();
Chris@172 102 }
Chris@172 103
Chris@172 104 void
Chris@172 105 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@172 106 {
Chris@173 107 if (!m_clicked) return;
Chris@173 108
Chris@173 109 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
Chris@173 110 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
Chris@173 111
Chris@173 112 m_rectX = m_dragStartX + dx;
Chris@173 113 m_rectY = m_dragStartY + dy;
Chris@173 114
Chris@173 115 normalise();
Chris@174 116 repaint();
Chris@174 117 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@174 118 emit rectCentreMoved(centreX(), centreY());
Chris@172 119 }
Chris@172 120
Chris@172 121 void
Chris@172 122 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@172 123 {
Chris@173 124 if (!m_clicked) return;
Chris@173 125
Chris@173 126 mouseMoveEvent(e);
Chris@173 127 m_clicked = false;
Chris@172 128 }
Chris@172 129
Chris@172 130 void
Chris@172 131 Panner::wheelEvent(QWheelEvent *e)
Chris@172 132 {
Chris@256 133 scroll(e->delta() > 0);
Chris@172 134 }
Chris@172 135
Chris@172 136 void
Chris@189 137 Panner::enterEvent(QEvent *)
Chris@189 138 {
Chris@189 139 emit mouseEntered();
Chris@189 140 }
Chris@189 141
Chris@189 142 void
Chris@189 143 Panner::leaveEvent(QEvent *)
Chris@189 144 {
Chris@189 145 emit mouseLeft();
Chris@189 146 }
Chris@189 147
Chris@189 148 void
Chris@249 149 Panner::paintEvent(QPaintEvent *)
Chris@172 150 {
Chris@172 151 QPainter paint(this);
Chris@172 152 paint.setRenderHint(QPainter::Antialiasing, false);
Chris@173 153
Chris@173 154 QColor bg(palette().background().color());
Chris@174 155 bg.setAlpha(m_backgroundAlpha);
Chris@173 156
Chris@172 157 paint.setPen(palette().dark().color());
Chris@173 158 paint.setBrush(bg);
Chris@438 159 paint.drawRect(0, 0, width()-1, height()-1);
Chris@173 160
Chris@174 161 QColor hl(m_thumbColour);
Chris@174 162 hl.setAlpha(m_thumbAlpha);
Chris@173 163
Chris@173 164 paint.setBrush(hl);
Chris@173 165
Chris@438 166 int rw = lrintf((width() - 1) * m_rectWidth);
Chris@438 167 int rh = lrintf((height() - 1) * m_rectHeight);
Chris@437 168 if (rw < 2) rw = 2;
Chris@437 169 if (rh < 2) rh = 2;
Chris@437 170
Chris@173 171 paint.drawRect(lrintf(width() * m_rectX),
Chris@173 172 lrintf(height() * m_rectY),
Chris@437 173 rw, rh);
Chris@172 174 }
Chris@172 175
Chris@172 176 void
Chris@172 177 Panner::normalise()
Chris@172 178 {
Chris@172 179 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
Chris@172 180 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
Chris@172 181 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
Chris@172 182 if (m_rectX < 0) m_rectX = 0;
Chris@172 183 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
Chris@172 184 if (m_rectY < 0) m_rectY = 0;
Chris@173 185
Chris@173 186 if (!m_defaultsSet) {
Chris@173 187 m_defaultCentreX = centreX();
Chris@173 188 m_defaultCentreY = centreY();
Chris@173 189 m_defaultsSet = true;
Chris@173 190 }
Chris@172 191 }
Chris@172 192
Chris@172 193 void
Chris@172 194 Panner::emitAndUpdate()
Chris@172 195 {
Chris@172 196 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@173 197 emit rectCentreMoved(centreX(), centreY());
Chris@172 198 update();
Chris@172 199 }
Chris@172 200
Chris@172 201 void
Chris@188 202 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
Chris@188 203 {
Chris@188 204 x0 = m_rectX;
Chris@188 205 y0 = m_rectY;
Chris@188 206 width = m_rectWidth;
Chris@188 207 height = m_rectHeight;
Chris@188 208 }
Chris@188 209
Chris@188 210 void
Chris@172 211 Panner::setRectExtents(float x0, float y0, float width, float height)
Chris@172 212 {
Chris@587 213 // SVDEBUG << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
Chris@585 214 // << width << ", " << height << ")" << endl;
Chris@174 215
Chris@172 216 if (m_rectX == x0 &&
Chris@172 217 m_rectY == y0 &&
Chris@172 218 m_rectWidth == width &&
Chris@172 219 m_rectHeight == height) {
Chris@172 220 return;
Chris@172 221 }
Chris@173 222
Chris@172 223 m_rectX = x0;
Chris@172 224 m_rectY = y0;
Chris@172 225 m_rectWidth = width;
Chris@172 226 m_rectHeight = height;
Chris@173 227
Chris@172 228 normalise();
Chris@172 229 emitAndUpdate();
Chris@172 230 }
Chris@172 231
Chris@172 232 void
Chris@172 233 Panner::setRectWidth(float width)
Chris@172 234 {
Chris@172 235 if (m_rectWidth == width) return;
Chris@172 236 m_rectWidth = width;
Chris@172 237 normalise();
Chris@172 238 emitAndUpdate();
Chris@172 239 }
Chris@172 240
Chris@172 241 void
Chris@172 242 Panner::setRectHeight(float height)
Chris@172 243 {
Chris@172 244 if (m_rectHeight == height) return;
Chris@172 245 m_rectHeight = height;
Chris@172 246 normalise();
Chris@172 247 emitAndUpdate();
Chris@172 248 }
Chris@172 249
Chris@172 250 void
Chris@172 251 Panner::setRectCentreX(float x)
Chris@172 252 {
Chris@172 253 float x0 = x - m_rectWidth/2;
Chris@172 254 if (x0 == m_rectX) return;
Chris@172 255 m_rectX = x0;
Chris@172 256 normalise();
Chris@172 257 emitAndUpdate();
Chris@172 258 }
Chris@172 259
Chris@172 260 void
Chris@172 261 Panner::setRectCentreY(float y)
Chris@172 262 {
Chris@173 263 float y0 = y - m_rectHeight/2;
Chris@172 264 if (y0 == m_rectY) return;
Chris@172 265 m_rectY = y0;
Chris@172 266 normalise();
Chris@172 267 emitAndUpdate();
Chris@172 268 }
Chris@172 269
Chris@172 270 QSize
Chris@172 271 Panner::sizeHint() const
Chris@172 272 {
Chris@172 273 return QSize(30, 30);
Chris@172 274 }
Chris@172 275
Chris@173 276 void
Chris@173 277 Panner::setDefaultRectCentre(float cx, float cy)
Chris@173 278 {
Chris@173 279 m_defaultCentreX = cx;
Chris@173 280 m_defaultCentreY = cy;
Chris@173 281 m_defaultsSet = true;
Chris@173 282 }
Chris@172 283
Chris@173 284 void
Chris@173 285 Panner::resetToDefault()
Chris@173 286 {
Chris@173 287 float x0 = m_defaultCentreX - m_rectWidth/2;
Chris@173 288 float y0 = m_defaultCentreY - m_rectHeight/2;
Chris@173 289 if (x0 == m_rectX && y0 == m_rectY) return;
Chris@173 290 m_rectX = x0;
Chris@173 291 m_rectY = y0;
Chris@173 292 normalise();
Chris@173 293 emitAndUpdate();
Chris@173 294 }
Chris@172 295
Chris@173 296