comparison view/Panner.cpp @ 127:89c625dda204

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