From d72e18da2d1703ad56a0cfa30fedb70e97c73174 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Tue, 17 Mar 2020 16:41:34 +0100 Subject: [PATCH] Use QEasing instead of Bezier to paint the curve segments This way "failure state" is reflected in the appearance of the curve item Change-Id: I997f86f1a6072eaf65c77f2df0afd53a80dc0d0e Reviewed-by: Thomas Hartmann --- .../components/curveeditor/curvesegment.cpp | 33 +++++++++++-------- .../components/curveeditor/curvesegment.h | 2 ++ .../animationcurveeditormodel.cpp | 7 ++++ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp index 9d70c2a8bf5..0bcb64e0357 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curvesegment.cpp @@ -224,6 +224,23 @@ QPainterPath CurveSegment::path() const return path; } +void CurveSegment::extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const +{ + auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) { + QPointF slope(end.x() - start.x(), end.y() - start.y()); + return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y()); + }; + + QVector points = curve.toCubicSpline(); + int numSegments = points.count() / 3; + for (int i = 0; i < numSegments; i++) { + QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3)); + QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1)); + QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2)); + path.cubicTo(p1, p2, p3); + } +} + void CurveSegment::extend(QPainterPath &path) const { if (interpolation() == Keyframe::Interpolation::Linear) { @@ -232,23 +249,11 @@ void CurveSegment::extend(QPainterPath &path) const path.lineTo(QPointF(m_right.position().x(), m_left.position().y())); path.lineTo(m_right.position()); } else if (interpolation() == Keyframe::Interpolation::Bezier) { - path.cubicTo(m_left.rightHandle(), m_right.leftHandle(), m_right.position()); + extendWithEasingCurve(path, easingCurve()); } else if (interpolation() == Keyframe::Interpolation::Easing) { - auto mapEasing = [](const QPointF &start, const QPointF &end, const QPointF &pos) { - QPointF slope(end.x() - start.x(), end.y() - start.y()); - return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y()); - }; - QVariant data = m_right.data(); if (data.isValid() && data.type() == static_cast(QMetaType::QEasingCurve)) { - QVector points = data.value().toCubicSpline(); - int numSegments = points.count() / 3; - for (int i = 0; i < numSegments; i++) { - QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3)); - QPointF p2 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 1)); - QPointF p3 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3 + 2)); - path.cubicTo(p1, p2, p3); - } + extendWithEasingCurve(path, data.value()); } } } diff --git a/src/plugins/qmldesigner/components/curveeditor/curvesegment.h b/src/plugins/qmldesigner/components/curveeditor/curvesegment.h index dd5f9f8c550..d7b86aada07 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curvesegment.h +++ b/src/plugins/qmldesigner/components/curveeditor/curvesegment.h @@ -61,6 +61,8 @@ public: void extend(QPainterPath &path) const; + void extendWithEasingCurve(QPainterPath &path, const QEasingCurve &curve) const; + QEasingCurve easingCurve() const; std::vector extrema() const; diff --git a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp index d37be1cd357..35b89f6f170 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/animationcurveeditormodel.cpp @@ -206,6 +206,13 @@ std::vector resolveSmallCurves( QEasingCurve curve = frame.data().toEasingCurve(); if (curve.toCubicSpline().count() == 3) { DesignTools::Keyframe &previous = out.back(); +#if 0 + // Do not resolve when two adjacent keyframes have the same value. + if (qFuzzyCompare(previous.position().y(), frame.position().y())) { + out.push_back(frame); + continue; + } +#endif DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position()); previous.setRightHandle(acurve.keyframeAt(0).rightHandle()); out.push_back(acurve.keyframeAt(1));