Mercurial > hg > svgui
comparison layer/Colour3DPlotLayer.cpp @ 44:ad214997dddb
* Refactor Layer classes so as no longer to store a single View pointer;
instead they need to be able to draw themselves on any View on demand.
Layers with caches (e.g. spectrogram) will need to be further refactored
so as to maintain a per-View cache
* Begin refactoring MainWindow by pulling out the document stuff (set of
layers, models etc) into a Document class. Not yet in use.
This revision is fairly unstable.
author | Chris Cannam |
---|---|
date | Thu, 02 Mar 2006 16:58:49 +0000 |
parents | 202d1dca67d2 |
children | 8dae7f6732c1 |
comparison
equal
deleted
inserted
replaced
43:78515b1e29eb | 44:ad214997dddb |
---|---|
19 #include <iostream> | 19 #include <iostream> |
20 | 20 |
21 #include <cassert> | 21 #include <cassert> |
22 | 22 |
23 | 23 |
24 Colour3DPlotLayer::Colour3DPlotLayer(View *w) : | 24 Colour3DPlotLayer::Colour3DPlotLayer() : |
25 Layer(w), | 25 Layer(), |
26 m_model(0), | 26 m_model(0), |
27 m_cache(0) | 27 m_cache(0) |
28 { | 28 { |
29 m_view->addLayer(this); | 29 |
30 } | 30 } |
31 | 31 |
32 Colour3DPlotLayer::~Colour3DPlotLayer() | 32 Colour3DPlotLayer::~Colour3DPlotLayer() |
33 { | 33 { |
34 } | 34 } |
65 { | 65 { |
66 cacheInvalid(); | 66 cacheInvalid(); |
67 } | 67 } |
68 | 68 |
69 bool | 69 bool |
70 Colour3DPlotLayer::isLayerScrollable() const | 70 Colour3DPlotLayer::isLayerScrollable(const View *v) const |
71 { | 71 { |
72 QPoint discard; | 72 QPoint discard; |
73 return !m_view->shouldIlluminateLocalFeatures(this, discard); | 73 return !v->shouldIlluminateLocalFeatures(this, discard); |
74 } | 74 } |
75 | 75 |
76 QString | 76 QString |
77 Colour3DPlotLayer::getFeatureDescription(QPoint &pos) const | 77 Colour3DPlotLayer::getFeatureDescription(View *v, QPoint &pos) const |
78 { | 78 { |
79 if (!m_model) return ""; | 79 if (!m_model) return ""; |
80 | 80 |
81 int x = pos.x(); | 81 int x = pos.x(); |
82 int y = pos.y(); | 82 int y = pos.y(); |
83 | 83 |
84 size_t modelStart = m_model->getStartFrame(); | 84 size_t modelStart = m_model->getStartFrame(); |
85 size_t modelWindow = m_model->getWindowSize(); | 85 size_t modelWindow = m_model->getWindowSize(); |
86 | 86 |
87 int sx0 = modelWindow * | 87 int sx0 = modelWindow * |
88 int((getFrameForX(x) - long(modelStart)) / long(modelWindow)); | 88 int((v->getFrameForX(x) - long(modelStart)) / long(modelWindow)); |
89 int sx1 = sx0 + modelWindow; | 89 int sx1 = sx0 + modelWindow; |
90 | 90 |
91 float binHeight = float(m_view->height()) / m_model->getYBinCount(); | 91 float binHeight = float(v->height()) / m_model->getYBinCount(); |
92 int sy = (m_view->height() - y) / binHeight; | 92 int sy = (v->height() - y) / binHeight; |
93 | 93 |
94 float value = m_model->getBinValue(sx0, sy); | 94 float value = m_model->getBinValue(sx0, sy); |
95 | 95 |
96 QString binName = m_model->getBinName(sy); | 96 QString binName = m_model->getBinName(sy); |
97 if (binName == "") binName = QString("[%1]").arg(sy + 1); | 97 if (binName == "") binName = QString("[%1]").arg(sy + 1); |
107 | 107 |
108 return text; | 108 return text; |
109 } | 109 } |
110 | 110 |
111 int | 111 int |
112 Colour3DPlotLayer::getVerticalScaleWidth(QPainter &paint) const | 112 Colour3DPlotLayer::getVerticalScaleWidth(View *v, QPainter &paint) const |
113 { | 113 { |
114 if (!m_model) return 0; | 114 if (!m_model) return 0; |
115 | 115 |
116 QString sampleText("123"); | 116 QString sampleText("123"); |
117 int tw = paint.fontMetrics().width(sampleText); | 117 int tw = paint.fontMetrics().width(sampleText); |
127 | 127 |
128 return tw + 13; | 128 return tw + 13; |
129 } | 129 } |
130 | 130 |
131 void | 131 void |
132 Colour3DPlotLayer::paintVerticalScale(QPainter &paint, QRect rect) const | 132 Colour3DPlotLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const |
133 { | 133 { |
134 if (!m_model) return; | 134 if (!m_model) return; |
135 | 135 |
136 int h = rect.height(), w = rect.width(); | 136 int h = rect.height(), w = rect.width(); |
137 float binHeight = float(m_view->height()) / m_model->getYBinCount(); | 137 float binHeight = float(v->height()) / m_model->getYBinCount(); |
138 | 138 |
139 // int textHeight = paint.fontMetrics().height(); | 139 // int textHeight = paint.fontMetrics().height(); |
140 // int toff = -textHeight + paint.fontMetrics().ascent() + 2; | 140 // int toff = -textHeight + paint.fontMetrics().ascent() + 2; |
141 | 141 |
142 for (size_t i = 0; i < m_model->getYBinCount(); ++i) { | 142 for (size_t i = 0; i < m_model->getYBinCount(); ++i) { |
143 | 143 |
144 int y0 = m_view->height() - (i * binHeight) - 1; | 144 int y0 = v->height() - (i * binHeight) - 1; |
145 | 145 |
146 QString text = m_model->getBinName(i); | 146 QString text = m_model->getBinName(i); |
147 if (text == "") text = QString("[%1]").arg(i + 1); | 147 if (text == "") text = QString("[%1]").arg(i + 1); |
148 | 148 |
149 paint.drawLine(0, y0, w, y0); | 149 paint.drawLine(0, y0, w, y0); |
155 paint.drawText(10, ty, text); | 155 paint.drawText(10, ty, text); |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 void | 159 void |
160 Colour3DPlotLayer::paint(QPainter &paint, QRect rect) const | 160 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const |
161 { | 161 { |
162 // Profiler profiler("Colour3DPlotLayer::paint"); | 162 // Profiler profiler("Colour3DPlotLayer::paint"); |
163 // std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << m_view->getZoomLevel() << std::endl; | 163 // std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl; |
164 | 164 |
165 //!!! This doesn't yet accommodate the fact that the model may | 165 //!!! This doesn't yet accommodate the fact that the model may |
166 //have a different sample rate from an underlying model. At the | 166 //have a different sample rate from an underlying model. At the |
167 //moment our paint mechanism assumes all models have the same | 167 //moment our paint mechanism assumes all models have the same |
168 //sample rate. If that isn't the case, they won't align and the | 168 //sample rate. If that isn't the case, they won't align and the |
174 //samplerate.) | 174 //samplerate.) |
175 | 175 |
176 int completion = 0; | 176 int completion = 0; |
177 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) { | 177 if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) { |
178 if (completion > 0) { | 178 if (completion > 0) { |
179 paint.fillRect(0, 10, m_view->width() * completion / 100, | 179 paint.fillRect(0, 10, v->width() * completion / 100, |
180 10, QColor(120, 120, 120)); | 180 10, QColor(120, 120, 120)); |
181 } | 181 } |
182 return; | 182 return; |
183 } | 183 } |
184 | 184 |
185 long startFrame = m_view->getStartFrame(); | 185 long startFrame = v->getStartFrame(); |
186 int zoomLevel = m_view->getZoomLevel(); | 186 int zoomLevel = v->getZoomLevel(); |
187 | 187 |
188 size_t modelStart = m_model->getStartFrame(); | 188 size_t modelStart = m_model->getStartFrame(); |
189 size_t modelEnd = m_model->getEndFrame(); | 189 size_t modelEnd = m_model->getEndFrame(); |
190 size_t modelWindow = m_model->getWindowSize(); | 190 size_t modelWindow = m_model->getWindowSize(); |
191 | 191 |
259 int x1 = rect.right() + 1; | 259 int x1 = rect.right() + 1; |
260 | 260 |
261 // int y0 = rect.top(); | 261 // int y0 = rect.top(); |
262 // int y1 = rect.bottom(); | 262 // int y1 = rect.bottom(); |
263 int w = x1 - x0; | 263 int w = x1 - x0; |
264 int h = m_view->height(); | 264 int h = v->height(); |
265 | 265 |
266 // The cache is from the model's start frame to the model's end | 266 // The cache is from the model's start frame to the model's end |
267 // frame at the model's window increment frames per pixel. We | 267 // frame at the model's window increment frames per pixel. We |
268 // want to draw from our start frame + x0 * zoomLevel to our start | 268 // want to draw from our start frame + x0 * zoomLevel to our start |
269 // frame + x1 * zoomLevel at zoomLevel frames per pixel. | 269 // frame + x1 * zoomLevel at zoomLevel frames per pixel. |
271 //!!! Strictly speaking we want quite different paint mechanisms | 271 //!!! Strictly speaking we want quite different paint mechanisms |
272 //for models that have more than one bin per pixel in either | 272 //for models that have more than one bin per pixel in either |
273 //direction. This one is only really appropriate for models with | 273 //direction. This one is only really appropriate for models with |
274 //far fewer bins in both directions. | 274 //far fewer bins in both directions. |
275 | 275 |
276 int sx0 = int((getFrameForX(x0) - long(modelStart)) / long(modelWindow)); | 276 int sx0 = int((v->getFrameForX(x0) - long(modelStart)) / long(modelWindow)); |
277 int sx1 = int((getFrameForX(x1) - long(modelStart)) / long(modelWindow)); | 277 int sx1 = int((v->getFrameForX(x1) - long(modelStart)) / long(modelWindow)); |
278 int sw = sx1 - sx0; | 278 int sw = sx1 - sx0; |
279 int sh = m_model->getYBinCount(); | 279 int sh = m_model->getYBinCount(); |
280 | 280 |
281 /* | 281 /* |
282 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl; | 282 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl; |
283 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", window size " << m_model->getWindowSize() << std::endl; | 283 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", window size " << m_model->getWindowSize() << std::endl; |
284 */ | 284 */ |
285 | 285 |
286 QPoint illuminatePos; | 286 QPoint illuminatePos; |
287 bool illuminate = m_view->shouldIlluminateLocalFeatures(this, illuminatePos); | 287 bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos); |
288 | 288 |
289 for (int sx = sx0 - 1; sx <= sx1; ++sx) { | 289 for (int sx = sx0 - 1; sx <= sx1; ++sx) { |
290 | 290 |
291 int fx = sx * int(modelWindow); | 291 int fx = sx * int(modelWindow); |
292 | 292 |
293 if (fx + modelWindow < int(modelStart) || | 293 if (fx + modelWindow < int(modelStart) || |
294 fx > int(modelEnd)) continue; | 294 fx > int(modelEnd)) continue; |
295 | 295 |
296 for (int sy = 0; sy < sh; ++sy) { | 296 for (int sy = 0; sy < sh; ++sy) { |
297 | 297 |
298 int rx0 = getXForFrame(fx + int(modelStart)); | 298 int rx0 = v->getXForFrame(fx + int(modelStart)); |
299 int rx1 = getXForFrame(fx + int(modelStart) + int(modelWindow)); | 299 int rx1 = v->getXForFrame(fx + int(modelStart) + int(modelWindow)); |
300 | 300 |
301 int ry0 = h - (sy * h) / sh - 1; | 301 int ry0 = h - (sy * h) / sh - 1; |
302 int ry1 = h - ((sy + 1) * h) / sh - 2; | 302 int ry1 = h - ((sy + 1) * h) / sh - 2; |
303 QRgb pixel = qRgb(255, 255, 255); | 303 QRgb pixel = qRgb(255, 255, 255); |
304 if (sx >= 0 && sx < m_cache->width() && | 304 if (sx >= 0 && sx < m_cache->width() && |
373 paint.drawImage(x0, 0, scaled); | 373 paint.drawImage(x0, 0, scaled); |
374 */ | 374 */ |
375 } | 375 } |
376 | 376 |
377 bool | 377 bool |
378 Colour3DPlotLayer::snapToFeatureFrame(int &frame, | 378 Colour3DPlotLayer::snapToFeatureFrame(View *v, int &frame, |
379 size_t &resolution, | 379 size_t &resolution, |
380 SnapType snap) const | 380 SnapType snap) const |
381 { | 381 { |
382 if (!m_model) { | 382 if (!m_model) { |
383 return Layer::snapToFeatureFrame(frame, resolution, snap); | 383 return Layer::snapToFeatureFrame(v, frame, resolution, snap); |
384 } | 384 } |
385 | 385 |
386 resolution = m_model->getWindowSize(); | 386 resolution = m_model->getWindowSize(); |
387 int left = (frame / resolution) * resolution; | 387 int left = (frame / resolution) * resolution; |
388 int right = left + resolution; | 388 int right = left + resolution; |