Mercurial > hg > svgui
comparison widgets/Panner.cpp @ 0:2a4f26e85b4c
initial import
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2006 16:33:16 +0000 |
parents | |
children | 37b110168acf |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:2a4f26e85b4c |
---|---|
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 A waveform viewer and audio annotation editor. | |
5 Chris Cannam, Queen Mary University of London, 2005 | |
6 | |
7 This is experimental software. Not for distribution. | |
8 */ | |
9 | |
10 #include "Panner.h" | |
11 #include "base/Layer.h" | |
12 #include "base/Model.h" | |
13 #include "base/ZoomConstraint.h" | |
14 | |
15 #include <QPaintEvent> | |
16 #include <QPainter> | |
17 #include <iostream> | |
18 | |
19 using std::cerr; | |
20 using std::endl; | |
21 | |
22 Panner::Panner(QWidget *w) : | |
23 View(w, false), | |
24 m_clickedInRange(false) | |
25 { | |
26 setObjectName(tr("Panner")); | |
27 m_followPan = false; | |
28 m_followZoom = false; | |
29 } | |
30 | |
31 void | |
32 Panner::modelChanged(size_t startFrame, size_t endFrame) | |
33 { | |
34 View::modelChanged(startFrame, endFrame); | |
35 } | |
36 | |
37 void | |
38 Panner::modelReplaced() | |
39 { | |
40 View::modelReplaced(); | |
41 } | |
42 | |
43 void | |
44 Panner::registerView(View *widget) | |
45 { | |
46 m_widgets[widget] = WidgetRec(0, -1); | |
47 update(); | |
48 } | |
49 | |
50 void | |
51 Panner::unregisterView(View *widget) | |
52 { | |
53 m_widgets.erase(widget); | |
54 update(); | |
55 } | |
56 | |
57 void | |
58 Panner::viewManagerCentreFrameChanged(void *p, unsigned long f, bool) | |
59 { | |
60 // std::cerr << "Panner[" << this << "]::viewManagerCentreFrameChanged(" | |
61 // << p << ", " << f << ")" << std::endl; | |
62 | |
63 if (p == this) return; | |
64 if (m_widgets.find(p) != m_widgets.end()) { | |
65 m_widgets[p].first = f; | |
66 update(); | |
67 } | |
68 } | |
69 | |
70 void | |
71 Panner::viewManagerZoomLevelChanged(void *p, unsigned long z, bool) | |
72 { | |
73 if (p == this) return; | |
74 if (m_widgets.find(p) != m_widgets.end()) { | |
75 m_widgets[p].second = z; | |
76 update(); | |
77 } | |
78 } | |
79 | |
80 void | |
81 Panner::viewManagerPlaybackFrameChanged(unsigned long f) | |
82 { | |
83 bool changed = false; | |
84 | |
85 if (m_playPointerFrame / m_zoomLevel != f / m_zoomLevel) changed = true; | |
86 m_playPointerFrame = f; | |
87 | |
88 for (WidgetMap::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { | |
89 unsigned long of = i->second.first; | |
90 i->second.first = f; | |
91 if (of / m_zoomLevel != f / m_zoomLevel) changed = true; | |
92 } | |
93 | |
94 if (changed) update(); | |
95 } | |
96 | |
97 void | |
98 Panner::paintEvent(QPaintEvent *e) | |
99 { | |
100 /*!!! | |
101 // Force View to recalculate zoom in case the size of the | |
102 // widget has changed. (We need a better name/mechanism for this) | |
103 m_newModel = true; | |
104 */ | |
105 | |
106 // Recalculate zoom in case the size of the widget has changed. | |
107 | |
108 size_t startFrame = getModelsStartFrame(); | |
109 size_t frameCount = getModelsEndFrame() - getModelsStartFrame(); | |
110 int zoomLevel = frameCount / width(); | |
111 if (zoomLevel < 1) zoomLevel = 1; | |
112 zoomLevel = getZoomConstraintBlockSize(zoomLevel, | |
113 ZoomConstraint::RoundUp); | |
114 if (zoomLevel != m_zoomLevel) { | |
115 m_zoomLevel = zoomLevel; | |
116 emit zoomLevelChanged(this, m_zoomLevel, m_followZoom); | |
117 } | |
118 size_t centreFrame = startFrame + m_zoomLevel * (width() / 2); | |
119 if (centreFrame > (startFrame + getModelsEndFrame())/2) { | |
120 centreFrame = (startFrame + getModelsEndFrame())/2; | |
121 } | |
122 if (centreFrame != m_centreFrame) { | |
123 m_centreFrame = centreFrame; | |
124 emit centreFrameChanged(this, m_centreFrame, false); | |
125 } | |
126 | |
127 View::paintEvent(e); | |
128 | |
129 QPainter paint; | |
130 paint.begin(this); | |
131 | |
132 QRect r(rect()); | |
133 | |
134 if (e) { | |
135 r = e->rect(); | |
136 paint.setClipRect(r); | |
137 } | |
138 | |
139 paint.setPen(Qt::black); | |
140 | |
141 int y = 0; | |
142 long prevCentre = 0; | |
143 long prevZoom = -1; | |
144 | |
145 for (WidgetMap::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { | |
146 if (!i->first) continue; | |
147 | |
148 View *w = (View *)i->first; | |
149 if (i->second.second < 0) i->second.second = w->getZoomLevel(); | |
150 if (i->second.second < 0) continue; | |
151 | |
152 long c = (long)i->second.first; | |
153 long z = (long)i->second.second; | |
154 | |
155 long f0 = c - (w->width() / 2) * z; | |
156 long f1 = c + (w->width() / 2) * z; | |
157 | |
158 int x0 = (f0 - long(getCentreFrame())) / getZoomLevel() + width()/2; | |
159 int x1 = (f1 - long(getCentreFrame())) / getZoomLevel() + width()/2 - 1; | |
160 | |
161 if (c != prevCentre || z != prevZoom) { | |
162 y += height() / 10 + 1; | |
163 prevCentre = c; | |
164 prevZoom = z; | |
165 } | |
166 | |
167 paint.drawRect(x0, y, x1 - x0, height() - 2 * y); | |
168 } | |
169 | |
170 paint.end(); | |
171 } | |
172 | |
173 void | |
174 Panner::mousePressEvent(QMouseEvent *e) | |
175 { | |
176 m_clickPos = e->pos(); | |
177 for (WidgetMap::iterator i = m_widgets.begin(); i != m_widgets.end(); ++i) { | |
178 if (i->first && i->second.second >= 0) { | |
179 m_clickedInRange = true; | |
180 m_dragCentreFrame = i->second.first; | |
181 } | |
182 } | |
183 } | |
184 | |
185 void | |
186 Panner::mouseReleaseEvent(QMouseEvent *e) | |
187 { | |
188 if (m_clickedInRange) { | |
189 mouseMoveEvent(e); | |
190 } | |
191 m_clickedInRange = false; | |
192 } | |
193 | |
194 void | |
195 Panner::mouseMoveEvent(QMouseEvent *e) | |
196 { | |
197 if (!m_clickedInRange) return; | |
198 | |
199 /*!!! | |
200 long newFrame = getStartFrame() + e->x() * m_zoomLevel; | |
201 | |
202 if (newFrame < 0) newFrame = 0; | |
203 if (newFrame >= getModelsEndFrame()) { | |
204 newFrame = getModelsEndFrame(); | |
205 if (newFrame > 0) --newFrame; | |
206 } | |
207 emit centreFrameChanged(this, newFrame, true); | |
208 */ | |
209 | |
210 long xoff = int(e->x()) - int(m_clickPos.x()); | |
211 long frameOff = xoff * m_zoomLevel; | |
212 | |
213 size_t newCentreFrame = m_dragCentreFrame; | |
214 if (frameOff > 0) { | |
215 newCentreFrame += frameOff; | |
216 } else if (newCentreFrame >= size_t(-frameOff)) { | |
217 newCentreFrame += frameOff; | |
218 } else { | |
219 newCentreFrame = 0; | |
220 } | |
221 | |
222 if (newCentreFrame >= getModelsEndFrame()) { | |
223 newCentreFrame = getModelsEndFrame(); | |
224 if (newCentreFrame > 0) --newCentreFrame; | |
225 } | |
226 | |
227 if (std::max(m_centreFrame, newCentreFrame) - | |
228 std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) { | |
229 emit centreFrameChanged(this, newCentreFrame, true); | |
230 } | |
231 } | |
232 | |
233 #ifdef INCLUDE_MOCFILES | |
234 #include "Panner.moc.cpp" | |
235 #endif | |
236 |