annotate widgets/Panner.cpp @ 190:53835534a9d3

* Allow user to activate a pane by clicking on the tab for its currently active layer. Formerly nothing happened if you clicked on the tab that was already topmost in a given property stack, because the tab widget only emitted a signal if the current tab changed. We want this to switch focus back to the pane if another one has been active in the mean time. * Make the thumbwheels look a bit round.
author Chris Cannam
date Mon, 22 Jan 2007 15:42:00 +0000
parents 5b7472db612b
children 57c2350a8c40
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@173 32 m_defaultCentreX(0),
Chris@173 33 m_defaultCentreY(0),
Chris@173 34 m_defaultsSet(false),
Chris@174 35 m_thumbColour(palette().highlightedText().color()),
Chris@174 36 m_backgroundAlpha(255),
Chris@174 37 m_thumbAlpha(255),
Chris@173 38 m_clicked(false)
Chris@172 39 {
Chris@172 40 }
Chris@172 41
Chris@172 42 Panner::~Panner()
Chris@172 43 {
Chris@172 44 }
Chris@172 45
Chris@172 46 void
Chris@174 47 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
Chris@174 48 {
Chris@174 49 m_backgroundAlpha = backgroundAlpha;
Chris@174 50 m_thumbAlpha = thumbAlpha;
Chris@174 51 }
Chris@174 52
Chris@174 53 void
Chris@172 54 Panner::mousePressEvent(QMouseEvent *e)
Chris@172 55 {
Chris@188 56 if (e->button() == Qt::MidButton ||
Chris@188 57 ((e->button() == Qt::LeftButton) &&
Chris@188 58 (e->modifiers() & Qt::ControlModifier))) {
Chris@188 59 resetToDefault();
Chris@188 60 } else if (e->button() == Qt::LeftButton) {
Chris@173 61 m_clicked = true;
Chris@173 62 m_clickPos = e->pos();
Chris@173 63 m_dragStartX = m_rectX;
Chris@173 64 m_dragStartY = m_rectY;
Chris@173 65 }
Chris@172 66 }
Chris@172 67
Chris@172 68 void
Chris@172 69 Panner::mouseDoubleClickEvent(QMouseEvent *e)
Chris@172 70 {
Chris@188 71 if (e->button() != Qt::LeftButton) {
Chris@188 72 return;
Chris@188 73 }
Chris@188 74
Chris@188 75 emit doubleClicked();
Chris@172 76 }
Chris@172 77
Chris@172 78 void
Chris@172 79 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@172 80 {
Chris@173 81 if (!m_clicked) return;
Chris@173 82
Chris@173 83 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
Chris@173 84 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
Chris@173 85
Chris@173 86 m_rectX = m_dragStartX + dx;
Chris@173 87 m_rectY = m_dragStartY + dy;
Chris@173 88
Chris@173 89 normalise();
Chris@174 90 repaint();
Chris@174 91 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@174 92 emit rectCentreMoved(centreX(), centreY());
Chris@172 93 }
Chris@172 94
Chris@172 95 void
Chris@172 96 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@172 97 {
Chris@173 98 if (!m_clicked) return;
Chris@173 99
Chris@173 100 mouseMoveEvent(e);
Chris@173 101 m_clicked = false;
Chris@172 102 }
Chris@172 103
Chris@172 104 void
Chris@172 105 Panner::wheelEvent(QWheelEvent *e)
Chris@172 106 {
Chris@173 107 if (e->delta() > 0) {
Chris@173 108 m_rectY += 0.1;
Chris@173 109 } else {
Chris@173 110 m_rectY -= 0.1;
Chris@173 111 }
Chris@173 112
Chris@173 113 normalise();
Chris@173 114 emitAndUpdate();
Chris@172 115 }
Chris@172 116
Chris@172 117 void
Chris@189 118 Panner::enterEvent(QEvent *)
Chris@189 119 {
Chris@189 120 emit mouseEntered();
Chris@189 121 }
Chris@189 122
Chris@189 123 void
Chris@189 124 Panner::leaveEvent(QEvent *)
Chris@189 125 {
Chris@189 126 emit mouseLeft();
Chris@189 127 }
Chris@189 128
Chris@189 129 void
Chris@172 130 Panner::paintEvent(QPaintEvent *e)
Chris@172 131 {
Chris@172 132 QPainter paint(this);
Chris@172 133 paint.setRenderHint(QPainter::Antialiasing, false);
Chris@173 134
Chris@173 135 QColor bg(palette().background().color());
Chris@174 136 bg.setAlpha(m_backgroundAlpha);
Chris@173 137
Chris@172 138 paint.setPen(palette().dark().color());
Chris@173 139 paint.setBrush(bg);
Chris@173 140 paint.drawRect(0, 0, width(), height());
Chris@173 141
Chris@174 142 QColor hl(m_thumbColour);
Chris@174 143 hl.setAlpha(m_thumbAlpha);
Chris@173 144
Chris@173 145 paint.setBrush(hl);
Chris@173 146
Chris@173 147 paint.drawRect(lrintf(width() * m_rectX),
Chris@173 148 lrintf(height() * m_rectY),
Chris@173 149 lrintf(width() * m_rectWidth),
Chris@173 150 lrintf(height() * m_rectHeight));
Chris@172 151 }
Chris@172 152
Chris@172 153 void
Chris@172 154 Panner::normalise()
Chris@172 155 {
Chris@172 156 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
Chris@172 157 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
Chris@172 158 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
Chris@172 159 if (m_rectX < 0) m_rectX = 0;
Chris@172 160 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
Chris@172 161 if (m_rectY < 0) m_rectY = 0;
Chris@173 162
Chris@173 163 if (!m_defaultsSet) {
Chris@173 164 m_defaultCentreX = centreX();
Chris@173 165 m_defaultCentreY = centreY();
Chris@173 166 m_defaultsSet = true;
Chris@173 167 }
Chris@172 168 }
Chris@172 169
Chris@172 170 void
Chris@172 171 Panner::emitAndUpdate()
Chris@172 172 {
Chris@172 173 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
Chris@173 174 emit rectCentreMoved(centreX(), centreY());
Chris@172 175 update();
Chris@172 176 }
Chris@172 177
Chris@172 178 void
Chris@188 179 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
Chris@188 180 {
Chris@188 181 x0 = m_rectX;
Chris@188 182 y0 = m_rectY;
Chris@188 183 width = m_rectWidth;
Chris@188 184 height = m_rectHeight;
Chris@188 185 }
Chris@188 186
Chris@188 187 void
Chris@172 188 Panner::setRectExtents(float x0, float y0, float width, float height)
Chris@172 189 {
Chris@174 190 std::cerr << "Panner::setRectExtents(" << x0 << ", " << y0 << ", "
Chris@174 191 << width << ", " << height << ")" << std::endl;
Chris@174 192
Chris@172 193 if (m_rectX == x0 &&
Chris@172 194 m_rectY == y0 &&
Chris@172 195 m_rectWidth == width &&
Chris@172 196 m_rectHeight == height) {
Chris@172 197 return;
Chris@172 198 }
Chris@173 199
Chris@172 200 m_rectX = x0;
Chris@172 201 m_rectY = y0;
Chris@172 202 m_rectWidth = width;
Chris@172 203 m_rectHeight = height;
Chris@173 204
Chris@172 205 normalise();
Chris@172 206 emitAndUpdate();
Chris@172 207 }
Chris@172 208
Chris@172 209 void
Chris@172 210 Panner::setRectWidth(float width)
Chris@172 211 {
Chris@172 212 if (m_rectWidth == width) return;
Chris@172 213 m_rectWidth = width;
Chris@172 214 normalise();
Chris@172 215 emitAndUpdate();
Chris@172 216 }
Chris@172 217
Chris@172 218 void
Chris@172 219 Panner::setRectHeight(float height)
Chris@172 220 {
Chris@172 221 if (m_rectHeight == height) return;
Chris@172 222 m_rectHeight = height;
Chris@172 223 normalise();
Chris@172 224 emitAndUpdate();
Chris@172 225 }
Chris@172 226
Chris@172 227 void
Chris@172 228 Panner::setRectCentreX(float x)
Chris@172 229 {
Chris@172 230 float x0 = x - m_rectWidth/2;
Chris@172 231 if (x0 == m_rectX) return;
Chris@172 232 m_rectX = x0;
Chris@172 233 normalise();
Chris@172 234 emitAndUpdate();
Chris@172 235 }
Chris@172 236
Chris@172 237 void
Chris@172 238 Panner::setRectCentreY(float y)
Chris@172 239 {
Chris@173 240 float y0 = y - m_rectHeight/2;
Chris@172 241 if (y0 == m_rectY) return;
Chris@172 242 m_rectY = y0;
Chris@172 243 normalise();
Chris@172 244 emitAndUpdate();
Chris@172 245 }
Chris@172 246
Chris@172 247 QSize
Chris@172 248 Panner::sizeHint() const
Chris@172 249 {
Chris@172 250 return QSize(30, 30);
Chris@172 251 }
Chris@172 252
Chris@173 253 void
Chris@173 254 Panner::setDefaultRectCentre(float cx, float cy)
Chris@173 255 {
Chris@173 256 m_defaultCentreX = cx;
Chris@173 257 m_defaultCentreY = cy;
Chris@173 258 m_defaultsSet = true;
Chris@173 259 }
Chris@172 260
Chris@173 261 void
Chris@173 262 Panner::resetToDefault()
Chris@173 263 {
Chris@173 264 float x0 = m_defaultCentreX - m_rectWidth/2;
Chris@173 265 float y0 = m_defaultCentreY - m_rectHeight/2;
Chris@173 266 if (x0 == m_rectX && y0 == m_rectY) return;
Chris@173 267 m_rectX = x0;
Chris@173 268 m_rectY = y0;
Chris@173 269 normalise();
Chris@173 270 emitAndUpdate();
Chris@173 271 }
Chris@172 272
Chris@173 273