annotate view/AlignmentView.cpp @ 868:99299949f965 alignment_view

Don't hide time-instant layers when switching modes; use them as source of key frames in alignment view
author Chris Cannam
date Fri, 17 Oct 2014 16:47:53 +0100
parents 99373ca20caf
children 6a590241d8ad
rev   line source
Chris@867 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@867 2
Chris@867 3 /*
Chris@867 4 Sonic Visualiser
Chris@867 5 An audio file viewer and annotation editor.
Chris@867 6 Centre for Digital Music, Queen Mary, University of London.
Chris@867 7 This file copyright 2006-2014 Chris Cannam and QMUL.
Chris@867 8
Chris@867 9 This program is free software; you can redistribute it and/or
Chris@867 10 modify it under the terms of the GNU General Public License as
Chris@867 11 published by the Free Software Foundation; either version 2 of the
Chris@867 12 License, or (at your option) any later version. See the file
Chris@867 13 COPYING included with this distribution for more information.
Chris@867 14 */
Chris@867 15
Chris@867 16 #include "AlignmentView.h"
Chris@867 17
Chris@867 18 #include <QPainter>
Chris@867 19
Chris@868 20 #include "data/model/SparseOneDimensionalModel.h"
Chris@868 21
Chris@868 22 #include "layer/TimeInstantLayer.h"
Chris@868 23
Chris@867 24 using std::vector;
Chris@867 25
Chris@867 26 AlignmentView::AlignmentView(QWidget *w) :
Chris@867 27 View(w, false),
Chris@867 28 m_above(0),
Chris@867 29 m_below(0)
Chris@867 30 {
Chris@867 31 setObjectName(tr("AlignmentView"));
Chris@867 32 }
Chris@867 33
Chris@867 34 void
Chris@867 35 AlignmentView::globalCentreFrameChanged(int f)
Chris@867 36 {
Chris@867 37 View::globalCentreFrameChanged(f);
Chris@867 38 update();
Chris@867 39 }
Chris@867 40
Chris@867 41 void
Chris@867 42 AlignmentView::viewCentreFrameChanged(View *v, int f)
Chris@867 43 {
Chris@867 44 View::viewCentreFrameChanged(v, f);
Chris@867 45 if (v == m_above) {
Chris@867 46 m_centreFrame = f;
Chris@867 47 update();
Chris@867 48 } else if (v == m_below) {
Chris@867 49 update();
Chris@867 50 }
Chris@867 51 }
Chris@867 52
Chris@867 53 void
Chris@867 54 AlignmentView::viewManagerPlaybackFrameChanged(int)
Chris@867 55 {
Chris@867 56 update();
Chris@867 57 }
Chris@867 58
Chris@867 59 void
Chris@867 60 AlignmentView::viewAboveZoomLevelChanged(int level, bool)
Chris@867 61 {
Chris@867 62 m_zoomLevel = level;
Chris@867 63 update();
Chris@867 64 }
Chris@867 65
Chris@867 66 void
Chris@867 67 AlignmentView::viewBelowZoomLevelChanged(int, bool)
Chris@867 68 {
Chris@867 69 update();
Chris@867 70 }
Chris@867 71
Chris@867 72 void
Chris@867 73 AlignmentView::setViewAbove(View *v)
Chris@867 74 {
Chris@867 75 if (m_above) {
Chris@867 76 disconnect(m_above, 0, this, 0);
Chris@867 77 }
Chris@867 78
Chris@867 79 m_above = v;
Chris@867 80
Chris@867 81 if (m_above) {
Chris@867 82 connect(m_above,
Chris@867 83 SIGNAL(zoomLevelChanged(int, bool)),
Chris@867 84 this,
Chris@867 85 SLOT(viewAboveZoomLevelChanged(int, bool)));
Chris@867 86 }
Chris@867 87 }
Chris@867 88
Chris@867 89 void
Chris@867 90 AlignmentView::setViewBelow(View *v)
Chris@867 91 {
Chris@867 92 if (m_below) {
Chris@867 93 disconnect(m_below, 0, this, 0);
Chris@867 94 }
Chris@867 95
Chris@867 96 m_below = v;
Chris@867 97
Chris@867 98 if (m_below) {
Chris@867 99 connect(m_below,
Chris@867 100 SIGNAL(zoomLevelChanged(int, bool)),
Chris@867 101 this,
Chris@867 102 SLOT(viewBelowZoomLevelChanged(int, bool)));
Chris@867 103 }
Chris@867 104 }
Chris@867 105
Chris@867 106 void
Chris@867 107 AlignmentView::paintEvent(QPaintEvent *)
Chris@867 108 {
Chris@867 109 if (m_above == 0 || m_below == 0 || !m_manager) return;
Chris@867 110
Chris@867 111 bool darkPalette = false;
Chris@867 112 if (m_manager) darkPalette = m_manager->getGlobalDarkBackground();
Chris@867 113
Chris@867 114 QColor fg = Qt::black, bg = Qt::white;
Chris@867 115 if (darkPalette) std::swap(fg, bg);
Chris@867 116
Chris@867 117 QPainter paint(this);
Chris@867 118 paint.setPen(QPen(fg, 2));
Chris@867 119 paint.setBrush(Qt::NoBrush);
Chris@867 120 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@867 121
Chris@867 122 paint.fillRect(rect(), bg);
Chris@867 123
Chris@868 124 vector<int> keyFrames = getKeyFrames();
Chris@867 125
Chris@867 126 foreach (int f, keyFrames) {
Chris@867 127 int af = m_above->alignFromReference(f);
Chris@867 128 int ax = m_above->getXForFrame(af);
Chris@867 129 int bf = m_below->alignFromReference(f);
Chris@867 130 int bx = m_below->getXForFrame(bf);
Chris@867 131 paint.drawLine(ax, 0, bx, height());
Chris@867 132 }
Chris@867 133
Chris@867 134 paint.end();
Chris@867 135 }
Chris@867 136
Chris@868 137 vector<int>
Chris@868 138 AlignmentView::getKeyFrames()
Chris@868 139 {
Chris@868 140 if (!m_above) {
Chris@868 141 return getDefaultKeyFrames();
Chris@868 142 }
Chris@868 143
Chris@868 144 SparseOneDimensionalModel *m = 0;
Chris@868 145
Chris@868 146 // get the topmost such
Chris@868 147 for (int i = 0; i < m_above->getLayerCount(); ++i) {
Chris@868 148 if (qobject_cast<TimeInstantLayer *>(m_above->getLayer(i))) {
Chris@868 149 SparseOneDimensionalModel *mm =
Chris@868 150 qobject_cast<SparseOneDimensionalModel *>
Chris@868 151 (m_above->getLayer(i)->getModel());
Chris@868 152 if (mm) m = mm;
Chris@868 153 }
Chris@868 154 }
Chris@868 155
Chris@868 156 if (!m) {
Chris@868 157 return getDefaultKeyFrames();
Chris@868 158 }
Chris@868 159
Chris@868 160 vector<int> keyFrames;
Chris@868 161
Chris@868 162 const SparseOneDimensionalModel::PointList pp = m->getPoints();
Chris@868 163 for (SparseOneDimensionalModel::PointList::const_iterator pi = pp.begin();
Chris@868 164 pi != pp.end(); ++pi) {
Chris@868 165 keyFrames.push_back(pi->frame);
Chris@868 166 }
Chris@868 167
Chris@868 168 return keyFrames;
Chris@868 169 }
Chris@868 170
Chris@868 171 vector<int>
Chris@868 172 AlignmentView::getDefaultKeyFrames()
Chris@868 173 {
Chris@868 174 vector<int> keyFrames;
Chris@868 175
Chris@868 176 if (!m_above || !m_manager) return keyFrames;
Chris@868 177
Chris@868 178 int rate = m_manager->getMainModelSampleRate();
Chris@868 179 if (rate == 0) return keyFrames;
Chris@868 180
Chris@868 181 for (int f = m_above->getModelsStartFrame();
Chris@868 182 f <= m_above->getModelsEndFrame();
Chris@868 183 f += rate * 5) {
Chris@868 184 keyFrames.push_back(f);
Chris@868 185 }
Chris@868 186
Chris@868 187 return keyFrames;
Chris@868 188 }
Chris@868 189
Chris@868 190
Chris@868 191
Chris@868 192
Chris@868 193
Chris@868 194