comparison layer/TimeValueLayer.cpp @ 1429:8a7c82282fbc single-point

Update TimeValueLayer etc
author Chris Cannam
date Tue, 19 Mar 2019 13:06:35 +0000
parents 62e908518c71
children 31499c3520ee
comparison
equal deleted inserted replaced
1428:c9fa16e41664 1429:8a7c82282fbc
529 } 529 }
530 530
531 return mapper; 531 return mapper;
532 } 532 }
533 533
534 SparseTimeValueModel::PointList 534 EventVector
535 TimeValueLayer::getLocalPoints(LayerGeometryProvider *v, int x) const 535 TimeValueLayer::getLocalPoints(LayerGeometryProvider *v, int x) const
536 { 536 {
537 if (!m_model) return SparseTimeValueModel::PointList(); 537 if (!m_model) return {};
538 538
539 sv_frame_t frame = v->getFrameForX(x); 539 sv_frame_t frame = v->getFrameForX(x);
540 540
541 SparseTimeValueModel::PointList onPoints = 541 //!!! this is not going to be right - we want "nearby" points and
542 m_model->getPoints(frame); 542 //!!! there's no api for that
543 543
544 if (!onPoints.empty()) { 544 EventVector local = m_model->getEventsCovering(frame);
545 return onPoints; 545 if (!local.empty()) return local;
546 } 546
547 return {};
548 /*!!!
547 549
548 SparseTimeValueModel::PointList prevPoints = 550 SparseTimeValueModel::PointList prevPoints =
549 m_model->getPreviousPoints(frame); 551 m_model->getPreviousPoints(frame);
550 SparseTimeValueModel::PointList nextPoints = 552 SparseTimeValueModel::PointList nextPoints =
551 m_model->getNextPoints(frame); 553 m_model->getNextPoints(frame);
572 usePoints.clear(); 574 usePoints.clear();
573 } 575 }
574 } 576 }
575 577
576 return usePoints; 578 return usePoints;
579 */
577 } 580 }
578 581
579 QString 582 QString
580 TimeValueLayer::getLabelPreceding(sv_frame_t frame) const 583 TimeValueLayer::getLabelPreceding(sv_frame_t /* frame */) const
581 { 584 {
582 if (!m_model) return ""; 585 if (!m_model || !m_model->hasTextLabels()) return "";
583 SparseTimeValueModel::PointList points = m_model->getPreviousPoints(frame); 586 /*!!! no corresponding api yet
584 for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); 587 EventVector points = m_model->getPreviousPoints(frame);
588 for (EventVector::const_iterator i = points.begin();
585 i != points.end(); ++i) { 589 i != points.end(); ++i) {
586 if (i->label != "") return i->label; 590 if (i->getLabel() != "") return i->getLabel();
587 } 591 }
592 */
588 return ""; 593 return "";
589 } 594 }
590 595
591 QString 596 QString
592 TimeValueLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 597 TimeValueLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
593 { 598 {
594 int x = pos.x(); 599 int x = pos.x();
595 600
596 if (!m_model || !m_model->getSampleRate()) return ""; 601 if (!m_model || !m_model->getSampleRate()) return "";
597 602
598 SparseTimeValueModel::PointList points = getLocalPoints(v, x); 603 EventVector points = getLocalPoints(v, x);
599 604
600 if (points.empty()) { 605 if (points.empty()) {
601 if (!m_model->isReady()) { 606 if (!m_model->isReady()) {
602 return tr("In progress"); 607 return tr("In progress");
603 } else { 608 } else {
604 return tr("No local points"); 609 return tr("No local points");
605 } 610 }
606 } 611 }
607 612
608 sv_frame_t useFrame = points.begin()->frame; 613 sv_frame_t useFrame = points.begin()->getFrame();
609 614
610 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 615 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
611 616
612 QString valueText; 617 QString valueText;
613 float value = points.begin()->value; 618 float value = points.begin()->getValue();
614 QString unit = getScaleUnits(); 619 QString unit = getScaleUnits();
615 620
616 if (unit == "Hz") { 621 if (unit == "Hz") {
617 valueText = tr("%1 Hz (%2, %3)") 622 valueText = tr("%1 Hz (%2, %3)")
618 .arg(value) 623 .arg(value)
624 valueText = tr("%1").arg(value); 629 valueText = tr("%1").arg(value);
625 } 630 }
626 631
627 QString text; 632 QString text;
628 633
629 if (points.begin()->label == "") { 634 if (points.begin()->getLabel() == "") {
630 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label")) 635 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label"))
631 .arg(rt.toText(true).c_str()) 636 .arg(rt.toText(true).c_str())
632 .arg(valueText); 637 .arg(valueText);
633 } else { 638 } else {
634 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%4")) 639 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%4"))
635 .arg(rt.toText(true).c_str()) 640 .arg(rt.toText(true).c_str())
636 .arg(valueText) 641 .arg(valueText)
637 .arg(points.begin()->label); 642 .arg(points.begin()->getLabel());
638 } 643 }
639 644
640 pos = QPoint(v->getXForFrame(useFrame), 645 pos = QPoint(v->getXForFrame(useFrame),
641 getYForValue(v, points.begin()->value)); 646 getYForValue(v, points.begin()->getValue()));
642 return text; 647 return text;
643 } 648 }
644 649
645 bool 650 bool
646 TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 651 TimeValueLayer::snapToFeatureFrame(LayerGeometryProvider *v,
652 sv_frame_t &frame,
647 int &resolution, 653 int &resolution,
648 SnapType snap) const 654 SnapType snap) const
649 { 655 {
650 if (!m_model) { 656 if (!m_model) {
651 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 657 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
652 } 658 }
653 659
654 resolution = m_model->getResolution(); 660 resolution = m_model->getResolution();
655 SparseTimeValueModel::PointList points; 661 EventVector points;
656 662
657 if (snap == SnapNeighbouring) { 663 if (snap == SnapNeighbouring) {
658
659 points = getLocalPoints(v, v->getXForFrame(frame)); 664 points = getLocalPoints(v, v->getXForFrame(frame));
660 if (points.empty()) return false; 665 if (points.empty()) return false;
661 frame = points.begin()->frame; 666 frame = points.begin()->getFrame();
662 return true; 667 return true;
663 } 668 }
664 669
665 points = m_model->getPoints(frame, frame); 670 //!!! again, wrong api - correct one is not here yet
671 points = m_model->getEventsCovering(frame);
666 sv_frame_t snapped = frame; 672 sv_frame_t snapped = frame;
667 bool found = false; 673 bool found = false;
668 674
669 for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); 675 for (EventVector::const_iterator i = points.begin();
670 i != points.end(); ++i) { 676 i != points.end(); ++i) {
671 677
672 if (snap == SnapRight) { 678 if (snap == SnapRight) {
673 679
674 if (i->frame > frame) { 680 if (i->getFrame() > frame) {
675 snapped = i->frame; 681 snapped = i->getFrame();
676 found = true; 682 found = true;
677 break; 683 break;
678 } 684 }
679 685
680 } else if (snap == SnapLeft) { 686 } else if (snap == SnapLeft) {
681 687
682 if (i->frame <= frame) { 688 if (i->getFrame() <= frame) {
683 snapped = i->frame; 689 snapped = i->getFrame();
684 found = true; // don't break, as the next may be better 690 found = true; // don't break, as the next may be better
685 } else { 691 } else {
686 break; 692 break;
687 } 693 }
688 694
689 } else { // nearest 695 } else { // nearest
690 696
691 SparseTimeValueModel::PointList::const_iterator j = i; 697 EventVector::const_iterator j = i;
692 ++j; 698 ++j;
693 699
694 if (j == points.end()) { 700 if (j == points.end()) {
695 701
696 snapped = i->frame; 702 snapped = i->getFrame();
697 found = true; 703 found = true;
698 break; 704 break;
699 705
700 } else if (j->frame >= frame) { 706 } else if (j->getFrame() >= frame) {
701 707
702 if (j->frame - frame < frame - i->frame) { 708 if (j->getFrame() - frame < frame - i->getFrame()) {
703 snapped = j->frame; 709 snapped = j->getFrame();
704 } else { 710 } else {
705 snapped = i->frame; 711 snapped = i->getFrame();
706 } 712 }
707 found = true; 713 found = true;
708 break; 714 break;
709 } 715 }
710 } 716 }
723 return Layer::snapToSimilarFeature(v, frame, resolution, snap); 729 return Layer::snapToSimilarFeature(v, frame, resolution, snap);
724 } 730 }
725 731
726 resolution = m_model->getResolution(); 732 resolution = m_model->getResolution();
727 733
728 const SparseTimeValueModel::PointList &points = m_model->getPoints(); 734 /*!!! todo: overhaul the logic of this function (and supporting
729 SparseTimeValueModel::PointList close = m_model->getPoints(frame, frame); 735 apis in EventSeries / SparseTimeValueModel)
730 736
731 SparseTimeValueModel::PointList::const_iterator i; 737 const EventVector &points = m_model->getPoints();
738 EventVector close = m_model->getPoints(frame, frame);
739 */
740 const EventVector &points = m_model->getAllEvents();
741 EventVector close = {};
742
743 EventVector::const_iterator i;
732 744
733 sv_frame_t matchframe = frame; 745 sv_frame_t matchframe = frame;
734 double matchvalue = 0.0; 746 double matchvalue = 0.0;
735 747
736 for (i = close.begin(); i != close.end(); ++i) { 748 for (i = close.begin(); i != close.end(); ++i) {
737 if (i->frame > frame) break; 749 if (i->getFrame() > frame) break;
738 matchvalue = i->value; 750 matchvalue = i->getValue();
739 matchframe = i->frame; 751 matchframe = i->getFrame();
740 } 752 }
741 753
742 sv_frame_t snapped = frame; 754 sv_frame_t snapped = frame;
743 bool found = false; 755 bool found = false;
744 bool distant = false; 756 bool distant = false;
764 } 776 }
765 } 777 }
766 778
767 if (snap == SnapRight) { 779 if (snap == SnapRight) {
768 780
769 if (i->frame > matchframe && 781 if (i->getFrame() > matchframe &&
770 fabs(i->value - matchvalue) < epsilon) { 782 fabs(i->getValue() - matchvalue) < epsilon) {
771 snapped = i->frame; 783 snapped = i->getFrame();
772 found = true; 784 found = true;
773 break; 785 break;
774 } 786 }
775 787
776 } else if (snap == SnapLeft) { 788 } else if (snap == SnapLeft) {
777 789
778 if (i->frame < matchframe) { 790 if (i->getFrame() < matchframe) {
779 if (fabs(i->value - matchvalue) < epsilon) { 791 if (fabs(i->getValue() - matchvalue) < epsilon) {
780 snapped = i->frame; 792 snapped = i->getFrame();
781 found = true; // don't break, as the next may be better 793 found = true; // don't break, as the next may be better
782 } 794 }
783 } else if (found || distant) { 795 } else if (found || distant) {
784 break; 796 break;
785 } 797 }
924 int x0 = rect.left(), x1 = rect.right(); 936 int x0 = rect.left(), x1 = rect.right();
925 sv_frame_t frame0 = v->getFrameForX(x0); 937 sv_frame_t frame0 = v->getFrameForX(x0);
926 sv_frame_t frame1 = v->getFrameForX(x1); 938 sv_frame_t frame1 = v->getFrameForX(x1);
927 if (m_derivative) --frame0; 939 if (m_derivative) --frame0;
928 940
929 SparseTimeValueModel::PointList points(m_model->getPoints 941 EventVector points(m_model->getEventsWithin(frame0, frame1 - frame0));
930 (frame0, frame1));
931 if (points.empty()) return; 942 if (points.empty()) return;
932 943
933 paint.setPen(getBaseQColor()); 944 paint.setPen(getBaseQColor());
934 945
935 QColor brushColour(getBaseQColor()); 946 QColor brushColour(getBaseQColor());
950 961
951 QPoint localPos; 962 QPoint localPos;
952 sv_frame_t illuminateFrame = -1; 963 sv_frame_t illuminateFrame = -1;
953 964
954 if (v->shouldIlluminateLocalFeatures(this, localPos)) { 965 if (v->shouldIlluminateLocalFeatures(this, localPos)) {
955 SparseTimeValueModel::PointList localPoints = 966 EventVector localPoints = getLocalPoints(v, localPos.x());
956 getLocalPoints(v, localPos.x());
957 #ifdef DEBUG_TIME_VALUE_LAYER 967 #ifdef DEBUG_TIME_VALUE_LAYER
958 cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl; 968 cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl;
959 #endif 969 #endif
960 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame; 970 if (!localPoints.empty()) {
971 illuminateFrame = localPoints.begin()->getFrame();
972 }
961 } 973 }
962 974
963 int w = 975 int w =
964 v->getXForFrame(frame0 + m_model->getResolution()) - 976 v->getXForFrame(frame0 + m_model->getResolution()) -
965 v->getXForFrame(frame0); 977 v->getXForFrame(frame0);
988 } 1000 }
989 } 1001 }
990 1002
991 sv_frame_t prevFrame = 0; 1003 sv_frame_t prevFrame = 0;
992 1004
993 for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); 1005 for (EventVector::const_iterator i = points.begin();
994 i != points.end(); ++i) { 1006 i != points.end(); ++i) {
995 1007
996 if (m_derivative && i == points.begin()) continue; 1008 if (m_derivative && i == points.begin()) continue;
997 1009
998 const SparseTimeValueModel::Point &p(*i); 1010 Event p(*i);
999 1011
1000 double value = p.value; 1012 double value = p.getValue();
1001 if (m_derivative) { 1013 if (m_derivative) {
1002 SparseTimeValueModel::PointList::const_iterator j = i; 1014 EventVector::const_iterator j = i;
1003 --j; 1015 --j;
1004 value -= j->value; 1016 value -= j->getValue();
1005 } 1017 }
1006 1018
1007 int x = v->getXForFrame(p.frame); 1019 int x = v->getXForFrame(p.getFrame());
1008 int y = getYForValue(v, value); 1020 int y = getYForValue(v, value);
1009 1021
1010 bool gap = false; 1022 bool gap = false;
1011 if (m_plotStyle == PlotDiscreteCurves) { 1023 if (m_plotStyle == PlotDiscreteCurves) {
1012 if (value == 0.0) { 1024 if (value == 0.0) {
1013 // Treat zeros as gaps 1025 // Treat zeros as gaps
1014 continue; 1026 continue;
1015 } 1027 }
1016 gap = (p.frame > prevFrame && 1028 gap = (p.getFrame() > prevFrame &&
1017 (p.frame - prevFrame >= m_model->getResolution() * 2)); 1029 (p.getFrame() - prevFrame >= m_model->getResolution() * 2));
1018 } 1030 }
1019 1031
1020 if (m_plotStyle != PlotSegmentation) { 1032 if (m_plotStyle != PlotSegmentation) {
1021 textY = y - paint.fontMetrics().height() 1033 textY = y - paint.fontMetrics().height()
1022 + paint.fontMetrics().ascent() - 1; 1034 + paint.fontMetrics().ascent() - 1;
1029 double nvalue = 0.f; 1041 double nvalue = 0.f;
1030 sv_frame_t nf = v->getModelsEndFrame(); 1042 sv_frame_t nf = v->getModelsEndFrame();
1031 int nx = v->getXForFrame(nf); 1043 int nx = v->getXForFrame(nf);
1032 int ny = y; 1044 int ny = y;
1033 1045
1034 SparseTimeValueModel::PointList::const_iterator j = i; 1046 EventVector::const_iterator j = i;
1035 ++j; 1047 ++j;
1036 1048
1037 if (j != points.end()) { 1049 if (j != points.end()) {
1038 const SparseTimeValueModel::Point &q(*j); 1050 Event q(*j);
1039 nvalue = q.value; 1051 nvalue = q.getValue();
1040 if (m_derivative) nvalue -= p.value; 1052 if (m_derivative) nvalue -= p.getValue();
1041 nf = q.frame; 1053 nf = q.getFrame();
1042 nx = v->getXForFrame(nf); 1054 nx = v->getXForFrame(nf);
1043 ny = getYForValue(v, nvalue); 1055 ny = getYForValue(v, nvalue);
1044 haveNext = true; 1056 haveNext = true;
1045 } 1057 }
1046 1058
1047 // cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 1059 // cout << "frame = " << p.getFrame() << ", x = " << x << ", haveNext = " << haveNext
1048 // << ", nx = " << nx << endl; 1060 // << ", nx = " << nx << endl;
1049 1061
1050 QPen pen(getBaseQColor()); 1062 QPen pen(getBaseQColor());
1051 QBrush brush(brushColour); 1063 QBrush brush(brushColour);
1052 1064
1072 } 1084 }
1073 } 1085 }
1074 1086
1075 bool illuminate = false; 1087 bool illuminate = false;
1076 1088
1077 if (illuminateFrame == p.frame) { 1089 if (illuminateFrame == p.getFrame()) {
1078 1090
1079 // not equipped to illuminate the right section in line 1091 // not equipped to illuminate the right section in line
1080 // or curve mode 1092 // or curve mode
1081 1093
1082 if (m_plotStyle != PlotCurve && 1094 if (m_plotStyle != PlotCurve &&
1136 double y1 = ny; 1148 double y1 = ny;
1137 1149
1138 if (m_plotStyle == PlotDiscreteCurves) { 1150 if (m_plotStyle == PlotDiscreteCurves) {
1139 bool nextGap = 1151 bool nextGap =
1140 (nvalue == 0.0) || 1152 (nvalue == 0.0) ||
1141 (nf - p.frame >= m_model->getResolution() * 2); 1153 (nf - p.getFrame() >= m_model->getResolution() * 2);
1142 if (nextGap) { 1154 if (nextGap) {
1143 x1 = x0; 1155 x1 = x0;
1144 y1 = y0; 1156 y1 = y0;
1145 } 1157 }
1146 } 1158 }
1186 paint.drawRect(x, -1, nx - x, v->getPaintHeight() + 1); 1198 paint.drawRect(x, -1, nx - x, v->getPaintHeight() + 1);
1187 } 1199 }
1188 1200
1189 if (v->shouldShowFeatureLabels()) { 1201 if (v->shouldShowFeatureLabels()) {
1190 1202
1191 QString label = p.label; 1203 QString label = p.getLabel();
1192 bool italic = false; 1204 bool italic = false;
1193 1205
1194 if (label == "" && 1206 if (label == "" &&
1195 (m_plotStyle == PlotPoints || 1207 (m_plotStyle == PlotPoints ||
1196 m_plotStyle == PlotSegmentation || 1208 m_plotStyle == PlotSegmentation ||
1197 m_plotStyle == PlotConnectedPoints)) { 1209 m_plotStyle == PlotConnectedPoints)) {
1198 char lc[20]; 1210 char lc[20];
1199 snprintf(lc, 20, "%.3g", p.value); 1211 snprintf(lc, 20, "%.3g", p.getValue());
1200 label = lc; 1212 label = lc;
1201 italic = true; 1213 italic = true;
1202 } 1214 }
1203 1215
1204 if (label != "") { 1216 if (label != "") {
1207 haveRoom = (haveRoom && 1219 haveRoom = (haveRoom &&
1208 (nx > x + 6 + paint.fontMetrics().width(label))); 1220 (nx > x + 6 + paint.fontMetrics().width(label)));
1209 if (haveRoom || 1221 if (haveRoom ||
1210 (!haveNext && 1222 (!haveNext &&
1211 (pointCount == 0 || !italic))) { 1223 (pointCount == 0 || !italic))) {
1212 PaintAssistant::drawVisibleText(v, paint, x + 5, textY, label, 1224 PaintAssistant::drawVisibleText
1213 italic ? 1225 (v, paint, x + 5, textY, label,
1214 PaintAssistant::OutlinedItalicText : 1226 italic ?
1215 PaintAssistant::OutlinedText); 1227 PaintAssistant::OutlinedItalicText :
1228 PaintAssistant::OutlinedText);
1216 } 1229 }
1217 } 1230 }
1218 } 1231 }
1219 1232
1220 prevFrame = p.frame; 1233 prevFrame = p.getFrame();
1221 ++pointCount; 1234 ++pointCount;
1222 } 1235 }
1223 1236
1224 if (m_plotStyle == PlotDiscreteCurves) { 1237 if (m_plotStyle == PlotDiscreteCurves) {
1225 paint.setRenderHint(QPainter::Antialiasing, true); 1238 paint.setRenderHint(QPainter::Antialiasing, true);
1259 } 1272 }
1260 1273
1261 void 1274 void
1262 TimeValueLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const 1275 TimeValueLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const
1263 { 1276 {
1264 if (!m_model || m_model->getPoints().empty()) return; 1277 if (!m_model || m_model->isEmpty()) return;
1265 1278
1266 QString unit; 1279 QString unit;
1267 double min, max; 1280 double min, max;
1268 bool logarithmic; 1281 bool logarithmic;
1269 1282
1326 1339
1327 double value = getValueForY(v, e->y()); 1340 double value = getValueForY(v, e->y());
1328 1341
1329 bool havePoint = false; 1342 bool havePoint = false;
1330 1343
1331 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1344 EventVector points = getLocalPoints(v, e->x());
1332 if (!points.empty()) { 1345 if (!points.empty()) {
1333 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1346 for (EventVector::iterator i = points.begin();
1334 i != points.end(); ++i) { 1347 i != points.end(); ++i) {
1335 if (((i->frame / resolution) * resolution) != frame) { 1348 if (((i->getFrame() / resolution) * resolution) != frame) {
1336 #ifdef DEBUG_TIME_VALUE_LAYER 1349 #ifdef DEBUG_TIME_VALUE_LAYER
1337 cerr << "ignoring out-of-range frame at " << i->frame << endl; 1350 cerr << "ignoring out-of-range frame at " << i->getFrame() << endl;
1338 #endif 1351 #endif
1339 continue; 1352 continue;
1340 } 1353 }
1341 m_editingPoint = *i; 1354 m_editingPoint = *i;
1342 havePoint = true; 1355 havePoint = true;
1343 } 1356 }
1344 } 1357 }
1345 1358
1346 if (!havePoint) { 1359 if (!havePoint) {
1347 m_editingPoint = SparseTimeValueModel::Point 1360 m_editingPoint = Event(frame, float(value), tr("New Point"));
1348 (frame, float(value), tr("New Point"));
1349 } 1361 }
1350 1362
1351 m_originalPoint = m_editingPoint; 1363 m_originalPoint = m_editingPoint;
1352 1364
1353 if (m_editingCommand) finish(m_editingCommand); 1365 if (m_editingCommand) finish(m_editingCommand);
1354 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model, 1366 m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point"));
1355 tr("Draw Point"));
1356 if (!havePoint) { 1367 if (!havePoint) {
1357 m_editingCommand->addPoint(m_editingPoint); 1368 m_editingCommand->add(m_editingPoint);
1358 } 1369 }
1359 1370
1360 m_editing = true; 1371 m_editing = true;
1361 } 1372 }
1362 1373
1374 if (frame < 0) frame = 0; 1385 if (frame < 0) frame = 0;
1375 frame = (frame / resolution) * resolution; 1386 frame = (frame / resolution) * resolution;
1376 1387
1377 double value = getValueForY(v, e->y()); 1388 double value = getValueForY(v, e->y());
1378 1389
1379 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1390 EventVector points = getLocalPoints(v, e->x());
1380 1391
1381 #ifdef DEBUG_TIME_VALUE_LAYER 1392 #ifdef DEBUG_TIME_VALUE_LAYER
1382 cerr << points.size() << " points" << endl; 1393 cerr << points.size() << " points" << endl;
1383 #endif 1394 #endif
1384 1395
1385 bool havePoint = false; 1396 bool havePoint = false;
1386 1397
1387 if (!points.empty()) { 1398 if (!points.empty()) {
1388 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1399 for (EventVector::iterator i = points.begin();
1389 i != points.end(); ++i) { 1400 i != points.end(); ++i) {
1390 if (i->frame == m_editingPoint.frame && 1401 if (i->getFrame() == m_editingPoint.getFrame() &&
1391 i->value == m_editingPoint.value) { 1402 i->getValue() == m_editingPoint.getValue()) {
1392 #ifdef DEBUG_TIME_VALUE_LAYER 1403 #ifdef DEBUG_TIME_VALUE_LAYER
1393 cerr << "ignoring current editing point at " << i->frame << ", " << i->value << endl; 1404 cerr << "ignoring current editing point at " << i->getFrame() << ", " << i->getValue() << endl;
1394 #endif 1405 #endif
1395 continue; 1406 continue;
1396 } 1407 }
1397 if (((i->frame / resolution) * resolution) != frame) { 1408 if (((i->getFrame() / resolution) * resolution) != frame) {
1398 #ifdef DEBUG_TIME_VALUE_LAYER 1409 #ifdef DEBUG_TIME_VALUE_LAYER
1399 cerr << "ignoring out-of-range frame at " << i->frame << endl; 1410 cerr << "ignoring out-of-range frame at " << i->getFrame() << endl;
1400 #endif 1411 #endif
1401 continue; 1412 continue;
1402 } 1413 }
1403 #ifdef DEBUG_TIME_VALUE_LAYER 1414 #ifdef DEBUG_TIME_VALUE_LAYER
1404 cerr << "adjusting to new point at " << i->frame << ", " << i->value << endl; 1415 cerr << "adjusting to new point at " << i->getFrame() << ", " << i->getValue() << endl;
1405 #endif 1416 #endif
1406 m_editingPoint = *i; 1417 m_editingPoint = *i;
1407 m_originalPoint = m_editingPoint; 1418 m_originalPoint = m_editingPoint;
1408 m_editingCommand->deletePoint(m_editingPoint); 1419 m_editingCommand->remove(m_editingPoint);
1409 havePoint = true; 1420 havePoint = true;
1410 } 1421 }
1411 } 1422 }
1412 1423
1413 if (!havePoint) { 1424 if (!havePoint) {
1414 if (frame == m_editingPoint.frame) { 1425 if (frame == m_editingPoint.getFrame()) {
1415 m_editingCommand->deletePoint(m_editingPoint); 1426 m_editingCommand->remove(m_editingPoint);
1416 } 1427 }
1417 } 1428 }
1418 1429
1419 // m_editingCommand->deletePoint(m_editingPoint); 1430 m_editingPoint = m_editingPoint
1420 m_editingPoint.frame = frame; 1431 .withFrame(frame)
1421 m_editingPoint.value = float(value); 1432 .withValue(float(value));
1422 m_editingCommand->addPoint(m_editingPoint); 1433 m_editingCommand->add(m_editingPoint);
1423 } 1434 }
1424 1435
1425 void 1436 void
1426 TimeValueLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) 1437 TimeValueLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *)
1427 { 1438 {
1437 void 1448 void
1438 TimeValueLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) 1449 TimeValueLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e)
1439 { 1450 {
1440 if (!m_model) return; 1451 if (!m_model) return;
1441 1452
1442 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1453 EventVector points = getLocalPoints(v, e->x());
1443 if (points.empty()) return; 1454 if (points.empty()) return;
1444 1455
1445 m_editingPoint = *points.begin(); 1456 m_editingPoint = *points.begin();
1446 1457
1447 if (m_editingCommand) { 1458 if (m_editingCommand) {
1462 { 1473 {
1463 if (!m_model || !m_editing) return; 1474 if (!m_model || !m_editing) return;
1464 1475
1465 m_editing = false; 1476 m_editing = false;
1466 1477
1467 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1478 EventVector points = getLocalPoints(v, e->x());
1468 if (points.empty()) return; 1479 if (points.empty()) return;
1469 if (points.begin()->frame != m_editingPoint.frame || 1480 if (points.begin()->getFrame() != m_editingPoint.getFrame() ||
1470 points.begin()->value != m_editingPoint.value) return; 1481 points.begin()->getValue() != m_editingPoint.getValue()) return;
1471 1482
1472 m_editingCommand = new SparseTimeValueModel::EditCommand 1483 m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point"));
1473 (m_model, tr("Erase Point")); 1484 m_editingCommand->remove(m_editingPoint);
1474
1475 m_editingCommand->deletePoint(m_editingPoint);
1476
1477 finish(m_editingCommand); 1485 finish(m_editingCommand);
1478 m_editingCommand = nullptr; 1486 m_editingCommand = nullptr;
1479 m_editing = false; 1487 m_editing = false;
1480 } 1488 }
1481 1489
1486 cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 1494 cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
1487 #endif 1495 #endif
1488 1496
1489 if (!m_model) return; 1497 if (!m_model) return;
1490 1498
1491 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1499 EventVector points = getLocalPoints(v, e->x());
1492 if (points.empty()) return; 1500 if (points.empty()) return;
1493 1501
1494 m_editingPoint = *points.begin(); 1502 m_editingPoint = *points.begin();
1495 m_originalPoint = m_editingPoint; 1503 m_originalPoint = m_editingPoint;
1496 1504
1516 frame = frame / m_model->getResolution() * m_model->getResolution(); 1524 frame = frame / m_model->getResolution() * m_model->getResolution();
1517 1525
1518 double value = getValueForY(v, e->y()); 1526 double value = getValueForY(v, e->y());
1519 1527
1520 if (!m_editingCommand) { 1528 if (!m_editingCommand) {
1521 m_editingCommand = new SparseTimeValueModel::EditCommand(m_model, 1529 m_editingCommand = new ChangeEventsCommand(m_model, tr("Drag Point"));
1522 tr("Drag Point")); 1530 }
1523 } 1531
1524 1532 m_editingCommand->remove(m_editingPoint);
1525 m_editingCommand->deletePoint(m_editingPoint); 1533 m_editingPoint = m_editingPoint
1526 m_editingPoint.frame = frame; 1534 .withFrame(frame)
1527 m_editingPoint.value = float(value); 1535 .withValue(float(value));
1528 m_editingCommand->addPoint(m_editingPoint); 1536 m_editingCommand->add(m_editingPoint);
1529 } 1537 }
1530 1538
1531 void 1539 void
1532 TimeValueLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) 1540 TimeValueLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
1533 { 1541 {
1538 1546
1539 if (m_editingCommand) { 1547 if (m_editingCommand) {
1540 1548
1541 QString newName = m_editingCommand->getName(); 1549 QString newName = m_editingCommand->getName();
1542 1550
1543 if (m_editingPoint.frame != m_originalPoint.frame) { 1551 if (m_editingPoint.getFrame() != m_originalPoint.getFrame()) {
1544 if (m_editingPoint.value != m_originalPoint.value) { 1552 if (m_editingPoint.getValue() != m_originalPoint.getValue()) {
1545 newName = tr("Edit Point"); 1553 newName = tr("Edit Point");
1546 } else { 1554 } else {
1547 newName = tr("Relocate Point"); 1555 newName = tr("Relocate Point");
1548 } 1556 }
1549 } else { 1557 } else {
1561 bool 1569 bool
1562 TimeValueLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) 1570 TimeValueLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
1563 { 1571 {
1564 if (!m_model) return false; 1572 if (!m_model) return false;
1565 1573
1566 SparseTimeValueModel::PointList points = getLocalPoints(v, e->x()); 1574 EventVector points = getLocalPoints(v, e->x());
1567 if (points.empty()) return false; 1575 if (points.empty()) return false;
1568 1576
1569 SparseTimeValueModel::Point point = *points.begin(); 1577 Event point = *points.begin();
1570 1578
1571 ItemEditDialog *dialog = new ItemEditDialog 1579 ItemEditDialog *dialog = new ItemEditDialog
1572 (m_model->getSampleRate(), 1580 (m_model->getSampleRate(),
1573 ItemEditDialog::ShowTime | 1581 ItemEditDialog::ShowTime |
1574 ItemEditDialog::ShowValue | 1582 ItemEditDialog::ShowValue |
1575 ItemEditDialog::ShowText, 1583 ItemEditDialog::ShowText,
1576 getScaleUnits()); 1584 getScaleUnits());
1577 1585
1578 dialog->setFrameTime(point.frame); 1586 dialog->setFrameTime(point.getFrame());
1579 dialog->setValue(point.value); 1587 dialog->setValue(point.getValue());
1580 dialog->setText(point.label); 1588 dialog->setText(point.getLabel());
1581 1589
1582 if (dialog->exec() == QDialog::Accepted) { 1590 if (dialog->exec() == QDialog::Accepted) {
1583 1591
1584 SparseTimeValueModel::Point newPoint = point; 1592 Event newPoint = point
1585 newPoint.frame = dialog->getFrameTime(); 1593 .withFrame(dialog->getFrameTime())
1586 newPoint.value = dialog->getValue(); 1594 .withValue(dialog->getValue())
1587 newPoint.label = dialog->getText(); 1595 .withLabel(dialog->getText());
1588 1596
1589 SparseTimeValueModel::EditCommand *command = 1597 ChangeEventsCommand *command =
1590 new SparseTimeValueModel::EditCommand(m_model, tr("Edit Point")); 1598 new ChangeEventsCommand(m_model, tr("Edit Point"));
1591 command->deletePoint(point); 1599 command->remove(point);
1592 command->addPoint(newPoint); 1600 command->add(newPoint);
1593 finish(command); 1601 finish(command);
1594 } 1602 }
1595 1603
1596 delete dialog; 1604 delete dialog;
1597 return true; 1605 return true;
1600 void 1608 void
1601 TimeValueLayer::moveSelection(Selection s, sv_frame_t newStartFrame) 1609 TimeValueLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
1602 { 1610 {
1603 if (!m_model) return; 1611 if (!m_model) return;
1604 1612
1605 SparseTimeValueModel::EditCommand *command = 1613 ChangeEventsCommand *command =
1606 new SparseTimeValueModel::EditCommand(m_model, 1614 new ChangeEventsCommand(m_model, tr("Drag Selection"));
1607 tr("Drag Selection")); 1615
1608 1616 EventVector points =
1609 SparseTimeValueModel::PointList points = 1617 m_model->getEventsWithin(s.getStartFrame(), s.getDuration());
1610 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1618
1611 1619 for (Event p: points) {
1612 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1620
1613 i != points.end(); ++i) { 1621 Event newPoint = p.withFrame
1614 1622 (p.getFrame() + newStartFrame - s.getStartFrame());
1615 if (s.contains(i->frame)) { 1623 command->remove(p);
1616 SparseTimeValueModel::Point newPoint(*i); 1624 command->add(newPoint);
1617 newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
1618 command->deletePoint(*i);
1619 command->addPoint(newPoint);
1620 }
1621 } 1625 }
1622 1626
1623 finish(command); 1627 finish(command);
1624 } 1628 }
1625 1629
1626 void 1630 void
1627 TimeValueLayer::resizeSelection(Selection s, Selection newSize) 1631 TimeValueLayer::resizeSelection(Selection s, Selection newSize)
1628 { 1632 {
1633 if (!m_model || !s.getDuration()) return;
1634
1635 ChangeEventsCommand *command =
1636 new ChangeEventsCommand(m_model, tr("Resize Selection"));
1637
1638 EventVector points =
1639 m_model->getEventsWithin(s.getStartFrame(), s.getDuration());
1640
1641 double ratio = double(newSize.getDuration()) / double(s.getDuration());
1642 double oldStart = double(s.getStartFrame());
1643 double newStart = double(newSize.getStartFrame());
1644
1645 for (Event p: points) {
1646
1647 double newFrame = (double(p.getFrame()) - oldStart) * ratio + newStart;
1648
1649 Event newPoint = p
1650 .withFrame(lrint(newFrame));
1651 command->remove(p);
1652 command->add(newPoint);
1653 }
1654
1655 finish(command);
1656 }
1657
1658 void
1659 TimeValueLayer::deleteSelection(Selection s)
1660 {
1629 if (!m_model) return; 1661 if (!m_model) return;
1630 1662
1631 SparseTimeValueModel::EditCommand *command = 1663 ChangeEventsCommand *command =
1632 new SparseTimeValueModel::EditCommand(m_model, 1664 new ChangeEventsCommand(m_model, tr("Delete Selected Points"));
1633 tr("Resize Selection")); 1665
1634 1666 EventVector points =
1635 SparseTimeValueModel::PointList points = 1667 m_model->getEventsWithin(s.getStartFrame(), s.getDuration());
1636 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1668
1637 1669 for (Event p: points) {
1638 double ratio = 1670 command->remove(p);
1639 double(newSize.getEndFrame() - newSize.getStartFrame()) /
1640 double(s.getEndFrame() - s.getStartFrame());
1641
1642 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1643 i != points.end(); ++i) {
1644
1645 if (s.contains(i->frame)) {
1646
1647 double target = double(i->frame);
1648 target = double(newSize.getStartFrame()) +
1649 target - double(s.getStartFrame()) * ratio;
1650
1651 SparseTimeValueModel::Point newPoint(*i);
1652 newPoint.frame = lrint(target);
1653 command->deletePoint(*i);
1654 command->addPoint(newPoint);
1655 }
1656 }
1657
1658 finish(command);
1659 }
1660
1661 void
1662 TimeValueLayer::deleteSelection(Selection s)
1663 {
1664 if (!m_model) return;
1665
1666 SparseTimeValueModel::EditCommand *command =
1667 new SparseTimeValueModel::EditCommand(m_model,
1668 tr("Delete Selected Points"));
1669
1670 SparseTimeValueModel::PointList points =
1671 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1672
1673 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1674 i != points.end(); ++i) {
1675
1676 if (s.contains(i->frame)) {
1677 command->deletePoint(*i);
1678 }
1679 } 1671 }
1680 1672
1681 finish(command); 1673 finish(command);
1682 } 1674 }
1683 1675
1684 void 1676 void
1685 TimeValueLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) 1677 TimeValueLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
1686 { 1678 {
1687 if (!m_model) return; 1679 if (!m_model) return;
1688 1680
1689 SparseTimeValueModel::PointList points = 1681 EventVector points =
1690 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 1682 m_model->getEventsWithin(s.getStartFrame(), s.getDuration());
1691 1683
1692 for (SparseTimeValueModel::PointList::iterator i = points.begin(); 1684 for (Event p: points) {
1693 i != points.end(); ++i) { 1685 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame())));
1694 if (s.contains(i->frame)) {
1695 Event point(i->frame, i->value, i->label);
1696 to.addPoint(point.withReferenceFrame(alignToReference(v, i->frame)));
1697 }
1698 } 1686 }
1699 } 1687 }
1700 1688
1701 bool 1689 bool
1702 TimeValueLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, 1690 TimeValueLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */,
1723 if (button == QMessageBox::Yes) { 1711 if (button == QMessageBox::Yes) {
1724 realign = true; 1712 realign = true;
1725 } 1713 }
1726 } 1714 }
1727 1715
1728 SparseTimeValueModel::EditCommand *command = 1716 ChangeEventsCommand *command =
1729 new SparseTimeValueModel::EditCommand(m_model, tr("Paste")); 1717 new ChangeEventsCommand(m_model, tr("Paste"));
1730 1718
1731 enum ValueAvailability { 1719 enum ValueAvailability {
1732 UnknownAvailability, 1720 UnknownAvailability,
1733 NoValues, 1721 NoValues,
1734 SomeValues, 1722 SomeValues,
1831 1819
1832 prevSelection = selection; 1820 prevSelection = selection;
1833 } 1821 }
1834 } 1822 }
1835 1823
1836 SparseTimeValueModel::Point prevPoint(0); 1824 Event prevPoint;
1837 1825
1838 for (EventVector::const_iterator i = points.begin(); 1826 for (EventVector::const_iterator i = points.begin();
1839 i != points.end(); ++i) { 1827 i != points.end(); ++i) {
1840 1828
1841 sv_frame_t frame = 0; 1829 sv_frame_t frame = 0;
1852 } else { 1840 } else {
1853 frame = i->getFrame(); 1841 frame = i->getFrame();
1854 } 1842 }
1855 } 1843 }
1856 1844
1857 SparseTimeValueModel::Point newPoint(frame); 1845 Event newPoint = *i;
1858 1846 if (!i->hasLabel() && i->hasValue()) {
1859 if (i->hasLabel()) { 1847 newPoint = newPoint.withLabel(QString("%1").arg(i->getValue()));
1860 newPoint.label = i->getLabel();
1861 } else if (i->hasValue()) {
1862 newPoint.label = QString("%1").arg(i->getValue());
1863 } 1848 }
1864 1849
1865 bool usePrev = false; 1850 bool usePrev = false;
1866 SparseTimeValueModel::Point formerPrevPoint = prevPoint; 1851 Event formerPrevPoint = prevPoint;
1867 1852
1868 if (i->hasValue()) { 1853 if (!i->hasValue()) {
1869 newPoint.value = i->getValue(); 1854 #ifdef DEBUG_TIME_VALUE_LAYER
1870 } else { 1855 cerr << "Setting value on point at " << newPoint.getFrame() << " from labeller";
1871 #ifdef DEBUG_TIME_VALUE_LAYER
1872 cerr << "Setting value on point at " << newPoint.frame << " from labeller";
1873 if (i == points.begin()) { 1856 if (i == points.begin()) {
1874 cerr << ", no prev point" << endl; 1857 cerr << ", no prev point" << endl;
1875 } else { 1858 } else {
1876 cerr << ", prev point is at " << prevPoint.frame << endl; 1859 cerr << ", prev point is at " << prevPoint.getFrame() << endl;
1877 } 1860 }
1878 #endif 1861 #endif
1879 labeller.setValue<SparseTimeValueModel::Point> 1862
1863 Labeller::Revaluing valuing =
1864 labeller.revalue
1880 (newPoint, (i == points.begin()) ? nullptr : &prevPoint); 1865 (newPoint, (i == points.begin()) ? nullptr : &prevPoint);
1881 #ifdef DEBUG_TIME_VALUE_LAYER 1866
1882 cerr << "New point value = " << newPoint.value << endl; 1867 #ifdef DEBUG_TIME_VALUE_LAYER
1883 #endif 1868 cerr << "New point value = " << newPoint.getValue() << endl;
1884 if (labeller.actingOnPrevPoint() && i != points.begin()) { 1869 #endif
1870 if (valuing.first == Labeller::AppliesToPreviousEvent) {
1885 usePrev = true; 1871 usePrev = true;
1872 prevPoint = valuing.second;
1873 } else {
1874 newPoint = valuing.second;
1886 } 1875 }
1887 } 1876 }
1888 1877
1889 if (usePrev) { 1878 if (usePrev) {
1890 command->deletePoint(formerPrevPoint); 1879 command->remove(formerPrevPoint);
1891 command->addPoint(prevPoint); 1880 command->add(prevPoint);
1892 } 1881 }
1893 1882
1894 prevPoint = newPoint; 1883 prevPoint = newPoint;
1895 command->addPoint(newPoint); 1884 command->add(newPoint);
1896 } 1885 }
1897 1886
1898 finish(command); 1887 finish(command);
1899 return true; 1888 return true;
1900 } 1889 }