annotate widgets/Panner.cpp @ 1269:f2894944c6b8

Make the overlays at either end translucent, so they don't completely crop out any underlying text or necessary info (e.g. selection extents)
author Chris Cannam
date Thu, 19 Apr 2018 14:35:59 +0100
parents 4d0ca1ab4cd0
children 13f5f84fbfad
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@1238 23 #include "WidgetScale.h"
Chris@1238 24
Chris@172 25 #include <iostream>
Chris@181 26 #include <cmath>
Martin@175 27
Chris@172 28 Panner::Panner(QWidget *parent) :
Chris@172 29 QWidget(parent),
Chris@172 30 m_rectX(0),
Chris@172 31 m_rectY(0),
Chris@172 32 m_rectWidth(1),
Chris@173 33 m_rectHeight(1),
Chris@256 34 m_scrollUnit(0),
Chris@173 35 m_defaultCentreX(0),
Chris@173 36 m_defaultCentreY(0),
Chris@173 37 m_defaultsSet(false),
Chris@174 38 m_thumbColour(palette().highlightedText().color()),
Chris@174 39 m_backgroundAlpha(255),
Chris@174 40 m_thumbAlpha(255),
Chris@858 41 m_clicked(false),
Chris@858 42 m_dragStartX(0),
Chris@858 43 m_dragStartY(0)
Chris@172 44 {
Chris@172 45 }
Chris@172 46
Chris@172 47 Panner::~Panner()
Chris@172 48 {
Chris@172 49 }
Chris@172 50
Chris@172 51 void
Chris@174 52 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
Chris@174 53 {
Chris@174 54 m_backgroundAlpha = backgroundAlpha;
Chris@174 55 m_thumbAlpha = thumbAlpha;
Chris@174 56 }
Chris@174 57
Chris@174 58 void
Chris@256 59 Panner::setScrollUnit(float unit)
Chris@256 60 {
Chris@256 61 m_scrollUnit = unit;
Chris@256 62 }
Chris@256 63
Chris@256 64 void
Chris@256 65 Panner::scroll(bool up)
Chris@256 66 {
Chris@256 67 float unit = m_scrollUnit;
Chris@256 68 if (unit == 0.f) {
Chris@256 69 unit = float(m_rectHeight) / (6 * float(height()));
Chris@908 70 if (unit < 0.01f) unit = 0.01f;
Chris@256 71 }
Chris@256 72
Chris@256 73 if (!up) {
Chris@256 74 m_rectY += unit;
Chris@256 75 } else {
Chris@256 76 m_rectY -= unit;
Chris@256 77 }
Chris@256 78
Chris@256 79 normalise();
Chris@256 80 emitAndUpdate();
Chris@256 81 }
Chris@256 82
Chris@256 83 void
Chris@172 84 Panner::mousePressEvent(QMouseEvent *e)
Chris@172 85 {
Chris@188 86 if (e->button() == Qt::MidButton ||
Chris@188 87 ((e->button() == Qt::LeftButton) &&
Chris@188 88 (e->modifiers() & Qt::ControlModifier))) {
Chris@188 89 resetToDefault();
Chris@188 90 } else if (e->button() == Qt::LeftButton) {
Chris@173 91 m_clicked = true;
Chris@173 92 m_clickPos = e->pos();
Chris@173 93 m_dragStartX = m_rectX;
Chris@173 94 m_dragStartY = m_rectY;
Chris@173 95 }
Chris@172 96 }
Chris@172 97
Chris@172 98 void
Chris@172 99 Panner::mouseDoubleClickEvent(QMouseEvent *e)
Chris@172 100 {
Chris@188 101 if (e->button() != Qt::LeftButton) {
Chris@188 102 return;
Chris@188 103 }
Chris@188 104
Chris@188 105 emit doubleClicked();
Chris@172 106 }
Chris@172 107
Chris@172 108 void
Chris@172 109 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@172 110 {
Chris@173 111 if (!m_clicked) return;
Chris@173 112
Chris@173 113 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
Chris@173 114 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
Chris@173 115
Chris@173 116 m_rectX = m_dragStartX + dx;
Chris@173 117 m_rectY = m_dragStartY + dy;
Chris@173 118
Chris@173 119 normalise();
Chris@174 120 repaint();
Chris@174 121 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@174 122 emit rectCentreMoved(centreX(), centreY());
Chris@172 123 }
Chris@172 124
Chris@172 125 void
Chris@172 126 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@172 127 {
Chris@173 128 if (!m_clicked) return;
Chris@173 129
Chris@173 130 mouseMoveEvent(e);
Chris@173 131 m_clicked = false;
Chris@172 132 }
Chris@172 133
Chris@172 134 void
Chris@172 135 Panner::wheelEvent(QWheelEvent *e)
Chris@172 136 {
Chris@256 137 scroll(e->delta() > 0);
Chris@172 138 }
Chris@172 139
Chris@172 140 void
Chris@189 141 Panner::enterEvent(QEvent *)
Chris@189 142 {
Chris@189 143 emit mouseEntered();
Chris@189 144 }
Chris@189 145
Chris@189 146 void
Chris@189 147 Panner::leaveEvent(QEvent *)
Chris@189 148 {
Chris@189 149 emit mouseLeft();
Chris@189 150 }
Chris@189 151
Chris@189 152 void
Chris@249 153 Panner::paintEvent(QPaintEvent *)
Chris@172 154 {
Chris@172 155 QPainter paint(this);
Chris@172 156 paint.setRenderHint(QPainter::Antialiasing, false);
Chris@173 157
Chris@173 158 QColor bg(palette().background().color());
Chris@174 159 bg.setAlpha(m_backgroundAlpha);
Chris@173 160
Chris@1238 161 int penWidth = WidgetScale::scalePixelSize(1);
Chris@1238 162 if (penWidth < 1) penWidth = 1;
Chris@1238 163 paint.setPen(QPen(palette().dark().color(), penWidth));
Chris@1238 164
Chris@173 165 paint.setBrush(bg);
Chris@1238 166 paint.drawRect(penWidth/2, penWidth/2,
Chris@1238 167 width()-penWidth/2-1, height()-penWidth/2-1);
Chris@173 168
Chris@174 169 QColor hl(m_thumbColour);
Chris@174 170 hl.setAlpha(m_thumbAlpha);
Chris@173 171
Chris@173 172 paint.setBrush(hl);
Chris@173 173
Chris@908 174 int rw = int(lrintf(float(width() - 1) * m_rectWidth));
Chris@908 175 int rh = int(lrintf(float(height() - 1) * m_rectHeight));
Chris@437 176 if (rw < 2) rw = 2;
Chris@437 177 if (rh < 2) rh = 2;
Chris@437 178
Chris@908 179 paint.drawRect(int(lrintf(float(width()) * m_rectX)),
Chris@908 180 int(lrintf(float(height()) * m_rectY)),
Chris@437 181 rw, rh);
Chris@172 182 }
Chris@172 183
Chris@172 184 void
Chris@172 185 Panner::normalise()
Chris@172 186 {
Chris@908 187 if (m_rectWidth > 1.f) m_rectWidth = 1.f;
Chris@908 188 if (m_rectHeight > 1.f) m_rectHeight = 1.f;
Chris@908 189 if (m_rectX + m_rectWidth > 1.f) m_rectX = 1.f - m_rectWidth;
Chris@172 190 if (m_rectX < 0) m_rectX = 0;
Chris@908 191 if (m_rectY + m_rectHeight > 1.f) m_rectY = 1.f - m_rectHeight;
Chris@172 192 if (m_rectY < 0) m_rectY = 0;
Chris@173 193
Chris@173 194 if (!m_defaultsSet) {
Chris@173 195 m_defaultCentreX = centreX();
Chris@173 196 m_defaultCentreY = centreY();
Chris@173 197 m_defaultsSet = true;
Chris@173 198 }
Chris@172 199 }
Chris@172 200
Chris@172 201 void
Chris@172 202 Panner::emitAndUpdate()
Chris@172 203 {
Chris@172 204 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@173 205 emit rectCentreMoved(centreX(), centreY());
Chris@172 206 update();
Chris@172 207 }
Chris@172 208
Chris@172 209 void
Chris@188 210 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
Chris@188 211 {
Chris@188 212 x0 = m_rectX;
Chris@188 213 y0 = m_rectY;
Chris@188 214 width = m_rectWidth;
Chris@188 215 height = m_rectHeight;
Chris@188 216 }
Chris@188 217
Chris@188 218 void
Chris@172 219 Panner::setRectExtents(float x0, float y0, float width, float height)
Chris@172 220 {
Chris@587 221 // SVDEBUG << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
Chris@585 222 // << width << ", " << height << ")" << endl;
Chris@174 223
Chris@172 224 if (m_rectX == x0 &&
Chris@172 225 m_rectY == y0 &&
Chris@172 226 m_rectWidth == width &&
Chris@172 227 m_rectHeight == height) {
Chris@172 228 return;
Chris@172 229 }
Chris@173 230
Chris@172 231 m_rectX = x0;
Chris@172 232 m_rectY = y0;
Chris@172 233 m_rectWidth = width;
Chris@172 234 m_rectHeight = height;
Chris@173 235
Chris@172 236 normalise();
Chris@172 237 emitAndUpdate();
Chris@172 238 }
Chris@172 239
Chris@172 240 void
Chris@172 241 Panner::setRectWidth(float width)
Chris@172 242 {
Chris@172 243 if (m_rectWidth == width) return;
Chris@172 244 m_rectWidth = width;
Chris@172 245 normalise();
Chris@172 246 emitAndUpdate();
Chris@172 247 }
Chris@172 248
Chris@172 249 void
Chris@172 250 Panner::setRectHeight(float height)
Chris@172 251 {
Chris@172 252 if (m_rectHeight == height) return;
Chris@172 253 m_rectHeight = height;
Chris@172 254 normalise();
Chris@172 255 emitAndUpdate();
Chris@172 256 }
Chris@172 257
Chris@172 258 void
Chris@172 259 Panner::setRectCentreX(float x)
Chris@172 260 {
Chris@172 261 float x0 = x - m_rectWidth/2;
Chris@172 262 if (x0 == m_rectX) return;
Chris@172 263 m_rectX = x0;
Chris@172 264 normalise();
Chris@172 265 emitAndUpdate();
Chris@172 266 }
Chris@172 267
Chris@172 268 void
Chris@172 269 Panner::setRectCentreY(float y)
Chris@172 270 {
Chris@173 271 float y0 = y - m_rectHeight/2;
Chris@172 272 if (y0 == m_rectY) return;
Chris@172 273 m_rectY = y0;
Chris@172 274 normalise();
Chris@172 275 emitAndUpdate();
Chris@172 276 }
Chris@172 277
Chris@172 278 QSize
Chris@172 279 Panner::sizeHint() const
Chris@172 280 {
Chris@172 281 return QSize(30, 30);
Chris@172 282 }
Chris@172 283
Chris@173 284 void
Chris@173 285 Panner::setDefaultRectCentre(float cx, float cy)
Chris@173 286 {
Chris@173 287 m_defaultCentreX = cx;
Chris@173 288 m_defaultCentreY = cy;
Chris@173 289 m_defaultsSet = true;
Chris@173 290 }
Chris@172 291
Chris@173 292 void
Chris@173 293 Panner::resetToDefault()
Chris@173 294 {
Chris@173 295 float x0 = m_defaultCentreX - m_rectWidth/2;
Chris@173 296 float y0 = m_defaultCentreY - m_rectHeight/2;
Chris@173 297 if (x0 == m_rectX && y0 == m_rectY) return;
Chris@173 298 m_rectX = x0;
Chris@173 299 m_rectY = y0;
Chris@173 300 normalise();
Chris@173 301 emitAndUpdate();
Chris@173 302 }
Chris@172 303
Chris@173 304