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@976
|
35 AlignmentView::globalCentreFrameChanged(sv_frame_t 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@976
|
42 AlignmentView::viewCentreFrameChanged(View *v, sv_frame_t f)
|
Chris@867
|
43 {
|
Chris@867
|
44 View::viewCentreFrameChanged(v, f);
|
Chris@867
|
45 if (v == m_above) {
|
Chris@1266
|
46 m_centreFrame = f;
|
Chris@1266
|
47 update();
|
Chris@867
|
48 } else if (v == m_below) {
|
Chris@1266
|
49 update();
|
Chris@867
|
50 }
|
Chris@867
|
51 }
|
Chris@867
|
52
|
Chris@867
|
53 void
|
Chris@976
|
54 AlignmentView::viewManagerPlaybackFrameChanged(sv_frame_t)
|
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@1266
|
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@1266
|
82 connect(m_above,
|
Chris@1266
|
83 SIGNAL(zoomLevelChanged(int, bool)),
|
Chris@1266
|
84 this,
|
Chris@1266
|
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@1266
|
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@1266
|
99 connect(m_below,
|
Chris@1266
|
100 SIGNAL(zoomLevelChanged(int, bool)),
|
Chris@1266
|
101 this,
|
Chris@1266
|
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@881
|
114 QColor fg, bg;
|
Chris@881
|
115 if (darkPalette) {
|
Chris@881
|
116 fg = Qt::gray;
|
Chris@881
|
117 bg = Qt::black;
|
Chris@881
|
118 } else {
|
Chris@881
|
119 fg = Qt::black;
|
Chris@881
|
120 bg = Qt::gray;
|
Chris@881
|
121 }
|
Chris@867
|
122
|
Chris@867
|
123 QPainter paint(this);
|
Chris@867
|
124 paint.setPen(QPen(fg, 2));
|
Chris@867
|
125 paint.setBrush(Qt::NoBrush);
|
Chris@867
|
126 paint.setRenderHint(QPainter::Antialiasing, true);
|
Chris@867
|
127
|
Chris@867
|
128 paint.fillRect(rect(), bg);
|
Chris@867
|
129
|
Chris@976
|
130 vector<sv_frame_t> keyFrames = getKeyFrames();
|
Chris@867
|
131
|
Chris@976
|
132 foreach (sv_frame_t f, keyFrames) {
|
Chris@1266
|
133 int ax = m_above->getXForFrame(f);
|
Chris@1266
|
134 sv_frame_t rf = m_above->alignToReference(f);
|
Chris@1266
|
135 sv_frame_t bf = m_below->alignFromReference(rf);
|
Chris@1266
|
136 int bx = m_below->getXForFrame(bf);
|
Chris@1266
|
137 paint.drawLine(ax, 0, bx, height());
|
Chris@867
|
138 }
|
Chris@867
|
139
|
Chris@867
|
140 paint.end();
|
Chris@867
|
141 }
|
Chris@867
|
142
|
Chris@976
|
143 vector<sv_frame_t>
|
Chris@868
|
144 AlignmentView::getKeyFrames()
|
Chris@868
|
145 {
|
Chris@868
|
146 if (!m_above) {
|
Chris@1266
|
147 return getDefaultKeyFrames();
|
Chris@868
|
148 }
|
Chris@868
|
149
|
Chris@868
|
150 SparseOneDimensionalModel *m = 0;
|
Chris@868
|
151
|
Chris@868
|
152 // get the topmost such
|
Chris@868
|
153 for (int i = 0; i < m_above->getLayerCount(); ++i) {
|
Chris@1266
|
154 if (qobject_cast<TimeInstantLayer *>(m_above->getLayer(i))) {
|
Chris@1266
|
155 SparseOneDimensionalModel *mm =
|
Chris@1266
|
156 qobject_cast<SparseOneDimensionalModel *>
|
Chris@1266
|
157 (m_above->getLayer(i)->getModel());
|
Chris@1266
|
158 if (mm) m = mm;
|
Chris@1266
|
159 }
|
Chris@868
|
160 }
|
Chris@868
|
161
|
Chris@868
|
162 if (!m) {
|
Chris@1266
|
163 return getDefaultKeyFrames();
|
Chris@868
|
164 }
|
Chris@868
|
165
|
Chris@976
|
166 vector<sv_frame_t> keyFrames;
|
Chris@868
|
167
|
Chris@868
|
168 const SparseOneDimensionalModel::PointList pp = m->getPoints();
|
Chris@868
|
169 for (SparseOneDimensionalModel::PointList::const_iterator pi = pp.begin();
|
Chris@1266
|
170 pi != pp.end(); ++pi) {
|
Chris@1266
|
171 keyFrames.push_back(pi->frame);
|
Chris@868
|
172 }
|
Chris@868
|
173
|
Chris@868
|
174 return keyFrames;
|
Chris@868
|
175 }
|
Chris@868
|
176
|
Chris@976
|
177 vector<sv_frame_t>
|
Chris@868
|
178 AlignmentView::getDefaultKeyFrames()
|
Chris@868
|
179 {
|
Chris@976
|
180 vector<sv_frame_t> keyFrames;
|
Chris@868
|
181
|
Chris@868
|
182 if (!m_above || !m_manager) return keyFrames;
|
Chris@868
|
183
|
Chris@976
|
184 sv_samplerate_t rate = m_manager->getMainModelSampleRate();
|
Chris@868
|
185 if (rate == 0) return keyFrames;
|
Chris@868
|
186
|
Chris@976
|
187 for (sv_frame_t f = m_above->getModelsStartFrame();
|
Chris@1266
|
188 f <= m_above->getModelsEndFrame();
|
Chris@1266
|
189 f += sv_frame_t(rate * 5 + 0.5)) {
|
Chris@1266
|
190 keyFrames.push_back(f);
|
Chris@868
|
191 }
|
Chris@868
|
192
|
Chris@868
|
193 return keyFrames;
|
Chris@868
|
194 }
|
Chris@868
|
195
|
Chris@868
|
196
|
Chris@868
|
197
|
Chris@868
|
198
|
Chris@868
|
199
|
Chris@868
|
200
|