annotate widgets/LevelPanWidget.cpp @ 926:bfeabe25a1a3 tonioni

Add missed include
author Chris Cannam
date Tue, 24 Mar 2015 16:08:36 +0000
parents 76f4b81b766d
children 271e729c818b
rev   line source
Chris@923 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@923 2
Chris@923 3 /*
Chris@923 4 Sonic Visualiser
Chris@923 5 An audio file viewer and annotation editor.
Chris@923 6 Centre for Digital Music, Queen Mary, University of London.
Chris@923 7
Chris@923 8 This program is free software; you can redistribute it and/or
Chris@923 9 modify it under the terms of the GNU General Public License as
Chris@923 10 published by the Free Software Foundation; either version 2 of the
Chris@923 11 License, or (at your option) any later version. See the file
Chris@923 12 COPYING included with this distribution for more information.
Chris@923 13 */
Chris@923 14
Chris@923 15 #include "LevelPanWidget.h"
Chris@923 16
Chris@923 17 #include <QPainter>
Chris@923 18 #include <QMouseEvent>
Chris@923 19 #include <QWheelEvent>
Chris@923 20
Chris@923 21 #include "layer/ColourMapper.h"
Chris@925 22 #include "base/AudioLevel.h"
Chris@923 23
Chris@923 24 #include <iostream>
Chris@926 25 #include <cmath>
Chris@923 26
Chris@923 27 using std::cerr;
Chris@923 28 using std::endl;
Chris@923 29
Chris@924 30 static const int maxLevel = 4;
Chris@923 31 static const int maxPan = 2; // range is -maxPan to maxPan
Chris@923 32
Chris@923 33 LevelPanWidget::LevelPanWidget(QWidget *parent) :
Chris@923 34 QWidget(parent),
Chris@923 35 m_level(maxLevel),
Chris@923 36 m_pan(0),
Chris@923 37 m_editable(true)
Chris@923 38 {
Chris@923 39 }
Chris@923 40
Chris@923 41 LevelPanWidget::~LevelPanWidget()
Chris@923 42 {
Chris@923 43 }
Chris@923 44
Chris@923 45 void
Chris@925 46 LevelPanWidget::setLevel(float flevel)
Chris@923 47 {
Chris@925 48 int level = AudioLevel::multiplier_to_fader
Chris@925 49 (flevel, maxLevel, AudioLevel::ShortFader);
Chris@925 50 if (level < 0) level = 0;
Chris@925 51 if (level > maxLevel) level = maxLevel;
Chris@925 52 if (level != m_level) {
Chris@925 53 m_level = level;
Chris@925 54 float convertsTo = getLevel();
Chris@925 55 if (fabsf(convertsTo - flevel) > 1e-5) {
Chris@925 56 emitLevelChanged();
Chris@925 57 }
Chris@925 58 update();
Chris@925 59 }
Chris@923 60 }
Chris@923 61
Chris@923 62 void
Chris@923 63 LevelPanWidget::setPan(float pan)
Chris@923 64 {
Chris@923 65 m_pan = int(round(pan * maxPan));
Chris@923 66 if (m_pan < -maxPan) m_pan = -maxPan;
Chris@923 67 if (m_pan > maxPan) m_pan = maxPan;
Chris@923 68 update();
Chris@923 69 }
Chris@923 70
Chris@923 71 void
Chris@923 72 LevelPanWidget::setEditable(bool editable)
Chris@923 73 {
Chris@923 74 m_editable = editable;
Chris@923 75 update();
Chris@923 76 }
Chris@923 77
Chris@923 78 float
Chris@923 79 LevelPanWidget::getLevel() const
Chris@923 80 {
Chris@925 81 return float(AudioLevel::fader_to_multiplier
Chris@925 82 (m_level, maxLevel, AudioLevel::ShortFader));
Chris@923 83 }
Chris@923 84
Chris@923 85 float
Chris@923 86 LevelPanWidget::getPan() const
Chris@923 87 {
Chris@923 88 return float(m_pan) / float(maxPan);
Chris@923 89 }
Chris@923 90
Chris@923 91 void
Chris@923 92 LevelPanWidget::emitLevelChanged()
Chris@923 93 {
Chris@923 94 cerr << "emitting levelChanged(" << getLevel() << ")" << endl;
Chris@923 95 emit levelChanged(getLevel());
Chris@923 96 }
Chris@923 97
Chris@923 98 void
Chris@923 99 LevelPanWidget::emitPanChanged()
Chris@923 100 {
Chris@923 101 cerr << "emitting panChanged(" << getPan() << ")" << endl;
Chris@923 102 emit panChanged(getPan());
Chris@923 103 }
Chris@923 104
Chris@923 105 void
Chris@923 106 LevelPanWidget::mousePressEvent(QMouseEvent *e)
Chris@923 107 {
Chris@923 108 mouseMoveEvent(e);
Chris@923 109 }
Chris@923 110
Chris@923 111 void
Chris@923 112 LevelPanWidget::mouseMoveEvent(QMouseEvent *e)
Chris@923 113 {
Chris@923 114 if (!m_editable) return;
Chris@923 115
Chris@923 116 int level, pan;
Chris@923 117 toCell(e->pos(), level, pan);
Chris@923 118 if (level == m_level && pan == m_pan) {
Chris@923 119 return;
Chris@923 120 }
Chris@923 121 if (level != m_level) {
Chris@923 122 m_level = level;
Chris@923 123 emitLevelChanged();
Chris@923 124 }
Chris@923 125 if (pan != m_pan) {
Chris@923 126 m_pan = pan;
Chris@923 127 emitPanChanged();
Chris@923 128 }
Chris@923 129 update();
Chris@923 130 }
Chris@923 131
Chris@923 132 void
Chris@923 133 LevelPanWidget::mouseReleaseEvent(QMouseEvent *e)
Chris@923 134 {
Chris@923 135 mouseMoveEvent(e);
Chris@923 136 }
Chris@923 137
Chris@923 138 void
Chris@923 139 LevelPanWidget::wheelEvent(QWheelEvent *e)
Chris@923 140 {
Chris@923 141 if (e->modifiers() & Qt::ControlModifier) {
Chris@923 142 if (e->delta() > 0) {
Chris@923 143 if (m_pan < maxPan) {
Chris@923 144 ++m_pan;
Chris@923 145 emitPanChanged();
Chris@923 146 update();
Chris@923 147 }
Chris@923 148 } else {
Chris@923 149 if (m_pan > -maxPan) {
Chris@923 150 --m_pan;
Chris@923 151 emitPanChanged();
Chris@923 152 update();
Chris@923 153 }
Chris@923 154 }
Chris@923 155 } else {
Chris@923 156 if (e->delta() > 0) {
Chris@923 157 if (m_level < maxLevel) {
Chris@923 158 ++m_level;
Chris@923 159 emitLevelChanged();
Chris@923 160 update();
Chris@923 161 }
Chris@923 162 } else {
Chris@923 163 if (m_level > 0) {
Chris@923 164 --m_level;
Chris@923 165 emitLevelChanged();
Chris@923 166 update();
Chris@923 167 }
Chris@923 168 }
Chris@923 169 }
Chris@923 170 }
Chris@923 171
Chris@923 172 void
Chris@923 173 LevelPanWidget::toCell(QPointF loc, int &level, int &pan) const
Chris@923 174 {
Chris@923 175 double w = width(), h = height();
Chris@923 176 int npan = maxPan * 2 + 1;
Chris@924 177 int nlevel = maxLevel + 1;
Chris@924 178 double wcell = w / npan, hcell = h / nlevel;
Chris@923 179 level = int((h - loc.y()) / hcell) + 1;
Chris@924 180 if (level < 0) level = 0;
Chris@923 181 if (level > maxLevel) level = maxLevel;
Chris@923 182 pan = int(loc.x() / wcell) - maxPan;
Chris@923 183 if (pan < -maxPan) pan = -maxPan;
Chris@923 184 if (pan > maxPan) pan = maxPan;
Chris@923 185 }
Chris@923 186
Chris@923 187 QSizeF
Chris@923 188 LevelPanWidget::cellSize() const
Chris@923 189 {
Chris@923 190 double w = width(), h = height();
Chris@923 191 int npan = maxPan * 2 + 1;
Chris@924 192 int nlevel = maxLevel + 1;
Chris@924 193 double wcell = w / npan, hcell = h / nlevel;
Chris@923 194 return QSizeF(wcell, hcell);
Chris@923 195 }
Chris@923 196
Chris@923 197 QPointF
Chris@923 198 LevelPanWidget::cellCentre(int level, int pan) const
Chris@923 199 {
Chris@923 200 QSizeF cs = cellSize();
Chris@923 201 return QPointF(cs.width() * (pan + maxPan) + cs.width() / 2.,
Chris@924 202 height() - cs.height() * (level + 1) + cs.height() / 2.);
Chris@923 203 }
Chris@923 204
Chris@923 205 QSizeF
Chris@923 206 LevelPanWidget::cellLightSize() const
Chris@923 207 {
Chris@923 208 double extent = 3. / 4.;
Chris@923 209 QSizeF cs = cellSize();
Chris@923 210 double m = std::min(cs.width(), cs.height());
Chris@923 211 return QSizeF(m * extent, m * extent);
Chris@923 212 }
Chris@923 213
Chris@923 214 QRectF
Chris@923 215 LevelPanWidget::cellLightRect(int level, int pan) const
Chris@923 216 {
Chris@923 217 QSizeF cls = cellLightSize();
Chris@923 218 QPointF cc = cellCentre(level, pan);
Chris@923 219 return QRectF(cc.x() - cls.width() / 2.,
Chris@923 220 cc.y() - cls.height() / 2.,
Chris@923 221 cls.width(),
Chris@923 222 cls.height());
Chris@923 223 }
Chris@923 224
Chris@923 225 double
Chris@923 226 LevelPanWidget::thinLineWidth() const
Chris@923 227 {
Chris@923 228 double tw = ceil(width() / (maxPan * 2. * 10.));
Chris@923 229 double th = ceil(height() / (maxLevel * 10.));
Chris@923 230 return std::min(th, tw);
Chris@923 231 }
Chris@923 232
Chris@923 233 void
Chris@923 234 LevelPanWidget::paintEvent(QPaintEvent *)
Chris@923 235 {
Chris@923 236 QPainter paint(this);
Chris@923 237 ColourMapper mapper(ColourMapper::Sunset, 0, maxLevel);
Chris@923 238
Chris@923 239 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@923 240
Chris@923 241 QPen pen;
Chris@923 242
Chris@923 243 double thin = thinLineWidth();
Chris@923 244
Chris@923 245 pen.setColor(QColor(127, 127, 127, 127));
Chris@923 246 pen.setWidthF(cellLightSize().width() + thin);
Chris@923 247 pen.setCapStyle(Qt::RoundCap);
Chris@923 248 paint.setPen(pen);
Chris@923 249
Chris@923 250 for (int pan = -maxPan; pan <= maxPan; ++pan) {
Chris@924 251 paint.drawLine(cellCentre(0, pan), cellCentre(maxLevel, pan));
Chris@924 252 }
Chris@924 253
Chris@924 254 if (isEnabled()) {
Chris@924 255 pen.setColor(Qt::black);
Chris@924 256 } else {
Chris@924 257 pen.setColor(Qt::darkGray);
Chris@923 258 }
Chris@923 259
Chris@923 260 pen.setWidthF(thin);
Chris@923 261 pen.setCapStyle(Qt::FlatCap);
Chris@923 262 paint.setPen(pen);
Chris@923 263
Chris@924 264 for (int level = 0; level <= m_level; ++level) {
Chris@924 265 if (isEnabled()) {
Chris@924 266 paint.setBrush(mapper.map(level));
Chris@924 267 }
Chris@924 268 QRectF clr = cellLightRect(level, m_pan);
Chris@924 269 if (m_level == 0) {
Chris@924 270 paint.drawLine(clr.topLeft(), clr.bottomRight());
Chris@924 271 paint.drawLine(clr.bottomLeft(), clr.topRight());
Chris@924 272 } else {
Chris@924 273 paint.drawEllipse(clr);
Chris@924 274 }
Chris@923 275 }
Chris@923 276 }
Chris@923 277
Chris@923 278