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