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