annotate view/Overview.cpp @ 183:5f86ae638b04

* Omit translucent blue fill for selection rectangles that are superimposed over layers that use colours for meaningful purposes such as the spectrogram (CHARM change request)
author Chris Cannam
date Fri, 24 Nov 2006 16:56:15 +0000
parents 42118892f428
children 5b7472db612b
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@173 35 }
Chris@173 36
Chris@173 37 void
Chris@173 38 Overview::modelChanged(size_t startFrame, size_t endFrame)
Chris@173 39 {
Chris@173 40 View::modelChanged(startFrame, endFrame);
Chris@173 41 }
Chris@173 42
Chris@173 43 void
Chris@173 44 Overview::modelReplaced()
Chris@173 45 {
Chris@173 46 View::modelReplaced();
Chris@173 47 }
Chris@173 48
Chris@173 49 void
Chris@173 50 Overview::registerView(View *widget)
Chris@173 51 {
Chris@173 52 m_widgets.insert(widget);
Chris@173 53 update();
Chris@173 54 }
Chris@173 55
Chris@173 56 void
Chris@173 57 Overview::unregisterView(View *widget)
Chris@173 58 {
Chris@173 59 m_widgets.erase(widget);
Chris@173 60 update();
Chris@173 61 }
Chris@173 62
Chris@173 63 void
Chris@173 64 Overview::viewManagerCentreFrameChanged(void *p, unsigned long f, bool)
Chris@173 65 {
Chris@173 66 // std::cerr << "Overview[" << this << "]::viewManagerCentreFrameChanged("
Chris@173 67 // << p << ", " << f << ")" << std::endl;
Chris@173 68
Chris@173 69 if (p == this) return;
Chris@173 70 if (m_widgets.find(p) != m_widgets.end()) {
Chris@173 71 update();
Chris@173 72 }
Chris@173 73 }
Chris@173 74
Chris@173 75 void
Chris@173 76 Overview::viewManagerZoomLevelChanged(void *p, unsigned long z, bool)
Chris@173 77 {
Chris@173 78 if (p == this) return;
Chris@173 79 if (m_widgets.find(p) != m_widgets.end()) {
Chris@173 80 update();
Chris@173 81 }
Chris@173 82 }
Chris@173 83
Chris@173 84 void
Chris@173 85 Overview::viewManagerPlaybackFrameChanged(unsigned long f)
Chris@173 86 {
Chris@173 87 bool changed = false;
Chris@173 88
Chris@173 89 if (getXForFrame(m_playPointerFrame) != getXForFrame(f)) changed = true;
Chris@173 90 m_playPointerFrame = f;
Chris@173 91
Chris@173 92 if (changed) update();
Chris@173 93 }
Chris@173 94
Chris@173 95 void
Chris@173 96 Overview::paintEvent(QPaintEvent *e)
Chris@173 97 {
Chris@173 98 // Recalculate zoom in case the size of the widget has changed.
Chris@173 99
Chris@173 100 size_t startFrame = getModelsStartFrame();
Chris@173 101 size_t frameCount = getModelsEndFrame() - getModelsStartFrame();
Chris@173 102 int zoomLevel = frameCount / width();
Chris@173 103 if (zoomLevel < 1) zoomLevel = 1;
Chris@173 104 zoomLevel = getZoomConstraintBlockSize(zoomLevel,
Chris@173 105 ZoomConstraint::RoundUp);
Chris@173 106 if (zoomLevel != m_zoomLevel) {
Chris@173 107 m_zoomLevel = zoomLevel;
Chris@173 108 emit zoomLevelChanged(this, m_zoomLevel, m_followZoom);
Chris@173 109 }
Chris@173 110 size_t centreFrame = startFrame + m_zoomLevel * (width() / 2);
Chris@173 111 if (centreFrame > (startFrame + getModelsEndFrame())/2) {
Chris@173 112 centreFrame = (startFrame + getModelsEndFrame())/2;
Chris@173 113 }
Chris@173 114 if (centreFrame != m_centreFrame) {
Chris@173 115 m_centreFrame = centreFrame;
Chris@173 116 emit centreFrameChanged(this, m_centreFrame, false);
Chris@173 117 }
Chris@173 118
Chris@173 119 View::paintEvent(e);
Chris@173 120
Chris@173 121 QPainter paint;
Chris@173 122 paint.begin(this);
Chris@173 123
Chris@173 124 QRect r(rect());
Chris@173 125
Chris@173 126 if (e) {
Chris@173 127 r = e->rect();
Chris@173 128 paint.setClipRect(r);
Chris@173 129 }
Chris@173 130
Chris@173 131 paint.setPen(Qt::black);
Chris@173 132
Chris@173 133 int y = 0;
Chris@173 134
Chris@173 135 int prevx0 = -10;
Chris@173 136 int prevx1 = -10;
Chris@173 137
Chris@173 138 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@173 139 if (!*i) continue;
Chris@173 140
Chris@173 141 View *w = (View *)*i;
Chris@173 142
Chris@173 143 long f0 = w->getFrameForX(0);
Chris@173 144 long f1 = w->getFrameForX(w->width());
Chris@173 145
Chris@173 146 int x0 = getXForFrame(f0);
Chris@173 147 int x1 = getXForFrame(f1);
Chris@173 148
Chris@173 149 if (x0 != prevx0 || x1 != prevx1) {
Chris@173 150 y += height() / 10 + 1;
Chris@173 151 prevx0 = x0;
Chris@173 152 prevx1 = x1;
Chris@173 153 }
Chris@173 154
Chris@173 155 if (x1 <= x0) x1 = x0 + 1;
Chris@173 156
Chris@173 157 paint.drawRect(x0, y, x1 - x0, height() - 2 * y);
Chris@173 158 }
Chris@173 159
Chris@173 160 paint.end();
Chris@173 161 }
Chris@173 162
Chris@173 163 void
Chris@173 164 Overview::mousePressEvent(QMouseEvent *e)
Chris@173 165 {
Chris@173 166 m_clickPos = e->pos();
Chris@173 167 for (WidgetSet::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) {
Chris@173 168 if (*i) {
Chris@173 169 m_clickedInRange = true;
Chris@173 170 m_dragCentreFrame = ((View *)*i)->getCentreFrame();
Chris@173 171 break;
Chris@173 172 }
Chris@173 173 }
Chris@173 174 }
Chris@173 175
Chris@173 176 void
Chris@173 177 Overview::mouseReleaseEvent(QMouseEvent *e)
Chris@173 178 {
Chris@173 179 if (m_clickedInRange) {
Chris@173 180 mouseMoveEvent(e);
Chris@173 181 }
Chris@173 182 m_clickedInRange = false;
Chris@173 183 }
Chris@173 184
Chris@173 185 void
Chris@173 186 Overview::mouseMoveEvent(QMouseEvent *e)
Chris@173 187 {
Chris@173 188 if (!m_clickedInRange) return;
Chris@173 189
Chris@173 190 long xoff = int(e->x()) - int(m_clickPos.x());
Chris@173 191 long frameOff = xoff * m_zoomLevel;
Chris@173 192
Chris@173 193 size_t newCentreFrame = m_dragCentreFrame;
Chris@173 194 if (frameOff > 0) {
Chris@173 195 newCentreFrame += frameOff;
Chris@173 196 } else if (newCentreFrame >= size_t(-frameOff)) {
Chris@173 197 newCentreFrame += frameOff;
Chris@173 198 } else {
Chris@173 199 newCentreFrame = 0;
Chris@173 200 }
Chris@173 201
Chris@173 202 if (newCentreFrame >= getModelsEndFrame()) {
Chris@173 203 newCentreFrame = getModelsEndFrame();
Chris@173 204 if (newCentreFrame > 0) --newCentreFrame;
Chris@173 205 }
Chris@173 206
Chris@173 207 if (std::max(m_centreFrame, newCentreFrame) -
Chris@173 208 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
Chris@173 209 emit centreFrameChanged(this, newCentreFrame, true);
Chris@173 210 }
Chris@173 211 }
Chris@173 212
Chris@173 213