Mercurial > hg > svgui
comparison view/Pane.cpp @ 261:11021509c4eb
* some more work on measurement tool, and refactor Pane::paintEvent
author | Chris Cannam |
---|---|
date | Thu, 14 Jun 2007 16:28:27 +0000 |
parents | 6d113226bb4c |
children | dae479593572 |
comparison
equal
deleted
inserted
replaced
260:6d113226bb4c | 261:11021509c4eb |
---|---|
358 // Profiler profiler("Pane::paintEvent", true); | 358 // Profiler profiler("Pane::paintEvent", true); |
359 | 359 |
360 QPainter paint; | 360 QPainter paint; |
361 | 361 |
362 QRect r(rect()); | 362 QRect r(rect()); |
363 | 363 if (e) r = e->rect(); |
364 if (e) { | 364 |
365 r = e->rect(); | 365 View::paintEvent(e); |
366 } | 366 |
367 /* | |
368 paint.begin(this); | 367 paint.begin(this); |
369 paint.setClipRect(r); | 368 |
370 | 369 if (e) paint.setClipRect(r); |
371 if (hasLightBackground()) { | |
372 paint.setPen(Qt::white); | |
373 paint.setBrush(Qt::white); | |
374 } else { | |
375 paint.setPen(Qt::black); | |
376 paint.setBrush(Qt::black); | |
377 } | |
378 paint.drawRect(r); | |
379 | |
380 paint.end(); | |
381 */ | |
382 View::paintEvent(e); | |
383 | |
384 paint.begin(this); | |
385 | |
386 if (e) { | |
387 paint.setClipRect(r); | |
388 } | |
389 | |
390 int fontHeight = paint.fontMetrics().height(); | |
391 int fontAscent = paint.fontMetrics().ascent(); | |
392 | 370 |
393 ViewManager::ToolMode toolMode = m_manager->getToolMode(); | 371 ViewManager::ToolMode toolMode = m_manager->getToolMode(); |
394 | 372 |
395 if (m_manager && | 373 if (m_manager && |
396 !m_manager->isPlaying() && | 374 !m_manager->isPlaying() && |
420 waveformModel = (*vi)->getModel(); | 398 waveformModel = (*vi)->getModel(); |
421 break; | 399 break; |
422 } | 400 } |
423 } | 401 } |
424 | 402 |
403 m_scaleWidth = 0; | |
404 | |
405 if (m_manager && m_manager->shouldShowVerticalScale() && topLayer) { | |
406 drawVerticalScale(r, topLayer, paint); | |
407 } | |
408 | |
409 if (m_identifyFeatures && topLayer) { | |
410 drawFeatureDescription(topLayer, paint); | |
411 } | |
412 | |
413 int sampleRate = getModelsSampleRate(); | |
414 paint.setBrush(Qt::NoBrush); | |
415 | |
416 if (m_centreLineVisible && | |
417 m_manager && | |
418 m_manager->shouldShowCentreLine()) { | |
419 drawCentreLine(sampleRate, paint); | |
420 } | |
421 | |
422 paint.setPen(QColor(50, 50, 50)); | |
423 | |
424 if (waveformModel && | |
425 m_manager && | |
426 m_manager->shouldShowDuration()) { | |
427 drawDurationAndRate(r, waveformModel, sampleRate, paint); | |
428 } | |
429 | |
430 if (m_manager && | |
431 m_manager->shouldShowLayerNames()) { | |
432 drawLayerNames(r, paint); | |
433 } | |
434 | |
435 if (m_clickedInRange && m_manager) { | |
436 | |
437 //!!! be nice if this looked a bit more in keeping with the | |
438 //selection block | |
439 | |
440 if (m_shiftPressed && toolMode == ViewManager::NavigateMode) { | |
441 | |
442 paint.setPen(Qt::blue); | |
443 //!!! shouldn't use clickPos -- needs to use a clicked frame | |
444 paint.drawRect(m_clickPos.x(), m_clickPos.y(), | |
445 m_mousePos.x() - m_clickPos.x(), | |
446 m_mousePos.y() - m_clickPos.y()); | |
447 | |
448 } else if (toolMode == ViewManager::MeasureMode && topLayer) { | |
449 | |
450 drawMeasurementRect(topLayer, paint); | |
451 } | |
452 } | |
453 | |
454 if (selectionIsBeingEdited()) { | |
455 drawEditingSelection(paint); | |
456 } | |
457 | |
458 paint.end(); | |
459 } | |
460 | |
461 void | |
462 Pane::drawVerticalScale(QRect r, Layer *topLayer, QPainter &paint) | |
463 { | |
425 Layer *scaleLayer = 0; | 464 Layer *scaleLayer = 0; |
426 | 465 |
427 if (m_manager && m_manager->shouldShowVerticalScale() && topLayer) { | 466 float min, max; |
428 | 467 bool log; |
429 float min, max; | 468 QString unit; |
430 bool log; | 469 |
431 QString unit; | 470 // If the top layer has no scale and reports no display |
432 | 471 // extents, but does report a unit, then the scale should be |
433 // If the top layer has no scale and reports no display | 472 // drawn from any underlying layer with a scale and that unit. |
434 // extents, but does report a unit, then the scale should be | 473 // If the top layer has no scale and no value extents at all, |
435 // drawn from any underlying layer with a scale and that unit. | 474 // then the scale should be drawn from any underlying layer |
436 // If the top layer has no scale and no value extents at all, | 475 // with a scale regardless of unit. |
437 // then the scale should be drawn from any underlying layer | 476 |
438 // with a scale regardless of unit. | 477 int sw = topLayer->getVerticalScaleWidth(this, paint); |
439 | 478 |
440 int sw = topLayer->getVerticalScaleWidth(this, paint); | 479 if (sw > 0) { |
441 | 480 scaleLayer = topLayer; |
442 if (sw > 0) { | 481 m_scaleWidth = sw; |
443 scaleLayer = topLayer; | 482 |
444 m_scaleWidth = sw; | 483 } else { |
445 | 484 |
446 } else { | 485 bool hasDisplayExtents = topLayer->getDisplayExtents(min, max); |
447 | 486 bool hasValueExtents = topLayer->getValueExtents(min, max, log, unit); |
448 bool hasDisplayExtents = topLayer->getDisplayExtents(min, max); | |
449 bool hasValueExtents = topLayer->getValueExtents(min, max, log, unit); | |
450 | 487 |
451 if (!hasDisplayExtents) { | 488 if (!hasDisplayExtents) { |
452 | 489 |
453 if (!hasValueExtents) { | 490 if (!hasValueExtents) { |
454 | 491 |
455 for (LayerList::iterator vi = m_layers.end(); | 492 for (LayerList::iterator vi = m_layers.end(); |
456 vi != m_layers.begin(); ) { | 493 vi != m_layers.begin(); ) { |
457 | 494 |
458 --vi; | 495 --vi; |
459 | 496 |
460 if ((*vi) == topLayer) continue; | 497 if ((*vi) == topLayer) continue; |
461 | 498 |
462 sw = (*vi)->getVerticalScaleWidth(this, paint); | 499 sw = (*vi)->getVerticalScaleWidth(this, paint); |
463 | 500 |
464 if (sw > 0) { | 501 if (sw > 0) { |
465 scaleLayer = *vi; | 502 scaleLayer = *vi; |
466 m_scaleWidth = sw; | 503 m_scaleWidth = sw; |
467 break; | 504 break; |
505 } | |
506 } | |
507 } else if (unit != "") { // && hasValueExtents && !hasDisplayExtents | |
508 | |
509 QString requireUnit = unit; | |
510 | |
511 for (LayerList::iterator vi = m_layers.end(); | |
512 vi != m_layers.begin(); ) { | |
513 | |
514 --vi; | |
515 | |
516 if ((*vi) == topLayer) continue; | |
517 | |
518 if ((*vi)->getDisplayExtents(min, max)) { | |
519 | |
520 // search no further than this: if the | |
521 // scale from this layer isn't suitable, | |
522 // we'll have to draw no scale (else we'd | |
523 // risk ending up with the wrong scale) | |
524 | |
525 if ((*vi)->getValueExtents(min, max, log, unit) && | |
526 unit == requireUnit) { | |
527 | |
528 sw = (*vi)->getVerticalScaleWidth(this, paint); | |
529 if (sw > 0) { | |
530 scaleLayer = *vi; | |
531 m_scaleWidth = sw; | |
532 } | |
468 } | 533 } |
469 } | 534 break; |
470 } else if (unit != "") { // && hasValueExtents && !hasDisplayExtents | |
471 | |
472 QString requireUnit = unit; | |
473 | |
474 for (LayerList::iterator vi = m_layers.end(); | |
475 vi != m_layers.begin(); ) { | |
476 | |
477 --vi; | |
478 | |
479 if ((*vi) == topLayer) continue; | |
480 | |
481 if ((*vi)->getDisplayExtents(min, max)) { | |
482 | |
483 // search no further than this: if the | |
484 // scale from this layer isn't suitable, | |
485 // we'll have to draw no scale (else we'd | |
486 // risk ending up with the wrong scale) | |
487 | |
488 if ((*vi)->getValueExtents(min, max, log, unit) && | |
489 unit == requireUnit) { | |
490 | |
491 sw = (*vi)->getVerticalScaleWidth(this, paint); | |
492 if (sw > 0) { | |
493 scaleLayer = *vi; | |
494 m_scaleWidth = sw; | |
495 } | |
496 } | |
497 break; | |
498 } | |
499 } | 535 } |
500 } | 536 } |
501 } | 537 } |
502 } | 538 } |
503 } | 539 } |
519 scaleLayer->paintVerticalScale | 555 scaleLayer->paintVerticalScale |
520 (this, paint, QRect(0, 0, m_scaleWidth, height())); | 556 (this, paint, QRect(0, 0, m_scaleWidth, height())); |
521 | 557 |
522 paint.restore(); | 558 paint.restore(); |
523 } | 559 } |
524 | 560 } |
525 if (m_identifyFeatures && topLayer) { | |
526 | 561 |
527 QPoint pos = m_identifyPoint; | 562 void |
528 QString desc = topLayer->getFeatureDescription(this, pos); | 563 Pane::drawFeatureDescription(Layer *topLayer, QPainter &paint) |
564 { | |
565 QPoint pos = m_identifyPoint; | |
566 QString desc = topLayer->getFeatureDescription(this, pos); | |
529 | 567 |
530 if (desc != "") { | 568 if (desc != "") { |
569 | |
570 paint.save(); | |
571 | |
572 int tabStop = | |
573 paint.fontMetrics().width(tr("Some lengthy prefix:")); | |
574 | |
575 QRect boundingRect = | |
576 paint.fontMetrics().boundingRect | |
577 (rect(), | |
578 Qt::AlignRight | Qt::AlignTop | Qt::TextExpandTabs, | |
579 desc, tabStop); | |
580 | |
581 if (hasLightBackground()) { | |
582 paint.setPen(Qt::NoPen); | |
583 paint.setBrush(QColor(250, 250, 250, 200)); | |
584 } else { | |
585 paint.setPen(Qt::NoPen); | |
586 paint.setBrush(QColor(50, 50, 50, 200)); | |
587 } | |
588 | |
589 int extra = paint.fontMetrics().descent(); | |
590 paint.drawRect(width() - boundingRect.width() - 10 - extra, | |
591 10 - extra, | |
592 boundingRect.width() + 2 * extra, | |
593 boundingRect.height() + extra); | |
594 | |
595 if (hasLightBackground()) { | |
596 paint.setPen(QColor(150, 20, 0)); | |
597 } else { | |
598 paint.setPen(QColor(255, 150, 100)); | |
599 } | |
600 | |
601 QTextOption option; | |
602 option.setWrapMode(QTextOption::NoWrap); | |
603 option.setAlignment(Qt::AlignRight | Qt::AlignTop); | |
604 option.setTabStop(tabStop); | |
605 paint.drawText(QRectF(width() - boundingRect.width() - 10, 10, | |
606 boundingRect.width(), | |
607 boundingRect.height()), | |
608 desc, | |
609 option); | |
610 | |
611 paint.restore(); | |
612 } | |
613 } | |
614 | |
615 void | |
616 Pane::drawCentreLine(int sampleRate, QPainter &paint) | |
617 { | |
618 int fontHeight = paint.fontMetrics().height(); | |
619 int fontAscent = paint.fontMetrics().ascent(); | |
620 | |
621 QColor c = QColor(0, 0, 0); | |
622 if (!hasLightBackground()) { | |
623 c = QColor(240, 240, 240); | |
624 } | |
625 paint.setPen(c); | |
626 int x = width() / 2 + 1; | |
627 paint.drawLine(x, 0, x, height() - 1); | |
628 paint.drawLine(x-1, 1, x+1, 1); | |
629 paint.drawLine(x-2, 0, x+2, 0); | |
630 paint.drawLine(x-1, height() - 2, x+1, height() - 2); | |
631 paint.drawLine(x-2, height() - 1, x+2, height() - 1); | |
632 | |
633 paint.setPen(QColor(50, 50, 50)); | |
634 | |
635 int y = height() - fontHeight + fontAscent - 6; | |
636 | |
637 LayerList::iterator vi = m_layers.end(); | |
638 | |
639 if (vi != m_layers.begin()) { | |
640 | |
641 switch ((*--vi)->getPreferredFrameCountPosition()) { | |
531 | 642 |
532 paint.save(); | 643 case Layer::PositionTop: |
644 y = fontAscent + 6; | |
645 break; | |
533 | 646 |
534 int tabStop = | 647 case Layer::PositionMiddle: |
535 paint.fontMetrics().width(tr("Some lengthy prefix:")); | 648 y = (height() - fontHeight) / 2 |
649 + fontAscent; | |
650 break; | |
536 | 651 |
537 QRect boundingRect = | 652 case Layer::PositionBottom: |
538 paint.fontMetrics().boundingRect | 653 // y already set correctly |
539 (rect(), | 654 break; |
540 Qt::AlignRight | Qt::AlignTop | Qt::TextExpandTabs, | 655 } |
541 desc, tabStop); | 656 } |
657 | |
658 if (m_manager && m_manager->shouldShowFrameCount()) { | |
659 | |
660 if (sampleRate) { | |
661 | |
662 QString text(QString::fromStdString | |
663 (RealTime::frame2RealTime | |
664 (m_centreFrame, sampleRate).toText(true))); | |
542 | 665 |
543 if (hasLightBackground()) { | 666 int tw = paint.fontMetrics().width(text); |
544 paint.setPen(Qt::NoPen); | 667 int x = width()/2 - 4 - tw; |
545 paint.setBrush(QColor(250, 250, 250, 200)); | 668 |
669 drawVisibleText(paint, x, y, text, OutlinedText); | |
670 } | |
671 | |
672 QString text = QString("%1").arg(m_centreFrame); | |
673 | |
674 int x = width()/2 + 4; | |
675 | |
676 drawVisibleText(paint, x, y, text, OutlinedText); | |
677 } | |
678 } | |
679 | |
680 void | |
681 Pane::drawLayerNames(QRect r, QPainter &paint) | |
682 { | |
683 int fontHeight = paint.fontMetrics().height(); | |
684 int fontAscent = paint.fontMetrics().ascent(); | |
685 | |
686 if (r.y() + r.height() < height() - int(m_layers.size()) * fontHeight - 6) { | |
687 return; | |
688 } | |
689 | |
690 std::vector<QString> texts; | |
691 int maxTextWidth = 0; | |
692 | |
693 for (LayerList::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { | |
694 | |
695 QString text = (*i)->getLayerPresentationName(); | |
696 int tw = paint.fontMetrics().width(text); | |
697 bool reduced = false; | |
698 while (tw > width() / 3 && text.length() > 4) { | |
699 if (!reduced && text.length() > 8) { | |
700 text = text.left(text.length() - 4); | |
546 } else { | 701 } else { |
547 paint.setPen(Qt::NoPen); | 702 text = text.left(text.length() - 2); |
548 paint.setBrush(QColor(50, 50, 50, 200)); | 703 } |
704 reduced = true; | |
705 tw = paint.fontMetrics().width(text + "..."); | |
706 } | |
707 if (reduced) { | |
708 texts.push_back(text + "..."); | |
709 } else { | |
710 texts.push_back(text); | |
711 } | |
712 if (tw > maxTextWidth) maxTextWidth = tw; | |
713 } | |
714 | |
715 int lly = height() - 6; | |
716 int llx = width() - maxTextWidth - 5; | |
717 | |
718 if (m_manager->getZoomWheelsEnabled()) { | |
719 lly -= 20; | |
720 llx -= 36; | |
721 } | |
722 | |
723 if (r.x() + r.width() >= llx) { | |
724 | |
725 for (size_t i = 0; i < texts.size(); ++i) { | |
726 | |
727 if (i + 1 == texts.size()) { | |
728 paint.setPen(Qt::black); | |
549 } | 729 } |
550 | 730 |
551 int extra = paint.fontMetrics().descent(); | 731 drawVisibleText(paint, llx, |
552 paint.drawRect(width() - boundingRect.width() - 10 - extra, | 732 lly - fontHeight + fontAscent, |
553 10 - extra, | 733 texts[i], OutlinedText); |
554 boundingRect.width() + 2 * extra, | |
555 boundingRect.height() + extra); | |
556 | 734 |
557 if (hasLightBackground()) { | 735 lly -= fontHeight; |
558 paint.setPen(QColor(150, 20, 0)); | 736 } |
559 } else { | 737 } |
560 paint.setPen(QColor(255, 150, 100)); | 738 } |
561 } | 739 |
562 | 740 void |
563 QTextOption option; | 741 Pane::drawMeasurementRect(Layer *topLayer, QPainter &paint) |
564 option.setWrapMode(QTextOption::NoWrap); | 742 { |
565 option.setAlignment(Qt::AlignRight | Qt::AlignTop); | 743 int fontHeight = paint.fontMetrics().height(); |
566 option.setTabStop(tabStop); | 744 int fontAscent = paint.fontMetrics().ascent(); |
567 paint.drawText(QRectF(width() - boundingRect.width() - 10, 10, | 745 |
568 boundingRect.width(), | 746 float v0, v1; |
569 boundingRect.height()), | 747 QString u0, u1; |
570 desc, | 748 bool b0, b1; |
571 option); | 749 |
572 | 750 QString axs, ays, bxs, bys, dxs, dys; |
573 paint.restore(); | 751 |
574 } | 752 if ((b0 = topLayer->getXScaleValue(this, m_clickPos.x(), v0, u0))) { |
575 } | 753 axs = QString("%1 %2").arg(v0).arg(u0); |
576 | 754 } |
577 int sampleRate = getModelsSampleRate(); | 755 |
578 paint.setBrush(Qt::NoBrush); | 756 if ((b1 = topLayer->getXScaleValue(this, m_mousePos.x(), v1, u1))) { |
579 | 757 bxs = QString("%1 %2").arg(v1).arg(u1); |
580 if (m_centreLineVisible && | 758 } |
581 m_manager && | 759 |
582 m_manager->shouldShowCentreLine()) { | 760 if (b0 && b1 && u0 == u1) { |
583 | 761 dxs = QString("(%1 %2)").arg(v1 - v0).arg(u1); |
584 QColor c = QColor(0, 0, 0); | 762 } |
585 if (!hasLightBackground()) { | 763 |
586 c = QColor(240, 240, 240); | 764 if ((b0 = topLayer->getYScaleValue(this, m_clickPos.y(), v0, u0))) { |
587 } | 765 ays = QString("%1 %2").arg(v0).arg(u0); |
588 paint.setPen(c); | 766 } |
589 int x = width() / 2 + 1; | 767 |
590 paint.drawLine(x, 0, x, height() - 1); | 768 if ((b1 = topLayer->getYScaleValue(this, m_mousePos.y(), v1, u1))) { |
591 paint.drawLine(x-1, 1, x+1, 1); | 769 bys = QString("%1 %2").arg(v1).arg(u1); |
592 paint.drawLine(x-2, 0, x+2, 0); | 770 } |
593 paint.drawLine(x-1, height() - 2, x+1, height() - 2); | 771 |
594 paint.drawLine(x-2, height() - 1, x+2, height() - 1); | 772 if (b0 && b1 && u0 == u1) { |
595 | 773 dys = QString("(%1 %2)").arg(v1 - v0).arg(u1); |
596 paint.setPen(QColor(50, 50, 50)); | 774 } |
597 | 775 |
598 int y = height() - fontHeight | 776 int x = m_clickPos.x() + 2; |
599 + fontAscent - 6; | 777 int y = m_clickPos.y() + fontAscent + 2; |
600 | 778 |
601 LayerList::iterator vi = m_layers.end(); | 779 if (axs != "") { |
602 | 780 drawVisibleText(paint, x, y, axs, OutlinedText); |
603 if (vi != m_layers.begin()) { | 781 y += fontHeight; |
604 | 782 } |
605 switch ((*--vi)->getPreferredFrameCountPosition()) { | 783 |
606 | 784 if (ays != "") { |
607 case Layer::PositionTop: | 785 drawVisibleText(paint, x, y, ays, OutlinedText); |
608 y = fontAscent + 6; | 786 y += fontHeight; |
609 break; | 787 } |
610 | 788 |
611 case Layer::PositionMiddle: | 789 x = m_mousePos.x() - paint.fontMetrics().width(bxs) - 2; |
612 y = (height() - fontHeight) / 2 | 790 y = m_mousePos.y() - 2; |
613 + fontAscent; | 791 |
614 break; | 792 if (bys != "" && bxs != "") y -= fontHeight; |
615 | 793 |
616 case Layer::PositionBottom: | 794 if (bxs != "") { |
617 // y already set correctly | 795 drawVisibleText(paint, x, y, bxs, OutlinedText); |
618 break; | 796 y += fontHeight; |
619 } | 797 } |
620 } | 798 |
621 | 799 x = m_mousePos.x() - paint.fontMetrics().width(bys) - 2; |
622 if (m_manager && m_manager->shouldShowFrameCount()) { | 800 |
623 | 801 if (bys != "") { |
624 if (sampleRate) { | 802 drawVisibleText(paint, x, y, bys, OutlinedText); |
625 | 803 y += fontHeight; |
626 QString text(QString::fromStdString | 804 } |
627 (RealTime::frame2RealTime | 805 |
628 (m_centreFrame, sampleRate).toText(true))); | 806 paint.save(); |
629 | 807 |
630 int tw = paint.fontMetrics().width(text); | 808 paint.setPen(Qt::green); |
631 int x = width()/2 - 4 - tw; | 809 |
632 | 810 paint.drawRect(m_clickPos.x(), m_clickPos.y(), |
633 drawVisibleText(paint, x, y, text, OutlinedText); | 811 m_mousePos.x() - m_clickPos.x(), |
634 } | 812 m_mousePos.y() - m_clickPos.y()); |
635 | 813 |
636 QString text = QString("%1").arg(m_centreFrame); | 814 paint.restore(); |
637 | 815 } |
638 int x = width()/2 + 4; | 816 |
639 | 817 void |
640 drawVisibleText(paint, x, y, text, OutlinedText); | 818 Pane::drawEditingSelection(QPainter &paint) |
641 } | 819 { |
642 | 820 int offset = m_mousePos.x() - m_clickPos.x(); |
821 int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset; | |
822 int p1 = getXForFrame(m_editingSelection.getEndFrame()) + offset; | |
823 | |
824 if (m_editingSelectionEdge < 0) { | |
825 p1 = getXForFrame(m_editingSelection.getEndFrame()); | |
826 } else if (m_editingSelectionEdge > 0) { | |
827 p0 = getXForFrame(m_editingSelection.getStartFrame()); | |
828 } | |
829 | |
830 paint.save(); | |
831 if (hasLightBackground()) { | |
832 paint.setPen(QPen(Qt::black, 2)); | |
643 } else { | 833 } else { |
644 | 834 paint.setPen(QPen(Qt::white, 2)); |
645 paint.setPen(QColor(50, 50, 50)); | 835 } |
646 } | 836 |
647 | 837 //!!! duplicating display policy with View::drawSelections |
648 if (waveformModel && | 838 |
649 m_manager && | 839 if (m_editingSelectionEdge < 0) { |
650 m_manager->shouldShowDuration() && | 840 paint.drawLine(p0, 1, p1, 1); |
651 r.y() + r.height() >= height() - fontHeight - 6) { | 841 paint.drawLine(p0, 0, p0, height()); |
652 | 842 paint.drawLine(p0, height() - 1, p1, height() - 1); |
653 size_t modelRate = waveformModel->getSampleRate(); | 843 } else if (m_editingSelectionEdge > 0) { |
654 size_t playbackRate = m_manager->getPlaybackSampleRate(); | 844 paint.drawLine(p0, 1, p1, 1); |
655 size_t outputRate = m_manager->getOutputSampleRate(); | 845 paint.drawLine(p1, 0, p1, height()); |
656 | 846 paint.drawLine(p0, height() - 1, p1, height() - 1); |
657 QString srNote = ""; | 847 } else { |
658 | 848 paint.setBrush(Qt::NoBrush); |
659 // Show (R) for waveform models that will be resampled on | 849 paint.drawRect(p0, 1, p1 - p0, height() - 2); |
660 // playback, and (X) for waveform models that will be played | 850 } |
661 // at the wrong rate because their rate differs from the | 851 paint.restore(); |
662 // current playback rate (which is not necessarily that of the | 852 } |
663 // main model). | 853 |
664 | 854 void |
665 if (playbackRate != 0) { | 855 Pane::drawDurationAndRate(QRect r, const Model *waveformModel, |
666 if (modelRate == playbackRate) { | 856 int sampleRate, QPainter &paint) |
667 if (modelRate != outputRate) srNote = " " + tr("(R)"); | 857 { |
668 } else { | 858 int fontHeight = paint.fontMetrics().height(); |
669 srNote = " " + tr("(X)"); | 859 int fontAscent = paint.fontMetrics().ascent(); |
670 } | 860 |
671 } | 861 if (r.y() + r.height() < height() - fontHeight - 6) return; |
672 | 862 |
673 QString desc = tr("%1 / %2Hz%3") | 863 size_t modelRate = waveformModel->getSampleRate(); |
674 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(), | 864 size_t playbackRate = m_manager->getPlaybackSampleRate(); |
675 sampleRate) | 865 size_t outputRate = m_manager->getOutputSampleRate(); |
676 .toText(false).c_str()) | 866 |
677 .arg(modelRate) | 867 QString srNote = ""; |
678 .arg(srNote); | 868 |
679 | 869 // Show (R) for waveform models that will be resampled on |
680 if (r.x() < m_scaleWidth + 5 + paint.fontMetrics().width(desc)) { | 870 // playback, and (X) for waveform models that will be played |
681 drawVisibleText(paint, m_scaleWidth + 5, | 871 // at the wrong rate because their rate differs from the |
682 height() - fontHeight + fontAscent - 6, | 872 // current playback rate (which is not necessarily that of the |
683 desc, OutlinedText); | 873 // main model). |
684 } | 874 |
685 } | 875 if (playbackRate != 0) { |
686 | 876 if (modelRate == playbackRate) { |
687 if (m_manager && | 877 if (modelRate != outputRate) srNote = " " + tr("(R)"); |
688 m_manager->shouldShowLayerNames() && | 878 } else { |
689 r.y() + r.height() >= height() - int(m_layers.size()) * fontHeight - 6) { | 879 srNote = " " + tr("(X)"); |
690 | 880 } |
691 std::vector<QString> texts; | 881 } |
692 int maxTextWidth = 0; | 882 |
693 | 883 QString desc = tr("%1 / %2Hz%3") |
694 for (LayerList::iterator i = m_layers.begin(); i != m_layers.end(); ++i) { | 884 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(), |
695 | 885 sampleRate) |
696 QString text = (*i)->getLayerPresentationName(); | 886 .toText(false).c_str()) |
697 int tw = paint.fontMetrics().width(text); | 887 .arg(modelRate) |
698 bool reduced = false; | 888 .arg(srNote); |
699 while (tw > width() / 3 && text.length() > 4) { | 889 |
700 if (!reduced && text.length() > 8) { | 890 if (r.x() < m_scaleWidth + 5 + paint.fontMetrics().width(desc)) { |
701 text = text.left(text.length() - 4); | 891 drawVisibleText(paint, m_scaleWidth + 5, |
702 } else { | 892 height() - fontHeight + fontAscent - 6, |
703 text = text.left(text.length() - 2); | 893 desc, OutlinedText); |
704 } | 894 } |
705 reduced = true; | |
706 tw = paint.fontMetrics().width(text + "..."); | |
707 } | |
708 if (reduced) { | |
709 texts.push_back(text + "..."); | |
710 } else { | |
711 texts.push_back(text); | |
712 } | |
713 if (tw > maxTextWidth) maxTextWidth = tw; | |
714 } | |
715 | |
716 int lly = height() - 6; | |
717 int llx = width() - maxTextWidth - 5; | |
718 | |
719 if (m_manager->getZoomWheelsEnabled()) { | |
720 lly -= 20; | |
721 llx -= 36; | |
722 } | |
723 | |
724 if (r.x() + r.width() >= llx) { | |
725 | |
726 for (size_t i = 0; i < texts.size(); ++i) { | |
727 | |
728 if (i + 1 == texts.size()) { | |
729 paint.setPen(Qt::black); | |
730 } | |
731 | |
732 drawVisibleText(paint, llx, | |
733 lly - fontHeight + fontAscent, | |
734 texts[i], OutlinedText); | |
735 | |
736 lly -= fontHeight; | |
737 } | |
738 } | |
739 } | |
740 | |
741 if (m_clickedInRange && m_manager) { | |
742 | |
743 //!!! be nice if this looked a bit more in keeping with the | |
744 //selection block | |
745 | |
746 if (m_shiftPressed && toolMode == ViewManager::NavigateMode) { | |
747 | |
748 paint.setPen(Qt::blue); | |
749 //!!! shouldn't use clickPos -- needs to use a clicked frame | |
750 paint.drawRect(m_clickPos.x(), m_clickPos.y(), | |
751 m_mousePos.x() - m_clickPos.x(), | |
752 m_mousePos.y() - m_clickPos.y()); | |
753 | |
754 } else if (toolMode == ViewManager::MeasureMode && topLayer) { | |
755 | |
756 float v0, v1; | |
757 QString u0, u1; | |
758 bool b0, b1; | |
759 | |
760 if ((b0 = topLayer->getXScaleValue(this, m_clickPos.x(), v0, u0))) { | |
761 drawVisibleText(paint, | |
762 m_clickPos.x() + 2, | |
763 m_clickPos.y() + fontAscent + 2, | |
764 QString("%1 %2").arg(v0).arg(u0), | |
765 OutlinedText); | |
766 | |
767 if ((b1 = topLayer->getXScaleValue(this, m_mousePos.x(), v1, u1)) | |
768 && u1 == u0) { | |
769 QString t = QString("%1 %2").arg(v1 - v0).arg(u1); | |
770 drawVisibleText(paint, | |
771 m_mousePos.x() - paint.fontMetrics().width(t) - 2, | |
772 m_mousePos.y() - 2, | |
773 t, | |
774 OutlinedText); | |
775 } | |
776 } | |
777 | |
778 paint.setPen(Qt::green); | |
779 | |
780 //!!! shouldn't use clickPos -- needs to use a clicked frame | |
781 paint.drawRect(m_clickPos.x(), m_clickPos.y(), | |
782 m_mousePos.x() - m_clickPos.x(), | |
783 m_mousePos.y() - m_clickPos.y()); | |
784 } | |
785 } | |
786 | |
787 if (selectionIsBeingEdited()) { | |
788 | |
789 int offset = m_mousePos.x() - m_clickPos.x(); | |
790 int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset; | |
791 int p1 = getXForFrame(m_editingSelection.getEndFrame()) + offset; | |
792 | |
793 if (m_editingSelectionEdge < 0) { | |
794 p1 = getXForFrame(m_editingSelection.getEndFrame()); | |
795 } else if (m_editingSelectionEdge > 0) { | |
796 p0 = getXForFrame(m_editingSelection.getStartFrame()); | |
797 } | |
798 | |
799 paint.save(); | |
800 if (hasLightBackground()) { | |
801 paint.setPen(QPen(Qt::black, 2)); | |
802 } else { | |
803 paint.setPen(QPen(Qt::white, 2)); | |
804 } | |
805 | |
806 //!!! duplicating display policy with View::drawSelections | |
807 | |
808 if (m_editingSelectionEdge < 0) { | |
809 paint.drawLine(p0, 1, p1, 1); | |
810 paint.drawLine(p0, 0, p0, height()); | |
811 paint.drawLine(p0, height() - 1, p1, height() - 1); | |
812 } else if (m_editingSelectionEdge > 0) { | |
813 paint.drawLine(p0, 1, p1, 1); | |
814 paint.drawLine(p1, 0, p1, height()); | |
815 paint.drawLine(p0, height() - 1, p1, height() - 1); | |
816 } else { | |
817 paint.setBrush(Qt::NoBrush); | |
818 paint.drawRect(p0, 1, p1 - p0, height() - 2); | |
819 } | |
820 paint.restore(); | |
821 } | |
822 | |
823 paint.end(); | |
824 } | 895 } |
825 | 896 |
826 bool | 897 bool |
827 Pane::render(QPainter &paint, int xorigin, size_t f0, size_t f1) | 898 Pane::render(QPainter &paint, int xorigin, size_t f0, size_t f1) |
828 { | 899 { |