annotate view/Overview.cpp @ 211:e2baee498ec8

* Rejig handling of scrolling views. Ensures, among other things, that playing when there is a scroll mode view present (e.g. a spectrum) does not drag any page mode views into scroll mode with it.
author Chris Cannam
date Thu, 01 Mar 2007 11:55:46 +0000
parents 5b7472db612b
children df791d8c8f58
rev   line source
Chris@173 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@173 2
Chris@173 3 /*
Chris@173 4 Sonic Visualiser
Chris@173 5 An audio file viewer and annotation editor.
Chris@173 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@173 8
Chris@173 9 This program is free software; you can redistribute it and/or
Chris@173 10 modify it under the terms of the GNU General Public License as
Chris@173 11 published by the Free Software Foundation; either version 2 of the
Chris@173 12 License, or (at your option) any later version. See the file
Chris@173 13 COPYING included with this distribution for more information.
Chris@173 14 */
Chris@173 15
Chris@173 16 #include "Overview.h"
Chris@173 17 #include "layer/Layer.h"
Chris@173 18 #include "data/model/Model.h"
Chris@173 19 #include "base/ZoomConstraint.h"
Chris@173 20
Chris@173 21 #include <QPaintEvent>
Chris@173 22 #include <QPainter>
Chris@173 23 #include <iostream>
Chris@173 24
Chris@173 25 using std::cerr;
Chris@173 26 using std::endl;
Chris@173 27
Chris@173 28 Overview::Overview(QWidget *w) :
Chris@173 29 View(w, false),
Chris@173 30 m_clickedInRange(false)
Chris@173 31 {
Chris@173 32 setObjectName(tr("Overview"));
Chris@173 33 m_followPan = false;
Chris@173 34 m_followZoom = false;
Chris@211 35 setPlaybackFollow(PlaybackIgnore);
Chris@173 36 }
Chris@173 37
Chris@173 38 void
Chris@173 39 Overview::modelChanged(size_t startFrame, size_t endFrame)
Chris@173 40 {
Chris@173 41 View::modelChanged(startFrame, endFrame);
Chris@173 42 }
Chris@173 43
Chris@173 44 void
Chris@173 45 Overview::modelReplaced()
Chris@173 46 {
Chris@173 47 View::modelReplaced();
Chris@173 48 }
Chris@173 49
Chris@173 50 void
Chris@211 51 Overview::registerView(View *view)
Chris@173 52 {
Chris@211 53 m_views.insert(view);
Chris@173 54 update();
Chris@173 55 }
Chris@173 56
Chris@173 57 void
Chris@211 58 Overview::unregisterView(View *view)
Chris@173 59 {
Chris@211 60 m_views.erase(view);
Chris@173 61 update();
Chris@173 62 }
Chris@173 63
Chris@173 64 void
Chris@211 65 Overview::globalCentreFrameChanged(unsigned long f)
Chris@173 66 {
Chris@211 67 update();
Chris@211 68 }
Chris@173 69
Chris@211 70 void
Chris@211 71 Overview::viewCentreFrameChanged(View *v, unsigned long f)
Chris@211 72 {
Chris@211 73 if (m_views.find(v) != m_views.end()) {
Chris@173 74 update();
Chris@173 75 }
Chris@211 76 }
Chris@173 77
Chris@173 78 void
Chris@173 79 Overview::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
Chris@173 80 {
Chris@173 81 if (p == this) return;
Chris@211 82 View *v = (View *)p;
Chris@211 83 if (m_views.find(v) != m_views.end()) {
Chris@173 84 update();
Chris@173 85 }
Chris@173 86 }
Chris@173 87
Chris@173 88 void
Chris@173 89 Overview::viewManagerPlaybackFrameChanged(unsigned long f)
Chris@173 90 {
Chris@173 91 bool changed = false;
Chris@173 92
Chris@173 93 if (getXForFrame(m_playPointerFrame) != getXForFrame(f)) changed = true;
Chris@173 94 m_playPointerFrame = f;
Chris@173 95
Chris@173 96 if (changed) update();
Chris@173 97 }
Chris@173 98
Chris@173 99 void
Chris@173 100 Overview::paintEvent(QPaintEvent *e)
Chris@173 101 {
Chris@173 102 // Recalculate zoom in case the size of the widget has changed.
Chris@173 103
Chris@173 104 size_t startFrame = getModelsStartFrame();
Chris@173 105 size_t frameCount = getModelsEndFrame() - getModelsStartFrame();
Chris@173 106 int zoomLevel = frameCount / width();
Chris@173 107 if (zoomLevel < 1) zoomLevel = 1;
Chris@173 108 zoomLevel = getZoomConstraintBlockSize(zoomLevel,
Chris@173 109 ZoomConstraint::RoundUp);
Chris@173 110 if (zoomLevel != m_zoomLevel) {
Chris@173 111 m_zoomLevel = zoomLevel;
Chris@173 112 emit zoomLevelChanged(this, m_zoomLevel, m_followZoom);
Chris@173 113 }
Chris@173 114 size_t centreFrame = startFrame + m_zoomLevel * (width() / 2);
Chris@173 115 if (centreFrame > (startFrame + getModelsEndFrame())/2) {
Chris@173 116 centreFrame = (startFrame + getModelsEndFrame())/2;
Chris@173 117 }
Chris@173 118 if (centreFrame != m_centreFrame) {
Chris@173 119 m_centreFrame = centreFrame;
Chris@211 120 emit centreFrameChanged(m_centreFrame, false, PlaybackIgnore);
Chris@173 121 }
Chris@173 122
Chris@173 123 View::paintEvent(e);
Chris@173 124
Chris@173 125 QPainter paint;
Chris@173 126 paint.begin(this);
Chris@173 127
Chris@173 128 QRect r(rect());
Chris@173 129
Chris@173 130 if (e) {
Chris@173 131 r = e->rect();
Chris@173 132 paint.setClipRect(r);
Chris@173 133 }
Chris@173 134
Chris@173 135 paint.setPen(Qt::black);
Chris@173 136
Chris@173 137 int y = 0;
Chris@173 138
Chris@173 139 int prevx0 = -10;
Chris@173 140 int prevx1 = -10;
Chris@173 141
Chris@211 142 for (ViewSet::iterator i = m_views.begin(); i != m_views.end(); ++i) {
Chris@173 143 if (!*i) continue;
Chris@173 144
Chris@173 145 View *w = (View *)*i;
Chris@173 146
Chris@173 147 long f0 = w->getFrameForX(0);
Chris@173 148 long f1 = w->getFrameForX(w->width());
Chris@173 149
Chris@173 150 int x0 = getXForFrame(f0);
Chris@173 151 int x1 = getXForFrame(f1);
Chris@173 152
Chris@173 153 if (x0 != prevx0 || x1 != prevx1) {
Chris@173 154 y += height() / 10 + 1;
Chris@173 155 prevx0 = x0;
Chris@173 156 prevx1 = x1;
Chris@173 157 }
Chris@173 158
Chris@173 159 if (x1 <= x0) x1 = x0 + 1;
Chris@173 160
Chris@173 161 paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
Chris@173 162 }
Chris@173 163
Chris@173 164 paint.end();
Chris@173 165 }
Chris@173 166
Chris@173 167 void
Chris@173 168 Overview::mousePressEvent(QMouseEvent *e)
Chris@173 169 {
Chris@173 170 m_clickPos = e->pos();
Chris@211 171 for (ViewSet::iterator i = m_views.begin(); i != m_views.end(); ++i) {
Chris@173 172 if (*i) {
Chris@173 173 m_clickedInRange = true;
Chris@173 174 m_dragCentreFrame = ((View *)*i)->getCentreFrame();
Chris@173 175 break;
Chris@173 176 }
Chris@173 177 }
Chris@173 178 }
Chris@173 179
Chris@173 180 void
Chris@173 181 Overview::mouseReleaseEvent(QMouseEvent *e)
Chris@173 182 {
Chris@173 183 if (m_clickedInRange) {
Chris@173 184 mouseMoveEvent(e);
Chris@173 185 }
Chris@173 186 m_clickedInRange = false;
Chris@173 187 }
Chris@173 188
Chris@173 189 void
Chris@173 190 Overview::mouseMoveEvent(QMouseEvent *e)
Chris@173 191 {
Chris@173 192 if (!m_clickedInRange) return;
Chris@173 193
Chris@173 194 long xoff = int(e->x()) - int(m_clickPos.x());
Chris@173 195 long frameOff = xoff * m_zoomLevel;
Chris@173 196
Chris@173 197 size_t newCentreFrame = m_dragCentreFrame;
Chris@173 198 if (frameOff > 0) {
Chris@173 199 newCentreFrame += frameOff;
Chris@173 200 } else if (newCentreFrame >= size_t(-frameOff)) {
Chris@173 201 newCentreFrame += frameOff;
Chris@173 202 } else {
Chris@173 203 newCentreFrame = 0;
Chris@173 204 }
Chris@173 205
Chris@173 206 if (newCentreFrame >= getModelsEndFrame()) {
Chris@173 207 newCentreFrame = getModelsEndFrame();
Chris@173 208 if (newCentreFrame > 0) --newCentreFrame;
Chris@173 209 }
Chris@173 210
Chris@173 211 if (std::max(m_centreFrame, newCentreFrame) -
Chris@173 212 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
Chris@211 213 emit centreFrameChanged(newCentreFrame, true, PlaybackIgnore);
Chris@173 214 }
Chris@173 215 }
Chris@173 216
Chris@189 217 void
Chris@189 218 Overview::mouseDoubleClickEvent(QMouseEvent *e)
Chris@189 219 {
Chris@189 220 long frame = getFrameForX(e->x());
Chris@211 221 emit centreFrameChanged(frame, true, PlaybackIgnore);
Chris@189 222 }
Chris@173 223
Chris@189 224 void
Chris@189 225 Overview::enterEvent(QEvent *)
Chris@189 226 {
Chris@189 227 emit contextHelpChanged(tr("Click and drag to navigate; double-click to jump"));
Chris@189 228 }
Chris@189 229
Chris@189 230 void
Chris@189 231 Overview::leaveEvent(QEvent *)
Chris@189 232 {
Chris@189 233 emit contextHelpChanged("");
Chris@189 234 }
Chris@189 235
Chris@189 236