18 #include "data/model/Model.h" 19 #include "base/RealTime.h" 20 #include "base/Profiler.h" 21 #include "base/LogRange.h" 22 #include "base/RangeMapper.h" 26 #include "data/model/SparseTimeValueModel.h" 27 #include "data/model/Labeller.h" 41 #include <QPainterPath> 42 #include <QMouseEvent> 44 #include <QTextStream> 45 #include <QMessageBox> 46 #include <QInputDialog> 57 m_originalPoint(0, 0.0, tr(
"New Point")),
58 m_editingPoint(0, 0.0, tr(
"New Point")),
61 m_plotStyle(PlotConnectedPoints),
62 m_verticalScale(AutoAlignScale),
63 m_drawSegmentDivisions(true),
89 #ifdef DEBUG_TIME_VALUE_LAYER 90 cerr <<
"TimeValueLayer::setModel(" << model <<
")" << endl;
100 list.push_back(
"Plot Type");
101 list.push_back(
"Vertical Scale");
102 list.push_back(
"Scale Units");
103 list.push_back(
"Draw Segment Division Lines");
104 list.push_back(
"Show Derivative");
111 if (name ==
"Plot Type")
return tr(
"Plot Type");
112 if (name ==
"Vertical Scale")
return tr(
"Vertical Scale");
113 if (name ==
"Scale Units")
return tr(
"Scale Units");
114 if (name ==
"Draw Segment Division Lines")
return tr(
"Draw Segment Division Lines");
115 if (name ==
"Show Derivative")
return tr(
"Show Derivative");
122 if (name ==
"Draw Segment Division Lines")
return "lines";
123 if (name ==
"Show Derivative")
return "derivative";
130 if (name ==
"Plot Type")
return ValueProperty;
131 if (name ==
"Vertical Scale")
return ValueProperty;
132 if (name ==
"Scale Units")
return UnitsProperty;
134 if (name ==
"Draw Segment Division Lines")
return ToggleProperty;
135 if (name ==
"Show Derivative")
return ToggleProperty;
142 if (name ==
"Vertical Scale" || name ==
"Scale Units") {
145 if (name ==
"Plot Type" || name ==
"Draw Segment Division Lines" ||
146 name ==
"Show Derivative") {
147 return tr(
"Plot Type");
161 int *min,
int *max,
int *deflt)
const 169 if (deflt) *deflt = 0;
173 }
else if (name ==
"Plot Type") {
181 }
else if (name ==
"Vertical Scale") {
189 }
else if (name ==
"Scale Units") {
191 if (deflt) *deflt = 0;
193 val = UnitDatabase::getInstance()->getUnitId
197 }
else if (name ==
"Draw Segment Division Lines") {
201 if (deflt) *deflt = 1;
204 }
else if (name ==
"Show Derivative") {
208 if (deflt) *deflt = 0;
225 }
else if (name ==
"Plot Type") {
228 case 0:
return tr(
"Points");
229 case 1:
return tr(
"Stems");
230 case 2:
return tr(
"Connected Points");
231 case 3:
return tr(
"Lines");
232 case 4:
return tr(
"Curve");
233 case 5:
return tr(
"Segmentation");
234 case 6:
return tr(
"Discrete Curves");
236 }
else if (name ==
"Vertical Scale") {
239 case 0:
return tr(
"Auto-Align");
240 case 1:
return tr(
"Linear");
241 case 2:
return tr(
"Log");
242 case 3:
return tr(
"+/-1");
253 }
else if (name ==
"Plot Type") {
255 }
else if (name ==
"Vertical Scale") {
257 }
else if (name ==
"Scale Units") {
260 (UnitDatabase::getInstance()->getUnitById(value));
263 }
else if (name ==
"Draw Segment Division Lines") {
265 }
else if (name ==
"Show Derivative") {
287 if (colourTypeChanged) {
333 bool &logarithmic, QString &unit)
const 337 min =
m_model->getValueMinimum();
338 max =
m_model->getValueMaximum();
345 max = std::max(fabsf(min), fabsf(max));
349 #ifdef DEBUG_TIME_VALUE_LAYER 350 cerr <<
"TimeValueLayer::getValueExtents: min = " << min <<
", max = " << max << endl;
359 float margin = (max - min) / 10.0;
364 #ifdef DEBUG_TIME_VALUE_LAYER 365 cerr <<
"TimeValueLayer::getValueExtents: min = " << min <<
", max = " << max <<
" (after adjustment)" << endl;
387 max = std::max(fabsf(min), fabsf(max));
391 #ifdef DEBUG_TIME_VALUE_LAYER 392 cerr <<
"TimeValueLayer::getDisplayExtents: min = " << min <<
", max = " << max << endl;
414 #ifdef DEBUG_TIME_VALUE_LAYER 415 cerr <<
"TimeValueLayer::setDisplayExtents: min = " << min <<
", max = " << max << endl;
439 if (!mapper)
return 0;
444 int nr = mapper->getPositionForValue(dmax - dmin);
446 #ifdef DEBUG_TIME_VALUE_LAYER 447 cerr <<
"TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin <<
", dmax = " << dmax <<
", nr = " << nr << endl;
472 float newdist = mapper->getValueForPosition(100 - step);
474 float newmin, newmax;
480 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2;
481 newmin = newmax - newdist;
483 #ifdef DEBUG_TIME_VALUE_LAYER 484 cerr <<
"newmin = " << newmin <<
", newmax = " << newmax << endl;
488 float dmid = (dmax + dmin) / 2;
489 newmin = dmid - newdist / 2;
490 newmax = dmid + newdist / 2;
494 newmax += (min - newmin);
501 #ifdef DEBUG_TIME_VALUE_LAYER 502 cerr <<
"TimeValueLayer::setVerticalZoomStep: " << step <<
": " << newmin <<
" -> " << newmax <<
" (range " << newdist <<
")" << endl;
520 if (min == max)
return 0;
523 mapper =
new LogRangeMapper(0, 100, min, max, unit);
525 mapper =
new LinearRangeMapper(0, 100, min, max, unit);
531 SparseTimeValueModel::PointList
534 if (!
m_model)
return SparseTimeValueModel::PointList();
538 SparseTimeValueModel::PointList onPoints =
541 if (!onPoints.empty()) {
545 SparseTimeValueModel::PointList prevPoints =
546 m_model->getPreviousPoints(frame);
547 SparseTimeValueModel::PointList nextPoints =
550 SparseTimeValueModel::PointList usePoints = prevPoints;
552 if (prevPoints.empty()) {
553 usePoints = nextPoints;
554 }
else if (nextPoints.empty()) {
556 }
else if (
long(prevPoints.begin()->frame) < v->
getStartFrame() &&
558 usePoints = nextPoints;
559 }
else if (nextPoints.begin()->frame - frame <
560 frame - prevPoints.begin()->frame) {
561 usePoints = nextPoints;
564 if (!usePoints.empty()) {
567 if ((px > x && px - x > fuzz) ||
568 (px < x && x - px > fuzz + 3)) {
580 SparseTimeValueModel::PointList points =
m_model->getPreviousPoints(frame);
581 for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
582 i != points.end(); ++i) {
583 if (i->label !=
"")
return i->label;
597 if (points.empty()) {
599 return tr(
"In progress");
601 return tr(
"No local points");
605 long useFrame = points.begin()->frame;
607 RealTime rt = RealTime::frame2RealTime(useFrame,
m_model->getSampleRate());
611 if (unit !=
"") unit =
" " + unit;
613 if (points.begin()->label ==
"") {
614 text = QString(tr(
"Time:\t%1\nValue:\t%2%3\nNo label"))
615 .arg(rt.toText(
true).c_str())
616 .arg(points.begin()->value)
619 text = QString(tr(
"Time:\t%1\nValue:\t%2%3\nLabel:\t%4"))
620 .arg(rt.toText(
true).c_str())
621 .arg(points.begin()->value)
623 .arg(points.begin()->label);
640 resolution =
m_model->getResolution();
641 SparseTimeValueModel::PointList points;
646 if (points.empty())
return false;
647 frame = points.begin()->frame;
651 points =
m_model->getPoints(frame, frame);
655 for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
656 i != points.end(); ++i) {
660 if (i->frame > frame) {
668 if (i->frame <= frame) {
677 SparseTimeValueModel::PointList::const_iterator j = i;
680 if (j == points.end()) {
686 }
else if (j->frame >= frame) {
688 if (j->frame - frame < frame - i->frame) {
712 resolution =
m_model->getResolution();
714 const SparseTimeValueModel::PointList &points =
m_model->getPoints();
715 SparseTimeValueModel::PointList close =
m_model->getPoints(frame, frame);
717 SparseTimeValueModel::PointList::const_iterator i;
719 int matchframe = frame;
720 float matchvalue = 0.f;
722 for (i = close.begin(); i != close.end(); ++i) {
723 if (i->frame > frame)
break;
724 matchvalue = i->value;
725 matchframe = i->frame;
730 bool distant =
false;
731 float epsilon = 0.0001;
743 while (i != points.end()) {
746 if (i == close.end()) {
755 if (i->frame > matchframe &&
756 fabsf(i->value - matchvalue) < epsilon) {
764 if (i->frame < matchframe) {
765 if (fabsf(i->value - matchvalue) < epsilon) {
769 }
else if (found || distant) {
794 min =
m_model->getValueMinimum();
795 max =
m_model->getValueMaximum();
797 LogRange::mapRange(min, max);
810 LogRange::mapRange(min, max);
815 #ifdef DEBUG_TIME_VALUE_LAYER 816 cerr <<
"TimeValueLayer::getScaleExtents: min = " << min <<
", max = " << max << endl;
823 float min = 0.0, max = 0.0;
824 bool logarithmic =
false;
829 #ifdef DEBUG_TIME_VALUE_LAYER 830 cerr <<
"getYForValue(" << val <<
"): min " << min <<
", max " 831 << max <<
", log " << logarithmic << endl;
835 val = LogRange::map(val);
838 return int(h - ((val - min) * h) / (max - min));
844 float min = 0.0, max = 0.0;
845 bool logarithmic =
false;
850 float val = min + (float(h - y) * float(max - min)) / h;
853 val = LogRange::map(val);
874 if (min > max) std::swap(min, max);
875 if (max == min) max = min + 1;
878 val = LogRange::map(val);
881 #ifdef DEBUG_TIME_VALUE_LAYER 882 cerr <<
"TimeValueLayer::getColourForValue: min " << min <<
", max " 883 << max <<
", log " << log <<
", value " << val << endl;
887 return QColor(solid.red(), solid.green(), solid.blue(), 120);
895 (QString(darkbg ?
"Bright Green" :
"Green"));
903 int sampleRate =
m_model->getSampleRate();
904 if (!sampleRate)
return;
906 paint.setRenderHint(QPainter::Antialiasing,
false);
910 int x0 = rect.left(), x1 = rect.right();
915 SparseTimeValueModel::PointList points(
m_model->getPoints
917 if (points.empty())
return;
922 brushColour.setAlpha(80);
923 paint.setBrush(brushColour);
925 #ifdef DEBUG_TIME_VALUE_LAYER 926 cerr <<
"TimeValueLayer::paint: resolution is " 927 <<
m_model->getResolution() <<
" frames" << endl;
930 float min =
m_model->getValueMinimum();
931 float max =
m_model->getValueMaximum();
932 if (max == min) max = min + 1.0;
934 int origin = int(nearbyint(v->height() -
935 (-min * v->height()) / (max - min)));
938 long illuminateFrame = -1;
941 SparseTimeValueModel::PointList localPoints =
943 #ifdef DEBUG_TIME_VALUE_LAYER 944 cerr <<
"TimeValueLayer: " << localPoints.size() <<
" local points" << endl;
946 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
969 if (originY > 0 && originY < v->height()) {
972 paint.drawLine(x0, originY, x1, originY);
979 for (SparseTimeValueModel::PointList::const_iterator i = points.begin();
980 i != points.end(); ++i) {
984 const SparseTimeValueModel::Point &p(*i);
986 float value = p.value;
988 SparseTimeValueModel::PointList::const_iterator j = i;
1002 gap = (p.frame > prevFrame &&
1003 (p.frame - prevFrame >=
m_model->getResolution() * 2));
1007 textY = y -
paint.fontMetrics().height()
1008 +
paint.fontMetrics().ascent() - 1;
1009 if (textY <
paint.fontMetrics().ascent() + 1) {
1010 textY =
paint.fontMetrics().ascent() + 1;
1014 bool haveNext =
false;
1020 SparseTimeValueModel::PointList::const_iterator j = i;
1023 if (j != points.end()) {
1024 const SparseTimeValueModel::Point &q(*j);
1038 paint.setBrush(Qt::NoBrush);
1045 paint.setBrush(Qt::NoBrush);
1048 paint.setBrush(brushColour);
1061 if (y < origin - 1) {
1062 paint.drawLine(x + w/2, y + 1, x + w/2, origin);
1063 }
else if (y > origin + 1) {
1064 paint.drawLine(x + w/2, origin, x + w/2, y - 1);
1068 bool illuminate =
false;
1070 if (illuminateFrame == p.frame) {
1093 paint.drawRect(x, y - 1, w, 2);
1110 paint.setPen(brushColour);
1111 paint.drawLine(x + w, y, nx, ny);
1116 if (pointCount == 0) {
1117 path.moveTo(x + w/2, y);
1121 path.lineTo(nx + w/2, ny);
1125 float x0 = x + float(w)/2;
1126 float x1 = nx + float(w)/2;
1134 (nf - p.frame >=
m_model->getResolution() * 2);
1141 if (pointCount == 0 || gap) {
1142 path.moveTo((x0 + x1) / 2, (y0 + y1) / 2);
1146 path.cubicTo(x0, y0,
1148 (x0 + x1) / 2, (y0 + y1) / 2);
1154 path.lineTo((x0 + x1) / 2, (y0 + y1) / 2);
1162 #ifdef DEBUG_TIME_VALUE_LAYER 1163 cerr <<
"drawing rect" << endl;
1166 if (nx <= x)
continue;
1173 x >= v->width() - 1) {
1174 paint.setPen(Qt::NoPen);
1178 paint.drawRect(x, -1, nx - x, v->height() + 1);
1183 QString label = p.label;
1184 bool italic =
false;
1191 snprintf(lc, 20,
"%.3g", p.value);
1198 bool haveRoom = (nx > x + 20);
1199 haveRoom = (haveRoom &&
1200 (nx > x + 6 +
paint.fontMetrics().width(label)));
1203 (pointCount == 0 || !italic))) {
1212 prevFrame = p.frame;
1217 paint.setRenderHint(QPainter::Antialiasing,
true);
1218 paint.drawPath(path);
1220 && !path.isEmpty()) {
1221 paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->width());
1222 paint.drawPath(path);
1228 paint.setRenderHint(QPainter::Antialiasing,
false);
1261 int h = v->height();
1268 LogRange::mapRange(min, max);
1286 (v,
paint, QRect(w - 10, 0, 10, h),
1287 LogRange::unmap(min),
1288 LogRange::unmap(max));
1289 paint.drawLine(w, 0, w, h);
1296 5 +
paint.fontMetrics().ascent(),
1298 paint.fontMetrics(),
1306 #ifdef DEBUG_TIME_VALUE_LAYER 1307 cerr <<
"TimeValueLayer::drawStart(" << e->x() <<
"," << e->y() <<
")" << endl;
1313 long resolution =
m_model->getResolution();
1314 if (frame < 0) frame = 0;
1315 frame = (frame / resolution) * resolution;
1319 bool havePoint =
false;
1321 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1322 if (!points.empty()) {
1323 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1324 i != points.end(); ++i) {
1325 if (((i->frame / resolution) * resolution) != frame) {
1326 #ifdef DEBUG_TIME_VALUE_LAYER 1327 cerr <<
"ignoring out-of-range frame at " << i->frame << endl;
1338 (frame, value, tr(
"New Point"));
1356 #ifdef DEBUG_TIME_VALUE_LAYER 1357 cerr <<
"TimeValueLayer::drawDrag(" << e->x() <<
"," << e->y() <<
")" << endl;
1363 long resolution =
m_model->getResolution();
1364 if (frame < 0) frame = 0;
1365 frame = (frame / resolution) * resolution;
1369 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1371 #ifdef DEBUG_TIME_VALUE_LAYER 1372 cerr << points.size() <<
" points" << endl;
1375 bool havePoint =
false;
1377 if (!points.empty()) {
1378 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1379 i != points.end(); ++i) {
1382 #ifdef DEBUG_TIME_VALUE_LAYER 1383 cerr <<
"ignoring current editing point at " << i->frame <<
", " << i->value << endl;
1387 if (((i->frame / resolution) * resolution) != frame) {
1388 #ifdef DEBUG_TIME_VALUE_LAYER 1389 cerr <<
"ignoring out-of-range frame at " << i->frame << endl;
1393 #ifdef DEBUG_TIME_VALUE_LAYER 1394 cerr <<
"adjusting to new point at " << i->frame <<
", " << i->value << endl;
1418 #ifdef DEBUG_TIME_VALUE_LAYER 1419 cerr <<
"TimeValueLayer::drawEnd" << endl;
1432 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1433 if (points.empty())
return;
1457 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1458 if (points.empty())
return;
1475 #ifdef DEBUG_TIME_VALUE_LAYER 1476 cerr <<
"TimeValueLayer::editStart(" << e->x() <<
"," << e->y() <<
")" << endl;
1481 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1482 if (points.empty())
return;
1498 #ifdef DEBUG_TIME_VALUE_LAYER 1499 cerr <<
"TimeValueLayer::editDrag(" << e->x() <<
"," << e->y() <<
")" << endl;
1505 if (frame < 0) frame = 0;
1506 frame = frame /
m_model->getResolution() *
m_model->getResolution();
1524 #ifdef DEBUG_TIME_VALUE_LAYER 1525 cerr <<
"TimeValueLayer::editEnd" << endl;
1535 newName = tr(
"Edit Point");
1537 newName = tr(
"Relocate Point");
1540 newName = tr(
"Change Point Value");
1556 SparseTimeValueModel::PointList points =
getLocalPoints(v, e->x());
1557 if (points.empty())
return false;
1559 SparseTimeValueModel::Point point = *points.begin();
1572 if (dialog->exec() == QDialog::Accepted) {
1574 SparseTimeValueModel::Point newPoint = point;
1576 newPoint.value = dialog->
getValue();
1577 newPoint.label = dialog->
getText();
1579 SparseTimeValueModel::EditCommand *command =
1580 new SparseTimeValueModel::EditCommand(
m_model, tr(
"Edit Point"));
1581 command->deletePoint(point);
1582 command->addPoint(newPoint);
1595 SparseTimeValueModel::EditCommand *command =
1596 new SparseTimeValueModel::EditCommand(
m_model,
1597 tr(
"Drag Selection"));
1599 SparseTimeValueModel::PointList points =
1600 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1602 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1603 i != points.end(); ++i) {
1605 if (s.contains(i->frame)) {
1606 SparseTimeValueModel::Point newPoint(*i);
1607 newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
1608 command->deletePoint(*i);
1609 command->addPoint(newPoint);
1621 SparseTimeValueModel::EditCommand *command =
1622 new SparseTimeValueModel::EditCommand(
m_model,
1623 tr(
"Resize Selection"));
1625 SparseTimeValueModel::PointList points =
1626 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1629 double(newSize.getEndFrame() - newSize.getStartFrame()) /
1630 double(s.getEndFrame() - s.getStartFrame());
1632 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1633 i != points.end(); ++i) {
1635 if (s.contains(i->frame)) {
1637 double target = i->frame;
1638 target = newSize.getStartFrame() +
1639 double(target - s.getStartFrame()) * ratio;
1641 SparseTimeValueModel::Point newPoint(*i);
1642 newPoint.frame = lrint(target);
1643 command->deletePoint(*i);
1644 command->addPoint(newPoint);
1656 SparseTimeValueModel::EditCommand *command =
1657 new SparseTimeValueModel::EditCommand(
m_model,
1658 tr(
"Delete Selected Points"));
1660 SparseTimeValueModel::PointList points =
1661 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1663 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1664 i != points.end(); ++i) {
1666 if (s.contains(i->frame)) {
1667 command->deletePoint(*i);
1679 SparseTimeValueModel::PointList points =
1680 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
1682 for (SparseTimeValueModel::PointList::iterator i = points.begin();
1683 i != points.end(); ++i) {
1684 if (s.contains(i->frame)) {
1685 Clipboard::Point point(i->frame, i->value, i->label);
1698 const Clipboard::PointList &points = from.getPoints();
1700 bool realign =
false;
1704 QMessageBox::StandardButton button =
1705 QMessageBox::question(v, tr(
"Re-align pasted items?"),
1706 tr(
"The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"),
1707 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
1710 if (button == QMessageBox::Cancel) {
1714 if (button == QMessageBox::Yes) {
1719 SparseTimeValueModel::EditCommand *command =
1720 new SparseTimeValueModel::EditCommand(
m_model, tr(
"Paste"));
1722 enum ValueAvailability {
1723 UnknownAvailability,
1729 Labeller::ValueType generation = Labeller::ValueNone;
1731 bool haveUsableLabels =
false;
1733 labeller.setSampleRate(
m_model->getSampleRate());
1737 ValueAvailability availability = UnknownAvailability;
1739 for (Clipboard::PointList::const_iterator i = points.begin();
1740 i != points.end(); ++i) {
1742 if (!i->haveFrame())
continue;
1744 if (availability == UnknownAvailability) {
1745 if (i->haveValue()) availability = AllValues;
1746 else availability = NoValues;
1750 if (i->haveValue()) {
1751 if (availability == NoValues) {
1752 availability = SomeValues;
1755 if (availability == AllValues) {
1756 availability = SomeValues;
1760 if (!haveUsableLabels) {
1761 if (i->haveLabel()) {
1762 if (i->getLabel().contains(QRegExp(
"[0-9]"))) {
1763 haveUsableLabels =
true;
1768 if (availability == SomeValues && haveUsableLabels)
break;
1771 if (availability == NoValues || availability == SomeValues) {
1774 if (availability == NoValues) {
1775 text = tr(
"The items you are pasting do not have values.\nWhat values do you want to use for these items?");
1777 text = tr(
"Some of the items you are pasting do not have values.\nWhat values do you want to use for these items?");
1780 Labeller::TypeNameMap names = labeller.getTypeNames();
1782 QStringList options;
1783 std::vector<Labeller::ValueType> genopts;
1785 for (Labeller::TypeNameMap::const_iterator i = names.begin();
1786 i != names.end(); ++i) {
1787 if (i->first == Labeller::ValueNone) options << tr(
"Zero for all items");
1788 else options << i->second;
1789 genopts.push_back(i->first);
1792 static int prevSelection = 0;
1796 (0, tr(
"Choose value calculation"),
1797 text, options, prevSelection, &ok);
1804 generation = Labeller::ValueNone;
1806 for (QStringList::const_iterator i = options.begin();
1807 i != options.end(); ++i) {
1808 if (selected == *i) {
1809 generation = genopts[selection];
1815 labeller.setType(generation);
1817 if (generation == Labeller::ValueFromCyclicalCounter ||
1818 generation == Labeller::ValueFromTwoLevelCounter) {
1819 int cycleSize = QInputDialog::getInt
1820 (0, tr(
"Select cycle size"),
1821 tr(
"Cycle size:"), 4, 2, 16, 1);
1822 labeller.setCounterCycleSize(cycleSize);
1825 prevSelection = selection;
1829 SparseTimeValueModel::Point prevPoint(0);
1831 for (Clipboard::PointList::const_iterator i = points.begin();
1832 i != points.end(); ++i) {
1834 if (!i->haveFrame())
continue;
1840 frame = i->getFrame();
1844 if (i->haveReferenceFrame()) {
1845 frame = i->getReferenceFrame();
1848 frame = i->getFrame();
1852 SparseTimeValueModel::Point newPoint(frame);
1854 if (i->haveLabel()) {
1855 newPoint.label = i->getLabel();
1856 }
else if (i->haveValue()) {
1857 newPoint.label = QString(
"%1").arg(i->getValue());
1860 bool usePrev =
false;
1861 SparseTimeValueModel::Point formerPrevPoint = prevPoint;
1863 if (i->haveValue()) {
1864 newPoint.value = i->getValue();
1866 #ifdef DEBUG_TIME_VALUE_LAYER 1867 cerr <<
"Setting value on point at " << newPoint.frame <<
" from labeller";
1868 if (i == points.begin()) {
1869 cerr <<
", no prev point" << endl;
1871 cerr <<
", prev point is at " << prevPoint.frame << endl;
1874 labeller.setValue<SparseTimeValueModel::Point>
1875 (newPoint, (i == points.begin()) ? 0 : &prevPoint);
1876 #ifdef DEBUG_TIME_VALUE_LAYER 1877 cerr <<
"New point value = " << newPoint.value << endl;
1879 if (labeller.actingOnPrevPoint() && i != points.begin()) {
1885 command->deletePoint(formerPrevPoint);
1886 command->addPoint(prevPoint);
1889 prevPoint = newPoint;
1890 command->addPoint(newPoint);
1899 QString indent, QString extraAttributes)
const 1903 QString(
" colourMap=\"%1\" plotStyle=\"%2\" verticalScale=\"%3\" scaleMinimum=\"%4\" scaleMaximum=\"%5\" drawDivisions=\"%6\" derivative=\"%7\" ")
1920 int cmap = attributes.value(
"colourMap").toInt(&ok);
1924 attributes.value(
"plotStyle").toInt(&ok);
1928 attributes.value(
"verticalScale").toInt(&ok);
1931 bool draw = (attributes.value(
"drawDivisions").trimmed() ==
"true");
1934 bool derivative = (attributes.value(
"derivative").trimmed() ==
"true");
1937 float min = attributes.value(
"scaleMinimum").toFloat(&ok);
1938 float max = attributes.value(
"scaleMaximum").toFloat(&alsoOk);
1939 #ifdef DEBUG_TIME_VALUE_LAYER 1940 cerr <<
"from properties: min = " << min <<
", max = " << max << endl;
void paintPianoVertical(View *v, QPainter &paint, QRect rect, float minf, float maxf)
int getFrameForX(int x) const
Return the closest frame to the given pixel x-coordinate.
void setModel(SparseTimeValueModel *model)
virtual void copy(View *v, Selection s, Clipboard &to)
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
void setFrameTime(int frame)
virtual void setProperty(const PropertyName &, int value)
virtual bool isLayerScrollable(const View *v) const
This should return true if the layer can safely be scrolled automatically by a given view (simply cop...
SparseTimeValueModel * m_model
void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
virtual bool snapToFeatureFrame(View *, int &, int &resolution, SnapType) const
Adjust the given frame to snap to the nearest feature, if possible.
void connectSignals(const Model *)
void getScaleExtents(View *, float &min, float &max, bool &log) const
virtual bool snapToSimilarFeature(View *, int &, int &resolution, SnapType) const
Adjust the given frame to snap to the next feature that has "effectively" the same value as the featu...
virtual bool getValueExtents(QString unit, float &min, float &max, bool &log) const
static QString abbreviate(QString text, int maxLength, Policy policy=ElideEnd, bool fuzzy=true, QString ellipsis="")
Abbreviate the given text to the given maximum length (including ellipsis), using the given abbreviat...
virtual int getYForValue(View *, float value) const
VerticalScaleLayer and ColourScaleLayer methods.
virtual bool shouldShowFeatureLabels() const
virtual bool getValueExtents(float &min, float &max, bool &logarithmic, QString &unit) const
Return the minimum and maximum values for the y axis of the model in this layer, as well as whether t...
virtual void drawDrag(View *v, QMouseEvent *)
void setPlotStyle(PlotStyle style)
virtual QString getScaleUnits() const
virtual void eraseStart(View *v, QMouseEvent *)
void paintVertical(View *v, const ColourScaleLayer *layer, QPainter &paint, int x0, float minf, float maxf)
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
virtual RangeMapper * getNewVerticalZoomRangeMapper() const
Create and return a range mapper for vertical zoom step values.
virtual float getValueForY(View *, int y) const
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
virtual bool snapToFeatureFrame(View *v, int &frame, int &resolution, SnapType snap) const
Adjust the given frame to snap to the nearest feature, if possible.
virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const
virtual void deleteSelection(Selection s)
virtual QString getPropertyLabel(const PropertyName &) const
static int getColourMapCount()
void paintVertical(View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0, float minlog, float maxlog)
SparseTimeValueModel::Point m_editingPoint
virtual int getTextLabelHeight(const Layer *layer, QPainter &) const
VerticalScale m_verticalScale
virtual void setVerticalZoomStep(int)
Set the vertical zoom step.
virtual QColor getForegroundQColor(View *v) const
void layerParameterRangesChanged()
virtual QColor getBaseQColor() const
int getWidth(View *v, QPainter &paint)
void setText(QString text)
virtual int getVerticalScaleWidth(View *v, bool, QPainter &) const
virtual QColor getColourForValue(View *v, float value) const
std::vector< QColor > getPartialShades(View *v) const
int getColourIndex(QString name) const
int getWidth(View *v, QPainter &paint)
virtual QString getPropertyIconName(const PropertyName &) const
virtual void editDrag(View *v, QMouseEvent *)
virtual QString getPropertyLabel(const PropertyName &) const
virtual bool paste(View *v, const Clipboard &from, int frameOffset, bool interactive)
Paste from the given clipboard onto the layer at the given frame offset.
int getStartFrame() const
Retrieve the first visible sample frame on the widget.
virtual PropertyType getPropertyType(const PropertyName &) const
void paintVertical(View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0, float minf, float maxf)
void layerParametersChanged()
virtual QString getPropertyGroupName(const PropertyName &) const
virtual void paint(View *v, QPainter &paint, QRect rect) const
Paint the given rectangle of this layer onto the given view using the given painter,...
virtual void eraseEnd(View *v, QMouseEvent *)
int getWidth(View *v, QPainter &paint)
virtual void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
int getEndFrame() const
Retrieve the last visible sample frame on the widget.
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
A class for mapping intensity values onto various colour maps.
virtual int getCurrentVerticalZoomStep() const
Get the current vertical zoom step.
QColor map(float value) const
bool clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const
virtual void resizeSelection(Selection s, Selection newSize)
virtual bool setDisplayExtents(float min, float max)
Set the displayed minimum and maximum values for the y axis to the given range, if supported.
virtual void eraseDrag(View *v, QMouseEvent *)
void setVerticalScale(VerticalScale scale)
SparseTimeValueModel::PointList getLocalPoints(View *v, int) const
virtual void drawStart(View *v, QMouseEvent *)
virtual int alignFromReference(View *v, int frame) const
virtual int alignToReference(View *v, int frame) const
int getModelsEndFrame() const
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
int getWidth(View *v, QPainter &paint)
virtual void moveSelection(Selection s, int newStartFrame)
virtual void drawEnd(View *v, QMouseEvent *)
virtual int getVerticalZoomSteps(int &defaultStep) const
Get the number of vertical zoom steps available for this layer.
virtual PropertyList getProperties() const
virtual void paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const
void setDrawSegmentDivisions(bool)
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
virtual void drawVisibleText(QPainter &p, int x, int y, QString text, TextStyle style) const
bool m_drawSegmentDivisions
void paintVertical(View *v, const ColourScaleLayer *layer, QPainter &paint, int x0, float minf, float maxf)
void setShowDerivative(bool)
virtual QString getLabelPreceding(int) const
virtual bool snapToSimilarFeature(View *v, int &frame, int &resolution, SnapType snap) const
Adjust the given frame to snap to the next feature that has "effectively" the same value as the featu...
virtual QString getFeatureDescription(View *v, QPoint &) const
virtual PropertyList getProperties() const
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
void finish(SparseTimeValueModel::EditCommand *command)
virtual bool editOpen(View *v, QMouseEvent *)
Open an editor on the item under the mouse (e.g.
void setFillColourMap(int)
virtual QString getPropertyGroupName(const PropertyName &) const
virtual int getDefaultColourHint(bool dark, bool &impose)
virtual void editEnd(View *v, QMouseEvent *)
virtual bool getDisplayExtents(float &min, float &max) const
Return the minimum and maximum values within the displayed range for the y axis, if only a subset of ...
SparseTimeValueModel::Point m_originalPoint
SparseTimeValueModel::EditCommand * m_editingCommand
virtual PropertyType getPropertyType(const PropertyName &) const
int getXForFrame(int frame) const
Return the pixel x-coordinate corresponding to a given sample frame (which may be negative).
static ColourDatabase * getInstance()
bool shouldAutoAlign() const
virtual void setProperty(const PropertyName &, int value)
void setValue(float value)
virtual void editStart(View *v, QMouseEvent *)
static QString getColourMapName(int n)