annotate widgets/Panner.cpp @ 38:beb801473743

* Rearrange spectrogram cacheing so that gain, normalization, instantaneous frequency calculations etc can be done from the cached data (increasing the size of the cache, but also the usability).
author Chris Cannam
date Thu, 23 Feb 2006 18:01:31 +0000
parents 38fe0ea9e46e
children 01ab51f72e84
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@5 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #include "Panner.h"
Chris@0 11 #include "base/Layer.h"
Chris@0 12 #include "base/Model.h"
Chris@0 13 #include "base/ZoomConstraint.h"
Chris@0 14
Chris@0 15 #include <QPaintEvent>
Chris@0 16 #include <QPainter>
Chris@0 17 #include <iostream>
Chris@0 18
Chris@0 19 using std::cerr;
Chris@0 20 using std::endl;
Chris@0 21
Chris@0 22 Panner::Panner(QWidget *w) :
Chris@0 23 View(w, false),
Chris@0 24 m_clickedInRange(false)
Chris@0 25 {
Chris@0 26 setObjectName(tr("Panner"));
Chris@0 27 m_followPan = false;
Chris@0 28 m_followZoom = false;
Chris@0 29 }
Chris@0 30
Chris@0 31 void
Chris@0 32 Panner::modelChanged(size_t startFrame, size_t endFrame)
Chris@0 33 {
Chris@0 34 View::modelChanged(startFrame, endFrame);
Chris@0 35 }
Chris@0 36
Chris@0 37 void
Chris@0 38 Panner::modelReplaced()
Chris@0 39 {
Chris@0 40 View::modelReplaced();
Chris@0 41 }
Chris@0 42
Chris@0 43 void
Chris@0 44 Panner::registerView(View *widget)
Chris@0 45 {
Chris@27 46 m_widgets.insert(widget);
Chris@0 47 update();
Chris@0 48 }
Chris@0 49
Chris@0 50 void
Chris@0 51 Panner::unregisterView(View *widget)
Chris@0 52 {
Chris@0 53 m_widgets.erase(widget);
Chris@0 54 update();
Chris@0 55 }
Chris@0 56
Chris@0 57 void
Chris@0 58 Panner::viewManagerCentreFrameChanged(void *p, unsigned long f, bool)
Chris@0 59 {
Chris@0 60 // std::cerr << "Panner[" << this << "]::viewManagerCentreFrameChanged("
Chris@0 61 // << p << ", " << f << ")" << std::endl;
Chris@0 62
Chris@0 63 if (p == this) return;
Chris@0 64 if (m_widgets.find(p) != m_widgets.end()) {
Chris@0 65 update();
Chris@0 66 }
Chris@0 67 }
Chris@0 68
Chris@0 69 void
Chris@0 70 Panner::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
Chris@0 71 {
Chris@0 72 if (p == this) return;
Chris@0 73 if (m_widgets.find(p) != m_widgets.end()) {
Chris@0 74 update();
Chris@0 75 }
Chris@0 76 }
Chris@0 77
Chris@0 78 void
Chris@0 79 Panner::viewManagerPlaybackFrameChanged(unsigned long f)
Chris@0 80 {
Chris@0 81 bool changed = false;
Chris@0 82
Chris@27 83 if (getXForFrame(m_playPointerFrame) != getXForFrame(f)) changed = true;
Chris@0 84 m_playPointerFrame = f;
Chris@0 85
Chris@0 86 if (changed) update();
Chris@0 87 }
Chris@0 88
Chris@0 89 void
Chris@0 90 Panner::paintEvent(QPaintEvent *e)
Chris@0 91 {
Chris@0 92 // Recalculate zoom in case the size of the widget has changed.
Chris@0 93
Chris@0 94 size_t startFrame = getModelsStartFrame();
Chris@0 95 size_t frameCount = getModelsEndFrame() - getModelsStartFrame();
Chris@0 96 int zoomLevel = frameCount / width();
Chris@0 97 if (zoomLevel < 1) zoomLevel = 1;
Chris@0 98 zoomLevel = getZoomConstraintBlockSize(zoomLevel,
Chris@0 99 ZoomConstraint::RoundUp);
Chris@0 100 if (zoomLevel != m_zoomLevel) {
Chris@0 101 m_zoomLevel = zoomLevel;
Chris@0 102 emit zoomLevelChanged(this, m_zoomLevel, m_followZoom);
Chris@0 103 }
Chris@0 104 size_t centreFrame = startFrame + m_zoomLevel * (width() / 2);
Chris@0 105 if (centreFrame > (startFrame + getModelsEndFrame())/2) {
Chris@0 106 centreFrame = (startFrame + getModelsEndFrame())/2;
Chris@0 107 }
Chris@0 108 if (centreFrame != m_centreFrame) {
Chris@0 109 m_centreFrame = centreFrame;
Chris@0 110 emit centreFrameChanged(this, m_centreFrame, false);
Chris@0 111 }
Chris@0 112
Chris@0 113 View::paintEvent(e);
Chris@0 114
Chris@0 115 QPainter paint;
Chris@0 116 paint.begin(this);
Chris@0 117
Chris@0 118 QRect r(rect());
Chris@0 119
Chris@0 120 if (e) {
Chris@0 121 r = e->rect();
Chris@0 122 paint.setClipRect(r);
Chris@0 123 }
Chris@0 124
Chris@0 125 paint.setPen(Qt::black);
Chris@0 126
Chris@0 127 int y = 0;
Chris@0 128
Chris@27 129 int prevx0 = -10;
Chris@27 130 int prevx1 = -10;
Chris@0 131
Chris@27 132 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@27 133 if (!*i) continue;
Chris@0 134
Chris@27 135 View *w = (View *)*i;
Chris@0 136
Chris@27 137 long f0 = w->getFrameForX(0);
Chris@27 138 long f1 = w->getFrameForX(w->width());
Chris@0 139
Chris@27 140 int x0 = getXForFrame(f0);
Chris@27 141 int x1 = getXForFrame(f1);
Chris@0 142
Chris@27 143 if (x0 != prevx0 || x1 != prevx1) {
Chris@0 144 y += height() / 10 + 1;
Chris@27 145 prevx0 = x0;
Chris@27 146 prevx1 = x1;
Chris@0 147 }
Chris@27 148
Chris@27 149 if (x1 <= x0) x1 = x0 + 1;
Chris@0 150
Chris@0 151 paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
Chris@0 152 }
Chris@0 153
Chris@0 154 paint.end();
Chris@0 155 }
Chris@0 156
Chris@0 157 void
Chris@0 158 Panner::mousePressEvent(QMouseEvent *e)
Chris@0 159 {
Chris@0 160 m_clickPos = e->pos();
Chris@27 161 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@27 162 if (*i) {
Chris@0 163 m_clickedInRange = true;
Chris@27 164 m_dragCentreFrame = ((View *)*i)->getCentreFrame();
Chris@27 165 break;
Chris@0 166 }
Chris@0 167 }
Chris@0 168 }
Chris@0 169
Chris@0 170 void
Chris@0 171 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@0 172 {
Chris@0 173 if (m_clickedInRange) {
Chris@0 174 mouseMoveEvent(e);
Chris@0 175 }
Chris@0 176 m_clickedInRange = false;
Chris@0 177 }
Chris@0 178
Chris@0 179 void
Chris@0 180 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@0 181 {
Chris@0 182 if (!m_clickedInRange) return;
Chris@0 183
Chris@0 184 long xoff = int(e->x()) - int(m_clickPos.x());
Chris@0 185 long frameOff = xoff * m_zoomLevel;
Chris@0 186
Chris@0 187 size_t newCentreFrame = m_dragCentreFrame;
Chris@0 188 if (frameOff > 0) {
Chris@0 189 newCentreFrame += frameOff;
Chris@0 190 } else if (newCentreFrame >= size_t(-frameOff)) {
Chris@0 191 newCentreFrame += frameOff;
Chris@0 192 } else {
Chris@0 193 newCentreFrame = 0;
Chris@0 194 }
Chris@0 195
Chris@0 196 if (newCentreFrame >= getModelsEndFrame()) {
Chris@0 197 newCentreFrame = getModelsEndFrame();
Chris@0 198 if (newCentreFrame > 0) --newCentreFrame;
Chris@0 199 }
Chris@0 200
Chris@0 201 if (std::max(m_centreFrame, newCentreFrame) -
Chris@0 202 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
Chris@0 203 emit centreFrameChanged(this, newCentreFrame, true);
Chris@0 204 }
Chris@0 205 }
Chris@0 206
Chris@0 207 #ifdef INCLUDE_MOCFILES
Chris@0 208 #include "Panner.moc.cpp"
Chris@0 209 #endif
Chris@0 210