annotate widgets/Panner.cpp @ 98:2be85befe873

* Reorder plugin output querying so as to cope with plugins whose number of values per output varies depending on the initialise parameters * Make the colour 3D plot layer tolerably efficient with very dense models * Allow export of colour 3D plot layers
author Chris Cannam
date Wed, 10 May 2006 16:34:03 +0000
parents 705f05ab42e3
children
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@59 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "Panner.h"
Chris@0 17 #include "base/Layer.h"
Chris@0 18 #include "base/Model.h"
Chris@0 19 #include "base/ZoomConstraint.h"
Chris@0 20
Chris@0 21 #include <QPaintEvent>
Chris@0 22 #include <QPainter>
Chris@0 23 #include <iostream>
Chris@0 24
Chris@0 25 using std::cerr;
Chris@0 26 using std::endl;
Chris@0 27
Chris@0 28 Panner::Panner(QWidget *w) :
Chris@0 29 View(w, false),
Chris@0 30 m_clickedInRange(false)
Chris@0 31 {
Chris@0 32 setObjectName(tr("Panner"));
Chris@0 33 m_followPan = false;
Chris@0 34 m_followZoom = false;
Chris@0 35 }
Chris@0 36
Chris@0 37 void
Chris@0 38 Panner::modelChanged(size_t startFrame, size_t endFrame)
Chris@0 39 {
Chris@0 40 View::modelChanged(startFrame, endFrame);
Chris@0 41 }
Chris@0 42
Chris@0 43 void
Chris@0 44 Panner::modelReplaced()
Chris@0 45 {
Chris@0 46 View::modelReplaced();
Chris@0 47 }
Chris@0 48
Chris@0 49 void
Chris@0 50 Panner::registerView(View *widget)
Chris@0 51 {
Chris@27 52 m_widgets.insert(widget);
Chris@0 53 update();
Chris@0 54 }
Chris@0 55
Chris@0 56 void
Chris@0 57 Panner::unregisterView(View *widget)
Chris@0 58 {
Chris@0 59 m_widgets.erase(widget);
Chris@0 60 update();
Chris@0 61 }
Chris@0 62
Chris@0 63 void
Chris@0 64 Panner::viewManagerCentreFrameChanged(void *p, unsigned long f, bool)
Chris@0 65 {
Chris@0 66 // std::cerr << "Panner[" << this << "]::viewManagerCentreFrameChanged("
Chris@0 67 // << p << ", " << f << ")" << std::endl;
Chris@0 68
Chris@0 69 if (p == this) return;
Chris@0 70 if (m_widgets.find(p) != m_widgets.end()) {
Chris@0 71 update();
Chris@0 72 }
Chris@0 73 }
Chris@0 74
Chris@0 75 void
Chris@0 76 Panner::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
Chris@0 77 {
Chris@0 78 if (p == this) return;
Chris@0 79 if (m_widgets.find(p) != m_widgets.end()) {
Chris@0 80 update();
Chris@0 81 }
Chris@0 82 }
Chris@0 83
Chris@0 84 void
Chris@0 85 Panner::viewManagerPlaybackFrameChanged(unsigned long f)
Chris@0 86 {
Chris@0 87 bool changed = false;
Chris@0 88
Chris@27 89 if (getXForFrame(m_playPointerFrame) != getXForFrame(f)) changed = true;
Chris@0 90 m_playPointerFrame = f;
Chris@0 91
Chris@0 92 if (changed) update();
Chris@0 93 }
Chris@0 94
Chris@0 95 void
Chris@0 96 Panner::paintEvent(QPaintEvent *e)
Chris@0 97 {
Chris@0 98 // Recalculate zoom in case the size of the widget has changed.
Chris@0 99
Chris@0 100 size_t startFrame = getModelsStartFrame();
Chris@0 101 size_t frameCount = getModelsEndFrame() - getModelsStartFrame();
Chris@0 102 int zoomLevel = frameCount / width();
Chris@0 103 if (zoomLevel < 1) zoomLevel = 1;
Chris@0 104 zoomLevel = getZoomConstraintBlockSize(zoomLevel,
Chris@0 105 ZoomConstraint::RoundUp);
Chris@0 106 if (zoomLevel != m_zoomLevel) {
Chris@0 107 m_zoomLevel = zoomLevel;
Chris@0 108 emit zoomLevelChanged(this, m_zoomLevel, m_followZoom);
Chris@0 109 }
Chris@0 110 size_t centreFrame = startFrame + m_zoomLevel * (width() / 2);
Chris@0 111 if (centreFrame > (startFrame + getModelsEndFrame())/2) {
Chris@0 112 centreFrame = (startFrame + getModelsEndFrame())/2;
Chris@0 113 }
Chris@0 114 if (centreFrame != m_centreFrame) {
Chris@0 115 m_centreFrame = centreFrame;
Chris@0 116 emit centreFrameChanged(this, m_centreFrame, false);
Chris@0 117 }
Chris@0 118
Chris@0 119 View::paintEvent(e);
Chris@0 120
Chris@0 121 QPainter paint;
Chris@0 122 paint.begin(this);
Chris@0 123
Chris@0 124 QRect r(rect());
Chris@0 125
Chris@0 126 if (e) {
Chris@0 127 r = e->rect();
Chris@0 128 paint.setClipRect(r);
Chris@0 129 }
Chris@0 130
Chris@0 131 paint.setPen(Qt::black);
Chris@0 132
Chris@0 133 int y = 0;
Chris@0 134
Chris@27 135 int prevx0 = -10;
Chris@27 136 int prevx1 = -10;
Chris@0 137
Chris@27 138 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@27 139 if (!*i) continue;
Chris@0 140
Chris@27 141 View *w = (View *)*i;
Chris@0 142
Chris@27 143 long f0 = w->getFrameForX(0);
Chris@27 144 long f1 = w->getFrameForX(w->width());
Chris@0 145
Chris@27 146 int x0 = getXForFrame(f0);
Chris@27 147 int x1 = getXForFrame(f1);
Chris@0 148
Chris@27 149 if (x0 != prevx0 || x1 != prevx1) {
Chris@0 150 y += height() / 10 + 1;
Chris@27 151 prevx0 = x0;
Chris@27 152 prevx1 = x1;
Chris@0 153 }
Chris@27 154
Chris@27 155 if (x1 <= x0) x1 = x0 + 1;
Chris@0 156
Chris@0 157 paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
Chris@0 158 }
Chris@0 159
Chris@0 160 paint.end();
Chris@0 161 }
Chris@0 162
Chris@0 163 void
Chris@0 164 Panner::mousePressEvent(QMouseEvent *e)
Chris@0 165 {
Chris@0 166 m_clickPos = e->pos();
Chris@27 167 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@27 168 if (*i) {
Chris@0 169 m_clickedInRange = true;
Chris@27 170 m_dragCentreFrame = ((View *)*i)->getCentreFrame();
Chris@27 171 break;
Chris@0 172 }
Chris@0 173 }
Chris@0 174 }
Chris@0 175
Chris@0 176 void
Chris@0 177 Panner::mouseReleaseEvent(QMouseEvent *e)
Chris@0 178 {
Chris@0 179 if (m_clickedInRange) {
Chris@0 180 mouseMoveEvent(e);
Chris@0 181 }
Chris@0 182 m_clickedInRange = false;
Chris@0 183 }
Chris@0 184
Chris@0 185 void
Chris@0 186 Panner::mouseMoveEvent(QMouseEvent *e)
Chris@0 187 {
Chris@0 188 if (!m_clickedInRange) return;
Chris@0 189
Chris@0 190 long xoff = int(e->x()) - int(m_clickPos.x());
Chris@0 191 long frameOff = xoff * m_zoomLevel;
Chris@0 192
Chris@0 193 size_t newCentreFrame = m_dragCentreFrame;
Chris@0 194 if (frameOff > 0) {
Chris@0 195 newCentreFrame += frameOff;
Chris@0 196 } else if (newCentreFrame >= size_t(-frameOff)) {
Chris@0 197 newCentreFrame += frameOff;
Chris@0 198 } else {
Chris@0 199 newCentreFrame = 0;
Chris@0 200 }
Chris@0 201
Chris@0 202 if (newCentreFrame >= getModelsEndFrame()) {
Chris@0 203 newCentreFrame = getModelsEndFrame();
Chris@0 204 if (newCentreFrame > 0) --newCentreFrame;
Chris@0 205 }
Chris@0 206
Chris@0 207 if (std::max(m_centreFrame, newCentreFrame) -
Chris@0 208 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
Chris@0 209 emit centreFrameChanged(this, newCentreFrame, true);
Chris@0 210 }
Chris@0 211 }
Chris@0 212
Chris@0 213 #ifdef INCLUDE_MOCFILES
Chris@0 214 #include "Panner.moc.cpp"
Chris@0 215 #endif
Chris@0 216