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
|