annotate widgets/Panner.cpp @ 180:29f01de27db4

* Add vertical zooming and snap-to-selection for OSC control; add a demo script
author Chris Cannam
date Wed, 15 Nov 2006 18:22:26 +0000
parents 836498e57f59
children c4d407272010
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@172 7 This file copyright 2006 Chris Cannam.
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@172 24
Martin@175 25 #include <math.h>
Martin@175 26
Chris@172 27 Panner::Panner(QWidget *parent) :
Chris@172 28 QWidget(parent),
Chris@172 29 m_rectX(0),
Chris@172 30 m_rectY(0),
Chris@172 31 m_rectWidth(1),
Chris@173 32 m_rectHeight(1),
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@172 55 Panner::mousePressEvent(QMouseEvent *e)
Chris@172 56 {
Chris@173 57 if (e->button() == Qt::LeftButton) {
Chris@173 58 m_clicked = true;
Chris@173 59 m_clickPos = e->pos();
Chris@173 60 m_dragStartX = m_rectX;
Chris@173 61 m_dragStartY = m_rectY;
Chris@173 62 } else if (e->button() == Qt::MidButton) {
Chris@173 63 resetToDefault();
Chris@173 64 }
Chris@172 65 }
Chris@172 66
Chris@172 67 void
Chris@172 68 Panner::mouseDoubleClickEvent(QMouseEvent *e)
Chris@172 69 {
Chris@173 70 resetToDefault();
Chris@172 71 }
Chris@172 72
Chris@172 73 void
Chris@172 74 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@172 75 {
Chris@173 76 if (!m_clicked) return;
Chris@173 77
Chris@173 78 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
Chris@173 79 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
Chris@173 80
Chris@173 81 m_rectX = m_dragStartX + dx;
Chris@173 82 m_rectY = m_dragStartY + dy;
Chris@173 83
Chris@173 84 normalise();
Chris@174 85 repaint();
Chris@174 86 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@174 87 emit rectCentreMoved(centreX(), centreY());
Chris@172 88 }
Chris@172 89
Chris@172 90 void
Chris@172 91 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@172 92 {
Chris@173 93 if (!m_clicked) return;
Chris@173 94
Chris@173 95 mouseMoveEvent(e);
Chris@173 96 m_clicked = false;
Chris@172 97 }
Chris@172 98
Chris@172 99 void
Chris@172 100 Panner::wheelEvent(QWheelEvent *e)
Chris@172 101 {
Chris@173 102 if (e->delta() > 0) {
Chris@173 103 m_rectY += 0.1;
Chris@173 104 } else {
Chris@173 105 m_rectY -= 0.1;
Chris@173 106 }
Chris@173 107
Chris@173 108 normalise();
Chris@173 109 emitAndUpdate();
Chris@172 110 }
Chris@172 111
Chris@172 112 void
Chris@172 113 Panner::paintEvent(QPaintEvent *e)
Chris@172 114 {
Chris@172 115 QPainter paint(this);
Chris@172 116 paint.setRenderHint(QPainter::Antialiasing, false);
Chris@173 117
Chris@173 118 QColor bg(palette().background().color());
Chris@174 119 bg.setAlpha(m_backgroundAlpha);
Chris@173 120
Chris@172 121 paint.setPen(palette().dark().color());
Chris@173 122 paint.setBrush(bg);
Chris@173 123 paint.drawRect(0, 0, width(), height());
Chris@173 124
Chris@174 125 QColor hl(m_thumbColour);
Chris@174 126 hl.setAlpha(m_thumbAlpha);
Chris@173 127
Chris@173 128 paint.setBrush(hl);
Chris@173 129
Chris@173 130 paint.drawRect(lrintf(width() * m_rectX),
Chris@173 131 lrintf(height() * m_rectY),
Chris@173 132 lrintf(width() * m_rectWidth),
Chris@173 133 lrintf(height() * m_rectHeight));
Chris@172 134 }
Chris@172 135
Chris@172 136 void
Chris@172 137 Panner::normalise()
Chris@172 138 {
Chris@172 139 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
Chris@172 140 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
Chris@172 141 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
Chris@172 142 if (m_rectX < 0) m_rectX = 0;
Chris@172 143 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
Chris@172 144 if (m_rectY < 0) m_rectY = 0;
Chris@173 145
Chris@173 146 if (!m_defaultsSet) {
Chris@173 147 m_defaultCentreX = centreX();
Chris@173 148 m_defaultCentreY = centreY();
Chris@173 149 m_defaultsSet = true;
Chris@173 150 }
Chris@172 151 }
Chris@172 152
Chris@172 153 void
Chris@172 154 Panner::emitAndUpdate()
Chris@172 155 {
Chris@172 156 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@173 157 emit rectCentreMoved(centreX(), centreY());
Chris@172 158 update();
Chris@172 159 }
Chris@172 160
Chris@172 161 void
Chris@172 162 Panner::setRectExtents(float x0, float y0, float width, float height)
Chris@172 163 {
Chris@174 164 std::cerr << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
Chris@174 165 << width << ", " << height << ")" << std::endl;
Chris@174 166
Chris@172 167 if (m_rectX == x0 &&
Chris@172 168 m_rectY == y0 &&
Chris@172 169 m_rectWidth == width &&
Chris@172 170 m_rectHeight == height) {
Chris@172 171 return;
Chris@172 172 }
Chris@173 173
Chris@172 174 m_rectX = x0;
Chris@172 175 m_rectY = y0;
Chris@172 176 m_rectWidth = width;
Chris@172 177 m_rectHeight = height;
Chris@173 178
Chris@172 179 normalise();
Chris@172 180 emitAndUpdate();
Chris@172 181 }
Chris@172 182
Chris@172 183 void
Chris@172 184 Panner::setRectWidth(float width)
Chris@172 185 {
Chris@172 186 if (m_rectWidth == width) return;
Chris@172 187 m_rectWidth = width;
Chris@172 188 normalise();
Chris@172 189 emitAndUpdate();
Chris@172 190 }
Chris@172 191
Chris@172 192 void
Chris@172 193 Panner::setRectHeight(float height)
Chris@172 194 {
Chris@172 195 if (m_rectHeight == height) return;
Chris@172 196 m_rectHeight = height;
Chris@172 197 normalise();
Chris@172 198 emitAndUpdate();
Chris@172 199 }
Chris@172 200
Chris@172 201 void
Chris@172 202 Panner::setRectCentreX(float x)
Chris@172 203 {
Chris@172 204 float x0 = x - m_rectWidth/2;
Chris@172 205 if (x0 == m_rectX) return;
Chris@172 206 m_rectX = x0;
Chris@172 207 normalise();
Chris@172 208 emitAndUpdate();
Chris@172 209 }
Chris@172 210
Chris@172 211 void
Chris@172 212 Panner::setRectCentreY(float y)
Chris@172 213 {
Chris@173 214 float y0 = y - m_rectHeight/2;
Chris@172 215 if (y0 == m_rectY) return;
Chris@172 216 m_rectY = y0;
Chris@172 217 normalise();
Chris@172 218 emitAndUpdate();
Chris@172 219 }
Chris@172 220
Chris@172 221 QSize
Chris@172 222 Panner::sizeHint() const
Chris@172 223 {
Chris@172 224 return QSize(30, 30);
Chris@172 225 }
Chris@172 226
Chris@173 227 void
Chris@173 228 Panner::setDefaultRectCentre(float cx, float cy)
Chris@173 229 {
Chris@173 230 m_defaultCentreX = cx;
Chris@173 231 m_defaultCentreY = cy;
Chris@173 232 m_defaultsSet = true;
Chris@173 233 }
Chris@172 234
Chris@173 235 void
Chris@173 236 Panner::resetToDefault()
Chris@173 237 {
Chris@173 238 float x0 = m_defaultCentreX - m_rectWidth/2;
Chris@173 239 float y0 = m_defaultCentreY - m_rectHeight/2;
Chris@173 240 if (x0 == m_rectX && y0 == m_rectY) return;
Chris@173 241 m_rectX = x0;
Chris@173 242 m_rectY = y0;
Chris@173 243 normalise();
Chris@173 244 emitAndUpdate();
Chris@173 245 }
Chris@172 246
Chris@173 247