Mercurial > hg > svgui
comparison layer/WaveformLayer.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 | f2c416cbdaa9 |
children | fedaf3ffe80a |
comparison
equal
deleted
inserted
replaced
43:78515b1e29eb | 44:ad214997dddb |
---|---|
22 //#define DEBUG_WAVEFORM_PAINT 1 | 22 //#define DEBUG_WAVEFORM_PAINT 1 |
23 | 23 |
24 using std::cerr; | 24 using std::cerr; |
25 using std::endl; | 25 using std::endl; |
26 | 26 |
27 WaveformLayer::WaveformLayer(View *w) : | 27 WaveformLayer::WaveformLayer() : |
28 Layer(w), | 28 Layer(), |
29 m_model(0), | 29 m_model(0), |
30 m_gain(1.0f), | 30 m_gain(1.0f), |
31 m_colour(Qt::black), | 31 m_colour(Qt::black), |
32 m_showMeans(true), | 32 m_showMeans(true), |
33 m_greyscale(true), | 33 m_greyscale(true), |
36 m_scale(LinearScale), | 36 m_scale(LinearScale), |
37 m_aggressive(false), | 37 m_aggressive(false), |
38 m_cache(0), | 38 m_cache(0), |
39 m_cacheValid(false) | 39 m_cacheValid(false) |
40 { | 40 { |
41 m_view->addLayer(this); | 41 |
42 } | 42 } |
43 | 43 |
44 WaveformLayer::~WaveformLayer() | 44 WaveformLayer::~WaveformLayer() |
45 { | 45 { |
46 delete m_cache; | 46 delete m_cache; |
331 | 331 |
332 return channels; | 332 return channels; |
333 } | 333 } |
334 | 334 |
335 void | 335 void |
336 WaveformLayer::paint(QPainter &viewPainter, QRect rect) const | 336 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const |
337 { | 337 { |
338 if (!m_model || !m_model->isOK()) { | 338 if (!m_model || !m_model->isOK()) { |
339 return; | 339 return; |
340 } | 340 } |
341 | 341 |
342 long startFrame = m_view->getStartFrame(); | 342 long startFrame = v->getStartFrame(); |
343 int zoomLevel = m_view->getZoomLevel(); | 343 int zoomLevel = v->getZoomLevel(); |
344 | 344 |
345 #ifdef DEBUG_WAVEFORM_PAINT | 345 #ifdef DEBUG_WAVEFORM_PAINT |
346 Profiler profiler("WaveformLayer::paint", true); | 346 Profiler profiler("WaveformLayer::paint", true); |
347 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() | 347 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() |
348 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << ", start " << startFrame << std::endl; | 348 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << ", start " << startFrame << std::endl; |
352 bool mergingChannels = false; | 352 bool mergingChannels = false; |
353 | 353 |
354 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); | 354 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); |
355 if (channels == 0) return; | 355 if (channels == 0) return; |
356 | 356 |
357 int w = m_view->width(); | 357 int w = v->width(); |
358 int h = m_view->height(); | 358 int h = v->height(); |
359 | 359 |
360 bool ready = m_model->isReady(); | 360 bool ready = m_model->isReady(); |
361 QPainter *paint; | 361 QPainter *paint; |
362 | 362 |
363 if (m_aggressive) { | 363 if (m_aggressive) { |
377 } | 377 } |
378 | 378 |
379 paint = new QPainter(m_cache); | 379 paint = new QPainter(m_cache); |
380 | 380 |
381 paint->setPen(Qt::NoPen); | 381 paint->setPen(Qt::NoPen); |
382 paint->setBrush(m_view->palette().background()); | 382 paint->setBrush(v->palette().background()); |
383 paint->drawRect(rect); | 383 paint->drawRect(rect); |
384 | 384 |
385 paint->setPen(Qt::black); | 385 paint->setPen(Qt::black); |
386 paint->setBrush(Qt::NoBrush); | 386 paint->setBrush(Qt::NoBrush); |
387 | 387 |
398 x1 = rect.right(); | 398 x1 = rect.right(); |
399 y0 = rect.top(); | 399 y0 = rect.top(); |
400 y1 = rect.bottom(); | 400 y1 = rect.bottom(); |
401 | 401 |
402 if (x0 > 0) --x0; | 402 if (x0 > 0) --x0; |
403 if (x1 < m_view->width()) ++x1; | 403 if (x1 < v->width()) ++x1; |
404 | 404 |
405 long frame0 = getFrameForX(x0); | 405 long frame0 = v->getFrameForX(x0); |
406 long frame1 = getFrameForX(x1 + 1); | 406 long frame1 = v->getFrameForX(x1 + 1); |
407 | 407 |
408 #ifdef DEBUG_WAVEFORM_PAINT | 408 #ifdef DEBUG_WAVEFORM_PAINT |
409 std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << ")" << std::endl; | 409 std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << ")" << std::endl; |
410 #endif | 410 #endif |
411 | 411 |
418 for (int i = 0; i < 3; ++i) { // 0 lightest, 2 darkest | 418 for (int i = 0; i < 3; ++i) { // 0 lightest, 2 darkest |
419 int level = 192 - 64 * i; | 419 int level = 192 - 64 * i; |
420 greys[i] = QColor(level, level, level); | 420 greys[i] = QColor(level, level, level); |
421 } | 421 } |
422 } else { | 422 } else { |
423 int h, s, v; | 423 int hue, sat, val; |
424 m_colour.getHsv(&h, &s, &v); | 424 m_colour.getHsv(&hue, &sat, &val); |
425 for (int i = 0; i < 3; ++i) { // 0 lightest, 2 darkest | 425 for (int i = 0; i < 3; ++i) { // 0 lightest, 2 darkest |
426 if (m_view->hasLightBackground()) { | 426 if (v->hasLightBackground()) { |
427 greys[i] = QColor::fromHsv(h, s * (i + 1) / 4, v); | 427 greys[i] = QColor::fromHsv(hue, sat * (i + 1) / 4, val); |
428 } else { | 428 } else { |
429 greys[i] = QColor::fromHsv(h, s * (3 - i) / 4, v); | 429 greys[i] = QColor::fromHsv(hue, sat * (3 - i) / 4, val); |
430 } | 430 } |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 QColor midColour = m_colour; | 434 QColor midColour = m_colour; |
435 if (midColour == Qt::black) { | 435 if (midColour == Qt::black) { |
436 midColour = Qt::gray; | 436 midColour = Qt::gray; |
437 } else if (m_view->hasLightBackground()) { | 437 } else if (v->hasLightBackground()) { |
438 midColour = midColour.light(150); | 438 midColour = midColour.light(150); |
439 } else { | 439 } else { |
440 midColour = midColour.light(50); | 440 midColour = midColour.light(50); |
441 } | 441 } |
442 | 442 |
658 } | 658 } |
659 } | 659 } |
660 | 660 |
661 if (m_aggressive) { | 661 if (m_aggressive) { |
662 | 662 |
663 if (ready && rect == m_view->rect()) { | 663 if (ready && rect == v->rect()) { |
664 m_cacheValid = true; | 664 m_cacheValid = true; |
665 m_cacheZoomLevel = zoomLevel; | 665 m_cacheZoomLevel = zoomLevel; |
666 } | 666 } |
667 paint->end(); | 667 paint->end(); |
668 delete paint; | 668 delete paint; |
669 viewPainter.drawPixmap(rect, *m_cache, rect); | 669 viewPainter.drawPixmap(rect, *m_cache, rect); |
670 } | 670 } |
671 } | 671 } |
672 | 672 |
673 QString | 673 QString |
674 WaveformLayer::getFeatureDescription(QPoint &pos) const | 674 WaveformLayer::getFeatureDescription(View *v, QPoint &pos) const |
675 { | 675 { |
676 int x = pos.x(); | 676 int x = pos.x(); |
677 | 677 |
678 if (!m_model || !m_model->isOK()) return ""; | 678 if (!m_model || !m_model->isOK()) return ""; |
679 | 679 |
680 long f0 = getFrameForX(x); | 680 long f0 = v->getFrameForX(x); |
681 long f1 = getFrameForX(x + 1); | 681 long f1 = v->getFrameForX(x + 1); |
682 | 682 |
683 if (f0 < 0) f0 = 0; | 683 if (f0 < 0) f0 = 0; |
684 if (f1 <= f0) return ""; | 684 if (f1 <= f0) return ""; |
685 | 685 |
686 QString text; | 686 QString text; |
703 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); | 703 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); |
704 if (channels == 0) return ""; | 704 if (channels == 0) return ""; |
705 | 705 |
706 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { | 706 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { |
707 | 707 |
708 size_t blockSize = m_view->getZoomLevel(); | 708 size_t blockSize = v->getZoomLevel(); |
709 RangeSummarisableTimeValueModel::RangeBlock ranges = | 709 RangeSummarisableTimeValueModel::RangeBlock ranges = |
710 m_model->getRanges(ch, f0, f1, blockSize); | 710 m_model->getRanges(ch, f0, f1, blockSize); |
711 | 711 |
712 if (ranges.empty()) continue; | 712 if (ranges.empty()) continue; |
713 | 713 |
737 | 737 |
738 return text; | 738 return text; |
739 } | 739 } |
740 | 740 |
741 int | 741 int |
742 WaveformLayer::getVerticalScaleWidth(QPainter &paint) const | 742 WaveformLayer::getVerticalScaleWidth(View *v, QPainter &paint) const |
743 { | 743 { |
744 if (m_scale == LinearScale) { | 744 if (m_scale == LinearScale) { |
745 return paint.fontMetrics().width("0.0") + 13; | 745 return paint.fontMetrics().width("0.0") + 13; |
746 } else { | 746 } else { |
747 return std::max(paint.fontMetrics().width(tr("0dB")), | 747 return std::max(paint.fontMetrics().width(tr("0dB")), |
748 paint.fontMetrics().width(tr("-Inf"))) + 13; | 748 paint.fontMetrics().width(tr("-Inf"))) + 13; |
749 } | 749 } |
750 } | 750 } |
751 | 751 |
752 void | 752 void |
753 WaveformLayer::paintVerticalScale(QPainter &paint, QRect rect) const | 753 WaveformLayer::paintVerticalScale(View *v, QPainter &paint, QRect rect) const |
754 { | 754 { |
755 if (!m_model || !m_model->isOK()) { | 755 if (!m_model || !m_model->isOK()) { |
756 return; | 756 return; |
757 } | 757 } |
758 | 758 |