comparison layer/TimeValueLayer.cpp @ 1324:13d9b422f7fe zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:31 +0100
parents 1d7921b1852f
children d79e21855aef
comparison
equal deleted inserted replaced
1183:57d192e26331 1324:13d9b422f7fe
130 TimeValueLayer::getPropertyType(const PropertyName &name) const 130 TimeValueLayer::getPropertyType(const PropertyName &name) const
131 { 131 {
132 if (name == "Plot Type") return ValueProperty; 132 if (name == "Plot Type") return ValueProperty;
133 if (name == "Vertical Scale") return ValueProperty; 133 if (name == "Vertical Scale") return ValueProperty;
134 if (name == "Scale Units") return UnitsProperty; 134 if (name == "Scale Units") return UnitsProperty;
135 if (name == "Colour" && m_plotStyle == PlotSegmentation) return ValueProperty; 135 if (name == "Colour" && m_plotStyle == PlotSegmentation) return ColourMapProperty;
136 if (name == "Draw Segment Division Lines") return ToggleProperty; 136 if (name == "Draw Segment Division Lines") return ToggleProperty;
137 if (name == "Show Derivative") return ToggleProperty; 137 if (name == "Show Derivative") return ToggleProperty;
138 return SingleColourLayer::getPropertyType(name); 138 return SingleColourLayer::getPropertyType(name);
139 } 139 }
140 140
158 else return ""; 158 else return "";
159 } 159 }
160 160
161 int 161 int
162 TimeValueLayer::getPropertyRangeAndValue(const PropertyName &name, 162 TimeValueLayer::getPropertyRangeAndValue(const PropertyName &name,
163 int *min, int *max, int *deflt) const 163 int *min, int *max, int *deflt) const
164 { 164 {
165 int val = 0; 165 int val = 0;
166 166
167 if (name == "Colour" && m_plotStyle == PlotSegmentation) { 167 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
168 168
171 if (deflt) *deflt = 0; 171 if (deflt) *deflt = 0;
172 172
173 val = m_colourMap; 173 val = m_colourMap;
174 174
175 } else if (name == "Plot Type") { 175 } else if (name == "Plot Type") {
176 176
177 if (min) *min = 0; 177 if (min) *min = 0;
178 if (max) *max = 6; 178 if (max) *max = 6;
179 if (deflt) *deflt = int(PlotConnectedPoints); 179 if (deflt) *deflt = int(PlotConnectedPoints);
180 180
181 val = int(m_plotStyle); 181 val = int(m_plotStyle);
182 182
183 } else if (name == "Vertical Scale") { 183 } else if (name == "Vertical Scale") {
184 184
185 if (min) *min = 0; 185 if (min) *min = 0;
186 if (max) *max = 3; 186 if (max) *max = 3;
187 if (deflt) *deflt = int(AutoAlignScale); 187 if (deflt) *deflt = int(AutoAlignScale);
188 188
189 val = int(m_verticalScale); 189 val = int(m_verticalScale);
190 190
191 } else if (name == "Scale Units") { 191 } else if (name == "Scale Units") {
192 192
193 if (deflt) *deflt = 0; 193 if (deflt) *deflt = 0;
194 if (m_model) { 194 if (m_model) {
209 if (max) *max = 0; 209 if (max) *max = 0;
210 if (deflt) *deflt = 0; 210 if (deflt) *deflt = 0;
211 val = (m_derivative ? 1.0 : 0.0); 211 val = (m_derivative ? 1.0 : 0.0);
212 212
213 } else { 213 } else {
214 214
215 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); 215 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt);
216 } 216 }
217 217
218 return val; 218 return val;
219 } 219 }
220 220
221 QString 221 QString
222 TimeValueLayer::getPropertyValueLabel(const PropertyName &name, 222 TimeValueLayer::getPropertyValueLabel(const PropertyName &name,
223 int value) const 223 int value) const
224 { 224 {
225 if (name == "Colour" && m_plotStyle == PlotSegmentation) { 225 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
226 return ColourMapper::getColourMapName(value); 226 return ColourMapper::getColourMapName(value);
227 } else if (name == "Plot Type") { 227 } else if (name == "Plot Type") {
228 switch (value) { 228 switch (value) {
229 default: 229 default:
230 case 0: return tr("Points"); 230 case 0: return tr("Points");
231 case 1: return tr("Stems"); 231 case 1: return tr("Stems");
232 case 2: return tr("Connected Points"); 232 case 2: return tr("Connected Points");
233 case 3: return tr("Lines"); 233 case 3: return tr("Lines");
234 case 4: return tr("Curve"); 234 case 4: return tr("Curve");
235 case 5: return tr("Segmentation"); 235 case 5: return tr("Segmentation");
236 case 6: return tr("Discrete Curves"); 236 case 6: return tr("Discrete Curves");
237 } 237 }
238 } else if (name == "Vertical Scale") { 238 } else if (name == "Vertical Scale") {
239 switch (value) { 239 switch (value) {
240 default: 240 default:
241 case 0: return tr("Auto-Align"); 241 case 0: return tr("Auto-Align");
242 case 1: return tr("Linear"); 242 case 1: return tr("Linear");
243 case 2: return tr("Log"); 243 case 2: return tr("Log");
244 case 3: return tr("+/-1"); 244 case 3: return tr("+/-1");
245 } 245 }
246 } 246 }
247 return SingleColourLayer::getPropertyValueLabel(name, value); 247 return SingleColourLayer::getPropertyValueLabel(name, value);
248 } 248 }
249 249
250 void 250 void
251 TimeValueLayer::setProperty(const PropertyName &name, int value) 251 TimeValueLayer::setProperty(const PropertyName &name, int value)
252 { 252 {
253 if (name == "Colour" && m_plotStyle == PlotSegmentation) { 253 if (name == "Colour" && m_plotStyle == PlotSegmentation) {
254 setFillColourMap(value); 254 setFillColourMap(value);
255 } else if (name == "Plot Type") { 255 } else if (name == "Plot Type") {
256 setPlotStyle(PlotStyle(value)); 256 setPlotStyle(PlotStyle(value));
257 } else if (name == "Vertical Scale") { 257 } else if (name == "Vertical Scale") {
258 setVerticalScale(VerticalScale(value)); 258 setVerticalScale(VerticalScale(value));
259 } else if (name == "Scale Units") { 259 } else if (name == "Scale Units") {
260 if (m_model) { 260 if (m_model) {
261 m_model->setScaleUnits 261 m_model->setScaleUnits
262 (UnitDatabase::getInstance()->getUnitById(value)); 262 (UnitDatabase::getInstance()->getUnitById(value));
263 emit modelChanged(); 263 emit modelChanged();
321 { 321 {
322 // We don't illuminate sections in the line or curve modes, so 322 // We don't illuminate sections in the line or curve modes, so
323 // they're always scrollable 323 // they're always scrollable
324 324
325 if (m_plotStyle == PlotLines || 325 if (m_plotStyle == PlotLines ||
326 m_plotStyle == PlotCurve || 326 m_plotStyle == PlotCurve ||
327 m_plotStyle == PlotDiscreteCurves) return true; 327 m_plotStyle == PlotDiscreteCurves) return true;
328 328
329 QPoint discard; 329 QPoint discard;
330 return !v->shouldIlluminateLocalFeatures(this, discard); 330 return !v->shouldIlluminateLocalFeatures(this, discard);
331 } 331 }
536 if (!m_model) return SparseTimeValueModel::PointList(); 536 if (!m_model) return SparseTimeValueModel::PointList();
537 537
538 sv_frame_t frame = v->getFrameForX(x); 538 sv_frame_t frame = v->getFrameForX(x);
539 539
540 SparseTimeValueModel::PointList onPoints = 540 SparseTimeValueModel::PointList onPoints =
541 m_model->getPoints(frame); 541 m_model->getPoints(frame);
542 542
543 if (!onPoints.empty()) { 543 if (!onPoints.empty()) {
544 return onPoints; 544 return onPoints;
545 } 545 }
546 546
547 SparseTimeValueModel::PointList prevPoints = 547 SparseTimeValueModel::PointList prevPoints =
548 m_model->getPreviousPoints(frame); 548 m_model->getPreviousPoints(frame);
549 SparseTimeValueModel::PointList nextPoints = 549 SparseTimeValueModel::PointList nextPoints =
550 m_model->getNextPoints(frame); 550 m_model->getNextPoints(frame);
551 551
552 SparseTimeValueModel::PointList usePoints = prevPoints; 552 SparseTimeValueModel::PointList usePoints = prevPoints;
553 553
554 if (prevPoints.empty()) { 554 if (prevPoints.empty()) {
555 usePoints = nextPoints; 555 usePoints = nextPoints;
556 } else if (nextPoints.empty()) { 556 } else if (nextPoints.empty()) {
557 // stick with prevPoints 557 // stick with prevPoints
558 } else if (prevPoints.begin()->frame < v->getStartFrame() && 558 } else if (prevPoints.begin()->frame < v->getStartFrame() &&
559 !(nextPoints.begin()->frame > v->getEndFrame())) { 559 !(nextPoints.begin()->frame > v->getEndFrame())) {
560 usePoints = nextPoints; 560 usePoints = nextPoints;
561 } else if (nextPoints.begin()->frame - frame < 561 } else if (nextPoints.begin()->frame - frame <
562 frame - prevPoints.begin()->frame) { 562 frame - prevPoints.begin()->frame) {
563 usePoints = nextPoints; 563 usePoints = nextPoints;
564 } 564 }
565 565
566 if (!usePoints.empty()) { 566 if (!usePoints.empty()) {
567 int fuzz = 2; 567 int fuzz = 2;
568 int px = v->getXForFrame(usePoints.begin()->frame); 568 int px = v->getXForFrame(usePoints.begin()->frame);
569 if ((px > x && px - x > fuzz) || 569 if ((px > x && px - x > fuzz) ||
570 (px < x && x - px > fuzz + 3)) { 570 (px < x && x - px > fuzz + 3)) {
571 usePoints.clear(); 571 usePoints.clear();
572 } 572 }
573 } 573 }
574 574
575 return usePoints; 575 return usePoints;
576 } 576 }
577 577
595 if (!m_model || !m_model->getSampleRate()) return ""; 595 if (!m_model || !m_model->getSampleRate()) return "";
596 596
597 SparseTimeValueModel::PointList points = getLocalPoints(v, x); 597 SparseTimeValueModel::PointList points = getLocalPoints(v, x);
598 598
599 if (points.empty()) { 599 if (points.empty()) {
600 if (!m_model->isReady()) { 600 if (!m_model->isReady()) {
601 return tr("In progress"); 601 return tr("In progress");
602 } else { 602 } else {
603 return tr("No local points"); 603 return tr("No local points");
604 } 604 }
605 } 605 }
606 606
607 sv_frame_t useFrame = points.begin()->frame; 607 sv_frame_t useFrame = points.begin()->frame;
608 608
609 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 609 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
624 } 624 }
625 625
626 QString text; 626 QString text;
627 627
628 if (points.begin()->label == "") { 628 if (points.begin()->label == "") {
629 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label")) 629 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label"))
630 .arg(rt.toText(true).c_str()) 630 .arg(rt.toText(true).c_str())
631 .arg(valueText); 631 .arg(valueText);
632 } else { 632 } else {
633 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%4")) 633 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%4"))
634 .arg(rt.toText(true).c_str()) 634 .arg(rt.toText(true).c_str())
635 .arg(valueText) 635 .arg(valueText)
636 .arg(points.begin()->label); 636 .arg(points.begin()->label);
637 } 637 }
638 638
639 pos = QPoint(v->getXForFrame(useFrame), 639 pos = QPoint(v->getXForFrame(useFrame),
640 getYForValue(v, points.begin()->value)); 640 getYForValue(v, points.begin()->value));
641 return text; 641 return text;
642 } 642 }
643 643
644 bool 644 bool
645 TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 645 TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
646 int &resolution, 646 int &resolution,
647 SnapType snap) const 647 SnapType snap) const
648 { 648 {
649 if (!m_model) { 649 if (!m_model) {
650 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 650 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
651 } 651 }
652 652
653 resolution = m_model->getResolution(); 653 resolution = m_model->getResolution();
654 SparseTimeValueModel::PointList points; 654 SparseTimeValueModel::PointList points;
655 655
656 if (snap == SnapNeighbouring) { 656 if (snap == SnapNeighbouring) {
657 657
658 points = getLocalPoints(v, v->getXForFrame(frame)); 658 points = getLocalPoints(v, v->getXForFrame(frame));
659 if (points.empty()) return false; 659 if (points.empty()) return false;
660 frame = points.begin()->frame; 660 frame = points.begin()->frame;
661 return true; 661 return true;
662 } 662 }
663 663
664 points = m_model->getPoints(frame, frame); 664 points = m_model->getPoints(frame, frame);
665 sv_frame_t snapped = frame; 665 sv_frame_t snapped = frame;
666 bool found = false; 666 bool found = false;
667 667
668 for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); 668 for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
669 i != points.end(); ++i) { 669 i != points.end(); ++i) {
670 670
671 if (snap == SnapRight) { 671 if (snap == SnapRight) {
672 672
673 if (i->frame > frame) { 673 if (i->frame > frame) {
674 snapped = i->frame; 674 snapped = i->frame;
675 found = true; 675 found = true;
676 break; 676 break;
677 } 677 }
678 678
679 } else if (snap == SnapLeft) { 679 } else if (snap == SnapLeft) {
680 680
681 if (i->frame <= frame) { 681 if (i->frame <= frame) {
682 snapped = i->frame; 682 snapped = i->frame;
683 found = true; // don't break, as the next may be better 683 found = true; // don't break, as the next may be better
684 } else { 684 } else {
685 break; 685 break;
686 } 686 }
687 687
688 } else { // nearest 688 } else { // nearest
689 689
690 SparseTimeValueModel::PointList::const_iterator j = i; 690 SparseTimeValueModel::PointList::const_iterator j = i;
691 ++j; 691 ++j;
692 692
693 if (j == points.end()) { 693 if (j == points.end()) {
694 694
695 snapped = i->frame; 695 snapped = i->frame;
696 found = true; 696 found = true;
697 break; 697 break;
698 698
699 } else if (j->frame >= frame) { 699 } else if (j->frame >= frame) {
700 700
701 if (j->frame - frame < frame - i->frame) { 701 if (j->frame - frame < frame - i->frame) {
702 snapped = j->frame; 702 snapped = j->frame;
703 } else { 703 } else {
704 snapped = i->frame; 704 snapped = i->frame;
705 } 705 }
706 found = true; 706 found = true;
707 break; 707 break;
708 } 708 }
709 } 709 }
710 } 710 }
711 711
712 frame = snapped; 712 frame = snapped;
713 return found; 713 return found;
714 } 714 }
717 TimeValueLayer::snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame, 717 TimeValueLayer::snapToSimilarFeature(LayerGeometryProvider *v, sv_frame_t &frame,
718 int &resolution, 718 int &resolution,
719 SnapType snap) const 719 SnapType snap) const
720 { 720 {
721 if (!m_model) { 721 if (!m_model) {
722 return Layer::snapToSimilarFeature(v, frame, resolution, snap); 722 return Layer::snapToSimilarFeature(v, frame, resolution, snap);
723 } 723 }
724 724
725 resolution = m_model->getResolution(); 725 resolution = m_model->getResolution();
726 726
727 const SparseTimeValueModel::PointList &points = m_model->getPoints(); 727 const SparseTimeValueModel::PointList &points = m_model->getPoints();
761 i = points.begin(); 761 i = points.begin();
762 distant = true; 762 distant = true;
763 } 763 }
764 } 764 }
765 765
766 if (snap == SnapRight) { 766 if (snap == SnapRight) {
767 767
768 if (i->frame > matchframe && 768 if (i->frame > matchframe &&
769 fabs(i->value - matchvalue) < epsilon) { 769 fabs(i->value - matchvalue) < epsilon) {
770 snapped = i->frame; 770 snapped = i->frame;
771 found = true; 771 found = true;
772 break; 772 break;
773 } 773 }
774 774
775 } else if (snap == SnapLeft) { 775 } else if (snap == SnapLeft) {
776 776
777 if (i->frame < matchframe) { 777 if (i->frame < matchframe) {
778 if (fabs(i->value - matchvalue) < epsilon) { 778 if (fabs(i->value - matchvalue) < epsilon) {
779 snapped = i->frame; 779 snapped = i->frame;
780 found = true; // don't break, as the next may be better 780 found = true; // don't break, as the next may be better
781 } 781 }
782 } else if (found || distant) { 782 } else if (found || distant) {
783 break; 783 break;
784 } 784 }
785 785
786 } else { 786 } else {
787 // no other snap types supported 787 // no other snap types supported
788 } 788 }
789 789
790 ++i; 790 ++i;
791 } 791 }
792 792
793 frame = snapped; 793 frame = snapped;
924 sv_frame_t frame0 = v->getFrameForX(x0); 924 sv_frame_t frame0 = v->getFrameForX(x0);
925 sv_frame_t frame1 = v->getFrameForX(x1); 925 sv_frame_t frame1 = v->getFrameForX(x1);
926 if (m_derivative) --frame0; 926 if (m_derivative) --frame0;
927 927
928 SparseTimeValueModel::PointList points(m_model->getPoints 928 SparseTimeValueModel::PointList points(m_model->getPoints
929 (frame0, frame1)); 929 (frame0, frame1));
930 if (points.empty()) return; 930 if (points.empty()) return;
931 931
932 paint.setPen(getBaseQColor()); 932 paint.setPen(getBaseQColor());
933 933
934 QColor brushColour(getBaseQColor()); 934 QColor brushColour(getBaseQColor());
935 brushColour.setAlpha(80); 935 brushColour.setAlpha(80);
936 paint.setBrush(brushColour); 936 paint.setBrush(brushColour);
937 937
938 #ifdef DEBUG_TIME_VALUE_LAYER 938 #ifdef DEBUG_TIME_VALUE_LAYER
939 cerr << "TimeValueLayer::paint: resolution is " 939 cerr << "TimeValueLayer::paint: resolution is "
940 << m_model->getResolution() << " frames" << endl; 940 << m_model->getResolution() << " frames" << endl;
941 #endif 941 #endif
942 942
943 double min = m_model->getValueMinimum(); 943 double min = m_model->getValueMinimum();
944 double max = m_model->getValueMaximum(); 944 double max = m_model->getValueMaximum();
945 if (max == min) max = min + 1.0; 945 if (max == min) max = min + 1.0;
946 946
947 int origin = int(nearbyint(v->getPaintHeight() - 947 int origin = int(nearbyint(v->getPaintHeight() -
948 (-min * v->getPaintHeight()) / (max - min))); 948 (-min * v->getPaintHeight()) / (max - min)));
949 949
950 QPoint localPos; 950 QPoint localPos;
951 sv_frame_t illuminateFrame = -1; 951 sv_frame_t illuminateFrame = -1;
952 952
953 if (v->shouldIlluminateLocalFeatures(this, localPos)) { 953 if (v->shouldIlluminateLocalFeatures(this, localPos)) {
954 SparseTimeValueModel::PointList localPoints = 954 SparseTimeValueModel::PointList localPoints =
955 getLocalPoints(v, localPos.x()); 955 getLocalPoints(v, localPos.x());
956 #ifdef DEBUG_TIME_VALUE_LAYER 956 #ifdef DEBUG_TIME_VALUE_LAYER
957 cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl; 957 cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl;
958 #endif 958 #endif
959 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame; 959 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
960 } 960 }
961 961
962 int w = 962 int w =
963 v->getXForFrame(frame0 + m_model->getResolution()) - 963 v->getXForFrame(frame0 + m_model->getResolution()) -
964 v->getXForFrame(frame0); 964 v->getXForFrame(frame0);
965 965
966 if (m_plotStyle == PlotStems) { 966 if (m_plotStyle == PlotStems) {
967 if (w < 2) w = 2; 967 if (w < 2) w = 2;
968 } else { 968 } else {
969 if (w < 1) w = 1; 969 if (w < 1) w = 1;
988 } 988 }
989 989
990 sv_frame_t prevFrame = 0; 990 sv_frame_t prevFrame = 0;
991 991
992 for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); 992 for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
993 i != points.end(); ++i) { 993 i != points.end(); ++i) {
994 994
995 if (m_derivative && i == points.begin()) continue; 995 if (m_derivative && i == points.begin()) continue;
996 996
997 const SparseTimeValueModel::Point &p(*i); 997 const SparseTimeValueModel::Point &p(*i);
998 998
999 double value = p.value; 999 double value = p.value;
1000 if (m_derivative) { 1000 if (m_derivative) {
1001 SparseTimeValueModel::PointList::const_iterator j = i; 1001 SparseTimeValueModel::PointList::const_iterator j = i;
1002 --j; 1002 --j;
1003 value -= j->value; 1003 value -= j->value;
1004 } 1004 }
1005 1005
1006 int x = v->getXForFrame(p.frame); 1006 int x = v->getXForFrame(p.frame);
1007 int y = getYForValue(v, value); 1007 int y = getYForValue(v, value);
1008 1008
1009 bool gap = false; 1009 bool gap = false;
1010 if (m_plotStyle == PlotDiscreteCurves) { 1010 if (m_plotStyle == PlotDiscreteCurves) {
1011 if (value == 0.0) { 1011 if (value == 0.0) {
1012 // Treat zeros as gaps 1012 // Treat zeros as gaps
1022 if (textY < paint.fontMetrics().ascent() + 1) { 1022 if (textY < paint.fontMetrics().ascent() + 1) {
1023 textY = paint.fontMetrics().ascent() + 1; 1023 textY = paint.fontMetrics().ascent() + 1;
1024 } 1024 }
1025 } 1025 }
1026 1026
1027 bool haveNext = false; 1027 bool haveNext = false;
1028 double nvalue = 0.f; 1028 double nvalue = 0.f;
1029 sv_frame_t nf = v->getModelsEndFrame(); 1029 sv_frame_t nf = v->getModelsEndFrame();
1030 int nx = v->getXForFrame(nf); 1030 int nx = v->getXForFrame(nf);
1031 int ny = y; 1031 int ny = y;
1032 1032
1033 SparseTimeValueModel::PointList::const_iterator j = i; 1033 SparseTimeValueModel::PointList::const_iterator j = i;
1034 ++j; 1034 ++j;
1035 1035
1036 if (j != points.end()) { 1036 if (j != points.end()) {
1037 const SparseTimeValueModel::Point &q(*j); 1037 const SparseTimeValueModel::Point &q(*j);
1038 nvalue = q.value; 1038 nvalue = q.value;
1039 if (m_derivative) nvalue -= p.value; 1039 if (m_derivative) nvalue -= p.value;
1040 nf = q.frame; 1040 nf = q.frame;
1041 nx = v->getXForFrame(nf); 1041 nx = v->getXForFrame(nf);
1042 ny = getYForValue(v, nvalue); 1042 ny = getYForValue(v, nvalue);
1043 haveNext = true; 1043 haveNext = true;
1044 } 1044 }
1045 1045
1046 // cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 1046 // cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext
1047 // << ", nx = " << nx << endl; 1047 // << ", nx = " << nx << endl;
1048 1048
1049 QPen pen(getBaseQColor());
1050 QBrush brush(brushColour);
1051
1049 if (m_plotStyle == PlotDiscreteCurves) { 1052 if (m_plotStyle == PlotDiscreteCurves) {
1050 paint.setPen(QPen(getBaseQColor(), 3)); 1053 pen = QPen(getBaseQColor(), 3);
1051 paint.setBrush(Qt::NoBrush); 1054 brush = QBrush(Qt::NoBrush);
1052 } else if (m_plotStyle == PlotSegmentation) { 1055 } else if (m_plotStyle == PlotSegmentation) {
1053 paint.setPen(getForegroundQColor(v)); 1056 pen = QPen(getForegroundQColor(v));
1054 paint.setBrush(getColourForValue(v, value)); 1057 brush = QBrush(getColourForValue(v, value));
1055 } else if (m_plotStyle == PlotLines || 1058 } else if (m_plotStyle == PlotLines ||
1056 m_plotStyle == PlotCurve) { 1059 m_plotStyle == PlotCurve) {
1057 paint.setPen(getBaseQColor()); 1060 brush = QBrush(Qt::NoBrush);
1058 paint.setBrush(Qt::NoBrush); 1061 }
1059 } else { 1062
1060 paint.setPen(getBaseQColor()); 1063 paint.setPen(PaintAssistant::scalePen(pen));
1061 paint.setBrush(brushColour); 1064 paint.setBrush(brush);
1062 } 1065
1063 1066 if (m_plotStyle == PlotStems) {
1064 if (m_plotStyle == PlotStems) { 1067 if (y < origin - 1) {
1065 /* 1068 paint.drawLine(x + w/2, y + 1, x + w/2, origin);
1066 paint.setPen(brushColour); 1069 } else if (y > origin + 1) {
1067 if (y < origin - 1) { 1070 paint.drawLine(x + w/2, origin, x + w/2, y - 1);
1068 paint.drawRect(x + w/2, y + 1, 1, origin - y); 1071 }
1069 } else if (y > origin + 1) { 1072 }
1070 paint.drawRect(x + w/2, origin, 1, y - origin - 1);
1071 }
1072 */
1073 paint.setPen(getBaseQColor());
1074 if (y < origin - 1) {
1075 paint.drawLine(x + w/2, y + 1, x + w/2, origin);
1076 } else if (y > origin + 1) {
1077 paint.drawLine(x + w/2, origin, x + w/2, y - 1);
1078 }
1079 }
1080 1073
1081 bool illuminate = false; 1074 bool illuminate = false;
1082 1075
1083 if (illuminateFrame == p.frame) { 1076 if (illuminateFrame == p.frame) {
1084 1077
1085 // not equipped to illuminate the right section in line 1078 // not equipped to illuminate the right section in line
1086 // or curve mode 1079 // or curve mode
1087 1080
1088 if (m_plotStyle != PlotCurve && 1081 if (m_plotStyle != PlotCurve &&
1089 m_plotStyle != PlotDiscreteCurves && 1082 m_plotStyle != PlotDiscreteCurves &&
1090 m_plotStyle != PlotLines) { 1083 m_plotStyle != PlotLines) {
1091 illuminate = true; 1084 illuminate = true;
1092 } 1085 }
1093 } 1086 }
1094 1087
1095 if (m_plotStyle != PlotLines && 1088 if (m_plotStyle != PlotLines &&
1096 m_plotStyle != PlotCurve && 1089 m_plotStyle != PlotCurve &&
1097 m_plotStyle != PlotDiscreteCurves && 1090 m_plotStyle != PlotDiscreteCurves &&
1098 m_plotStyle != PlotSegmentation) { 1091 m_plotStyle != PlotSegmentation) {
1099 if (illuminate) { 1092 if (illuminate) {
1100 paint.save(); 1093 paint.save();
1101 paint.setPen(getForegroundQColor(v)); 1094 paint.setPen(PaintAssistant::scalePen(getForegroundQColor(v)));
1102 paint.setBrush(getForegroundQColor(v)); 1095 paint.setBrush(getForegroundQColor(v));
1103 } 1096 }
1104 if (m_plotStyle != PlotStems || 1097 if (m_plotStyle != PlotStems ||
1105 w > 1) { 1098 w > 1) {
1106 paint.drawRect(x, y - 1, w, 2); 1099 paint.drawRect(x, y - 1, w, 2);
1107 } 1100 }
1108 if (illuminate) { 1101 if (illuminate) {
1109 paint.restore(); 1102 paint.restore();
1110 } 1103 }
1111 } 1104 }
1112 1105
1113 if (m_plotStyle == PlotConnectedPoints || 1106 if (m_plotStyle == PlotConnectedPoints ||
1114 m_plotStyle == PlotLines || 1107 m_plotStyle == PlotLines ||
1115 m_plotStyle == PlotDiscreteCurves || 1108 m_plotStyle == PlotDiscreteCurves ||
1116 m_plotStyle == PlotCurve) { 1109 m_plotStyle == PlotCurve) {
1117 1110
1118 if (haveNext) { 1111 if (haveNext) {
1119 1112
1120 if (m_plotStyle == PlotConnectedPoints) { 1113 if (m_plotStyle == PlotConnectedPoints) {
1121 1114
1122 paint.save(); 1115 paint.save();
1123 paint.setPen(brushColour); 1116 paint.setPen(PaintAssistant::scalePen(brushColour));
1124 paint.drawLine(x + w, y, nx, ny); 1117 paint.drawLine(x + w, y, nx, ny);
1125 paint.restore(); 1118 paint.restore();
1126 1119
1127 } else if (m_plotStyle == PlotLines) { 1120 } else if (m_plotStyle == PlotLines) {
1128 1121
1129 if (pointCount == 0) { 1122 if (pointCount == 0) {
1130 path.moveTo(x + w/2, y); 1123 path.moveTo(x + w/2, y);
1131 } 1124 }
1132 1125
1133 // paint.drawLine(x + w/2, y, nx + w/2, ny); 1126 // paint.drawLine(x + w/2, y, nx + w/2, ny);
1134 path.lineTo(nx + w/2, ny); 1127 path.lineTo(nx + w/2, ny);
1135 1128
1136 } else { 1129 } else {
1137 1130
1138 double x0 = x + double(w)/2; 1131 double x0 = x + double(w)/2;
1139 double x1 = nx + double(w)/2; 1132 double x1 = nx + double(w)/2;
1140 1133
1141 double y0 = y; 1134 double y0 = y;
1142 double y1 = ny; 1135 double y1 = ny;
1143 1136
1144 if (m_plotStyle == PlotDiscreteCurves) { 1137 if (m_plotStyle == PlotDiscreteCurves) {
1145 bool nextGap = 1138 bool nextGap =
1146 (nvalue == 0.0) || 1139 (nvalue == 0.0) ||
1147 (nf - p.frame >= m_model->getResolution() * 2); 1140 (nf - p.frame >= m_model->getResolution() * 2);
1149 x1 = x0; 1142 x1 = x0;
1150 y1 = y0; 1143 y1 = y0;
1151 } 1144 }
1152 } 1145 }
1153 1146
1154 if (pointCount == 0 || gap) { 1147 if (pointCount == 0 || gap) {
1155 path.moveTo((x0 + x1) / 2, (y0 + y1) / 2); 1148 path.moveTo((x0 + x1) / 2, (y0 + y1) / 2);
1156 } 1149 }
1157 1150
1158 if (nx - x > 5) { 1151 if (nx - x > 5) {
1159 path.cubicTo(x0, y0, 1152 path.cubicTo(x0, y0,
1160 x0, y0, 1153 x0, y0,
1161 (x0 + x1) / 2, (y0 + y1) / 2); 1154 (x0 + x1) / 2, (y0 + y1) / 2);
1162 1155
1163 // // or 1156 // // or
1164 // path.quadTo(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2); 1157 // path.quadTo(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2);
1165 1158
1166 } else { 1159 } else {
1167 path.lineTo(x0, y0); 1160 path.lineTo(x0, y0);
1168 path.lineTo((x0 + x1) / 2, (y0 + y1) / 2); 1161 path.lineTo((x0 + x1) / 2, (y0 + y1) / 2);
1169 } 1162 }
1170 } 1163 }
1171 } 1164 }
1172 } 1165 }
1173 1166
1174 if (m_plotStyle == PlotSegmentation) { 1167 if (m_plotStyle == PlotSegmentation) {
1175 1168
1176 #ifdef DEBUG_TIME_VALUE_LAYER 1169 #ifdef DEBUG_TIME_VALUE_LAYER
1177 cerr << "drawing rect" << endl; 1170 cerr << "drawing rect" << endl;
1178 #endif 1171 #endif
1179 1172
1180 if (nx <= x) continue; 1173 if (nx <= x) continue;
1181 1174
1182 paint.setPen(QPen(getForegroundQColor(v), 2)); 1175 paint.setPen(PaintAssistant::scalePen(QPen(getForegroundQColor(v), 2)));
1183 1176
1184 if (!illuminate) { 1177 if (!illuminate) {
1185 if (!m_drawSegmentDivisions || 1178 if (!m_drawSegmentDivisions ||
1186 nx < x + 5 || 1179 nx < x + 5 ||
1187 x >= v->getPaintWidth() - 1) { 1180 x >= v->getPaintWidth() - 1) {
1188 paint.setPen(Qt::NoPen); 1181 paint.setPen(Qt::NoPen);
1189 } 1182 }
1190 } 1183 }
1191 1184
1192 paint.drawRect(x, -1, nx - x, v->getPaintHeight() + 1); 1185 paint.drawRect(x, -1, nx - x, v->getPaintHeight() + 1);
1193 } 1186 }
1194 1187
1195 if (v->shouldShowFeatureLabels()) { 1188 if (v->shouldShowFeatureLabels()) {
1196 1189
1197 QString label = p.label; 1190 QString label = p.label;
1198 bool italic = false; 1191 bool italic = false;
1227 ++pointCount; 1220 ++pointCount;
1228 } 1221 }
1229 1222
1230 if (m_plotStyle == PlotDiscreteCurves) { 1223 if (m_plotStyle == PlotDiscreteCurves) {
1231 paint.setRenderHint(QPainter::Antialiasing, true); 1224 paint.setRenderHint(QPainter::Antialiasing, true);
1232 paint.drawPath(path); 1225 paint.drawPath(path);
1233 } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines) 1226 } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines)
1234 && !path.isEmpty()) { 1227 && !path.isEmpty()) {
1235 paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->getPaintWidth()); 1228 paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->getPaintWidth());
1236 paint.drawPath(path); 1229 paint.drawPath(path);
1237 } 1230 }
1238 1231
1239 paint.restore(); 1232 paint.restore();
1240 1233
1241 // looks like save/restore doesn't deal with this: 1234 // looks like save/restore doesn't deal with this:
1243 } 1236 }
1244 1237
1245 int 1238 int
1246 TimeValueLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const 1239 TimeValueLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const
1247 { 1240 {
1248 if (!m_model || shouldAutoAlign()) { 1241 if (!m_model) {
1242 return 0;
1243 } else if (shouldAutoAlign() && !valueExtentsMatchMine(v)) {
1249 return 0; 1244 return 0;
1250 } else if (m_plotStyle == PlotSegmentation) { 1245 } else if (m_plotStyle == PlotSegmentation) {
1251 if (m_verticalScale == LogScale) { 1246 if (m_verticalScale == LogScale) {
1252 return LogColourScale().getWidth(v, paint); 1247 return LogColourScale().getWidth(v, paint);
1253 } else { 1248 } else {
1354 1349
1355 m_originalPoint = m_editingPoint; 1350 m_originalPoint = m_editingPoint;
1356 1351
1357 if (m_editingCommand) finish(m_editingCommand); 1352 if (m_editingCommand) finish(m_editingCommand);
1358 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model, 1353 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model,
1359 tr("Draw Point")); 1354 tr("Draw Point"));
1360 if (!havePoint) { 1355 if (!havePoint) {
1361 m_editingCommand->addPoint(m_editingPoint); 1356 m_editingCommand->addPoint(m_editingPoint);
1362 } 1357 }
1363 1358
1364 m_editing = true; 1359 m_editing = true;
1447 if (points.empty()) return; 1442 if (points.empty()) return;
1448 1443
1449 m_editingPoint = *points.begin(); 1444 m_editingPoint = *points.begin();
1450 1445
1451 if (m_editingCommand) { 1446 if (m_editingCommand) {
1452 finish(m_editingCommand); 1447 finish(m_editingCommand);
1453 m_editingCommand = 0; 1448 m_editingCommand = 0;
1454 } 1449 }
1455 1450
1456 m_editing = true; 1451 m_editing = true;
1457 } 1452 }
1458 1453
1497 1492
1498 m_editingPoint = *points.begin(); 1493 m_editingPoint = *points.begin();
1499 m_originalPoint = m_editingPoint; 1494 m_originalPoint = m_editingPoint;
1500 1495
1501 if (m_editingCommand) { 1496 if (m_editingCommand) {
1502 finish(m_editingCommand); 1497 finish(m_editingCommand);
1503 m_editingCommand = 0; 1498 m_editingCommand = 0;
1504 } 1499 }
1505 1500
1506 m_editing = true; 1501 m_editing = true;
1507 } 1502 }
1508 1503
1520 frame = frame / m_model->getResolution() * m_model->getResolution(); 1515 frame = frame / m_model->getResolution() * m_model->getResolution();
1521 1516
1522 double value = getValueForY(v, e->y()); 1517 double value = getValueForY(v, e->y());
1523 1518
1524 if (!m_editingCommand) { 1519 if (!m_editingCommand) {
1525 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model, 1520 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model,
1526 tr("Drag Point")); 1521 tr("Drag Point"));
1527 } 1522 }
1528 1523
1529 m_editingCommand->deletePoint(m_editingPoint); 1524 m_editingCommand->deletePoint(m_editingPoint);
1530 m_editingPoint.frame = frame; 1525 m_editingPoint.frame = frame;
1531 m_editingPoint.value = float(value); 1526 m_editingPoint.value = float(value);
1540 #endif 1535 #endif
1541 if (!m_model || !m_editing) return; 1536 if (!m_model || !m_editing) return;
1542 1537
1543 if (m_editingCommand) { 1538 if (m_editingCommand) {
1544 1539
1545 QString newName = m_editingCommand->getName(); 1540 QString newName = m_editingCommand->getName();
1546 1541
1547 if (m_editingPoint.frame != m_originalPoint.frame) { 1542 if (m_editingPoint.frame != m_originalPoint.frame) {
1548 if (m_editingPoint.value != m_originalPoint.value) { 1543 if (m_editingPoint.value != m_originalPoint.value) {
1549 newName = tr("Edit Point"); 1544 newName = tr("Edit Point");
1550 } else { 1545 } else {
1551 newName = tr("Relocate Point"); 1546 newName = tr("Relocate Point");
1552 } 1547 }
1553 } else { 1548 } else {
1554 newName = tr("Change Point Value"); 1549 newName = tr("Change Point Value");
1555 } 1550 }
1556 1551
1557 m_editingCommand->setName(newName); 1552 m_editingCommand->setName(newName);
1558 finish(m_editingCommand); 1553 finish(m_editingCommand);
1559 } 1554 }
1560 1555
1561 m_editingCommand = 0; 1556 m_editingCommand = 0;
1562 m_editing = false; 1557 m_editing = false;
1563 } 1558 }
1605 TimeValueLayer::moveSelection(Selection s, sv_frame_t newStartFrame) 1600 TimeValueLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
1606 { 1601 {
1607 if (!m_model) return; 1602 if (!m_model) return;
1608 1603
1609 SparseTimeValueModel::EditCommand *command = 1604 SparseTimeValueModel::EditCommand *command =
1610 new SparseTimeValueModel::EditCommand(m_model, 1605 new SparseTimeValueModel::EditCommand(m_model,
1611 tr("Drag Selection")); 1606 tr("Drag Selection"));
1612 1607
1613 SparseTimeValueModel::PointList points = 1608 SparseTimeValueModel::PointList points =
1614 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1609 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1615 1610
1616 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1611 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1617 i != points.end(); ++i) { 1612 i != points.end(); ++i) {
1618 1613
1619 if (s.contains(i->frame)) { 1614 if (s.contains(i->frame)) {
1620 SparseTimeValueModel::Point newPoint(*i); 1615 SparseTimeValueModel::Point newPoint(*i);
1621 newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); 1616 newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
1622 command->deletePoint(*i); 1617 command->deletePoint(*i);
1623 command->addPoint(newPoint); 1618 command->addPoint(newPoint);
1624 } 1619 }
1625 } 1620 }
1626 1621
1627 finish(command); 1622 finish(command);
1628 } 1623 }
1629 1624
1631 TimeValueLayer::resizeSelection(Selection s, Selection newSize) 1626 TimeValueLayer::resizeSelection(Selection s, Selection newSize)
1632 { 1627 {
1633 if (!m_model) return; 1628 if (!m_model) return;
1634 1629
1635 SparseTimeValueModel::EditCommand *command = 1630 SparseTimeValueModel::EditCommand *command =
1636 new SparseTimeValueModel::EditCommand(m_model, 1631 new SparseTimeValueModel::EditCommand(m_model,
1637 tr("Resize Selection")); 1632 tr("Resize Selection"));
1638 1633
1639 SparseTimeValueModel::PointList points = 1634 SparseTimeValueModel::PointList points =
1640 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1635 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1641 1636
1642 double ratio = 1637 double ratio =
1643 double(newSize.getEndFrame() - newSize.getStartFrame()) / 1638 double(newSize.getEndFrame() - newSize.getStartFrame()) /
1644 double(s.getEndFrame() - s.getStartFrame()); 1639 double(s.getEndFrame() - s.getStartFrame());
1645 1640
1646 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1641 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1647 i != points.end(); ++i) { 1642 i != points.end(); ++i) {
1648 1643
1649 if (s.contains(i->frame)) { 1644 if (s.contains(i->frame)) {
1650 1645
1651 double target = double(i->frame); 1646 double target = double(i->frame);
1652 target = double(newSize.getStartFrame()) + 1647 target = double(newSize.getStartFrame()) +
1653 target - double(s.getStartFrame()) * ratio; 1648 target - double(s.getStartFrame()) * ratio;
1654 1649
1655 SparseTimeValueModel::Point newPoint(*i); 1650 SparseTimeValueModel::Point newPoint(*i);
1656 newPoint.frame = lrint(target); 1651 newPoint.frame = lrint(target);
1657 command->deletePoint(*i); 1652 command->deletePoint(*i);
1658 command->addPoint(newPoint); 1653 command->addPoint(newPoint);
1659 } 1654 }
1660 } 1655 }
1661 1656
1662 finish(command); 1657 finish(command);
1663 } 1658 }
1664 1659
1666 TimeValueLayer::deleteSelection(Selection s) 1661 TimeValueLayer::deleteSelection(Selection s)
1667 { 1662 {
1668 if (!m_model) return; 1663 if (!m_model) return;
1669 1664
1670 SparseTimeValueModel::EditCommand *command = 1665 SparseTimeValueModel::EditCommand *command =
1671 new SparseTimeValueModel::EditCommand(m_model, 1666 new SparseTimeValueModel::EditCommand(m_model,
1672 tr("Delete Selected Points")); 1667 tr("Delete Selected Points"));
1673 1668
1674 SparseTimeValueModel::PointList points = 1669 SparseTimeValueModel::PointList points =
1675 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1670 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1676 1671
1677 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1672 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1678 i != points.end(); ++i) { 1673 i != points.end(); ++i) {
1679 1674
1680 if (s.contains(i->frame)) { 1675 if (s.contains(i->frame)) {
1681 command->deletePoint(*i); 1676 command->deletePoint(*i);
1682 } 1677 }
1683 } 1678 }
1689 TimeValueLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) 1684 TimeValueLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
1690 { 1685 {
1691 if (!m_model) return; 1686 if (!m_model) return;
1692 1687
1693 SparseTimeValueModel::PointList points = 1688 SparseTimeValueModel::PointList points =
1694 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1689 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1695 1690
1696 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1691 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1697 i != points.end(); ++i) { 1692 i != points.end(); ++i) {
1698 if (s.contains(i->frame)) { 1693 if (s.contains(i->frame)) {
1699 Clipboard::Point point(i->frame, i->value, i->label); 1694 Clipboard::Point point(i->frame, i->value, i->label);
1700 point.setReferenceFrame(alignToReference(v, i->frame)); 1695 point.setReferenceFrame(alignToReference(v, i->frame));
1701 to.addPoint(point); 1696 to.addPoint(point);
1702 } 1697 }
1703 } 1698 }
1729 realign = true; 1724 realign = true;
1730 } 1725 }
1731 } 1726 }
1732 1727
1733 SparseTimeValueModel::EditCommand *command = 1728 SparseTimeValueModel::EditCommand *command =
1734 new SparseTimeValueModel::EditCommand(m_model, tr("Paste")); 1729 new SparseTimeValueModel::EditCommand(m_model, tr("Paste"));
1735 1730
1736 enum ValueAvailability { 1731 enum ValueAvailability {
1737 UnknownAvailability, 1732 UnknownAvailability,
1738 NoValues, 1733 NoValues,
1739 SomeValues, 1734 SomeValues,
1933 1928
1934 int cmap = attributes.value("colourMap").toInt(&ok); 1929 int cmap = attributes.value("colourMap").toInt(&ok);
1935 if (ok) setFillColourMap(cmap); 1930 if (ok) setFillColourMap(cmap);
1936 1931
1937 PlotStyle style = (PlotStyle) 1932 PlotStyle style = (PlotStyle)
1938 attributes.value("plotStyle").toInt(&ok); 1933 attributes.value("plotStyle").toInt(&ok);
1939 if (ok) setPlotStyle(style); 1934 if (ok) setPlotStyle(style);
1940 1935
1941 VerticalScale scale = (VerticalScale) 1936 VerticalScale scale = (VerticalScale)
1942 attributes.value("verticalScale").toInt(&ok); 1937 attributes.value("verticalScale").toInt(&ok);
1943 if (ok) setVerticalScale(scale); 1938 if (ok) setVerticalScale(scale);
1944 1939
1945 bool draw = (attributes.value("drawDivisions").trimmed() == "true"); 1940 bool draw = (attributes.value("drawDivisions").trimmed() == "true");
1946 setDrawSegmentDivisions(draw); 1941 setDrawSegmentDivisions(draw);
1947 1942