annotate widgets/Panner.cpp @ 101:0f36cdf407a6 sv1-v0.9rc1

* Make vertical scale alignment modes work in note layer as well as time-value layer, and several significant fixes to it * Make it possible to draw notes properly on the note layer * Show units (and frequencies etc in note layer's case) in the time-value and note layer description boxes * Minor fix to item edit dialog layout * Some minor menu rearrangement * Comment out a lot of debug output * Add SV website and reference URLs to Help menu, and add code to (attempt to) open them in the user's preferred browser
author Chris Cannam
date Fri, 12 May 2006 14:40:43 +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