From ee06ee8e32d5512d69c4425ae7984410ee5afe5e Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Fri, 21 Sep 2018 09:38:52 +0300 Subject: Use a smoother looping animation in loading indicator Previous had an abrupt restart for the next go around. Instead clear the circle with the same speed as it is filled. To avoid flashing line cap changes, make sure there's always a bit of the green line available after the start. endAngle was confusing naming, because it implied that the angle is given in a similar way as startAngle, 0 being at the top and 180 at the bottom. This was not the case, as instead it is the length of the arc in angles. Rename it to spanAngle. Task-number: QTBUG-70548 Change-Id: Ia9d916cfa120f81e10c00caf6d10c653a9393efc Reviewed-by: Sami Nurmenniemi Reviewed-by: Mikko Gronoff Reviewed-by: Kari Hormi --- qml/BusyIndicator.qml | 31 ++++++++++++++++--------------- src/circularindicator.cpp | 18 +++++++++--------- src/circularindicator.h | 10 +++++----- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/qml/BusyIndicator.qml b/qml/BusyIndicator.qml index f2c9d80..2d45ef6 100644 --- a/qml/BusyIndicator.qml +++ b/qml/BusyIndicator.qml @@ -39,43 +39,44 @@ CircularIndicator { SequentialAnimation { running: true - // Fill 1/5 of the circle before starting looping + // Fill 20 degrees of the circle before starting looping NumberAnimation { target: circularIndicator - property: "endAngle" + property: "spanAngle" from: 0 - to: 72 + to: 20 duration: 200 } SequentialAnimation { loops: Animation.Infinite - // Fill rest of the circle + // Fill the circle, except have both caps still visible NumberAnimation { target: circularIndicator - property: "endAngle" - from: 72 - to: 360 + property: "spanAngle" + from: 20 + to: 345 duration: 800 } - // Fill 1/5 of the circle and clear previous fill + // Clear the circle, except for a 20 degree head start. The head start is to + // avoid an abrupt change in the cap of the indicator arc from an end to a beginning. ParallelAnimation { NumberAnimation { target: circularIndicator property: "startAngle" - from: -360 - to: 0 - duration: 200 + from: 0 + to: 360 + duration: 800 onStopped: circularIndicator.startAngle = 0 } NumberAnimation { target: circularIndicator - property: "endAngle" - from: 360 - to: 72 - duration: 200 + property: "spanAngle" + from: 345 + to: 20 + duration: 800 } } } diff --git a/src/circularindicator.cpp b/src/circularindicator.cpp index d923b68..f3f5a31 100644 --- a/src/circularindicator.cpp +++ b/src/circularindicator.cpp @@ -31,7 +31,7 @@ CircularIndicator::CircularIndicator(QQuickItem *parent) : QQuickPaintedItem(parent) , m_startAngle(0) - , m_endAngle(360) + , m_spanAngle(360) , m_lineWidth(10) , m_progressColor(QColor(255, 0, 0)) , m_backgroundColor(QColor(240, 240, 240)) @@ -58,18 +58,18 @@ void CircularIndicator::setStartAngle(int angle) update(); } -int CircularIndicator::endAngle() const +int CircularIndicator::spanAngle() const { - return m_endAngle; + return m_spanAngle; } -void CircularIndicator::setEndAngle(int angle) +void CircularIndicator::setSpanAngle(int angle) { - if (angle == m_endAngle) + if (angle == m_spanAngle) return; - m_endAngle = angle; - emit endAngleChanged(m_endAngle); + m_spanAngle = angle; + emit spanAngleChanged(m_spanAngle); update(); } @@ -156,11 +156,11 @@ void CircularIndicator::paint(QPainter *painter) painter->setPen(pen); painter->drawArc(indicatorRect, 0, 360 * 16); - if (m_startAngle == m_endAngle) + if (m_startAngle == m_spanAngle) return; // Draw the foreground pen.setColor(m_progressColor); painter->setPen(pen); - painter->drawArc(indicatorRect, (90 - m_startAngle) * 16, -m_endAngle * 16); + painter->drawArc(indicatorRect, (90 - m_startAngle) * 16, -m_spanAngle * 16); } diff --git a/src/circularindicator.h b/src/circularindicator.h index 9131317..a03c742 100644 --- a/src/circularindicator.h +++ b/src/circularindicator.h @@ -36,7 +36,7 @@ class CircularIndicator : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(int startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged) - Q_PROPERTY(int endAngle READ endAngle WRITE setEndAngle NOTIFY endAngleChanged) + Q_PROPERTY(int spanAngle READ spanAngle WRITE setSpanAngle NOTIFY spanAngleChanged) Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged) Q_PROPERTY(QColor progressColor READ progressColor WRITE setProgressColor NOTIFY progressColorChanged) Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged) @@ -47,7 +47,7 @@ public: ~CircularIndicator(); int startAngle() const; - int endAngle() const; + int spanAngle() const; int lineWidth() const; QColor progressColor() const; QColor backgroundColor() const; @@ -55,7 +55,7 @@ public: public slots: void setStartAngle(int angle); - void setEndAngle(int angle); + void setSpanAngle(int angle); void setLineWidth(int width); void setProgressColor(const QColor &color); void setBackgroundColor(const QColor &color); @@ -63,7 +63,7 @@ public slots: signals: void startAngleChanged(int); - void endAngleChanged(int); + void spanAngleChanged(int); void lineWidthChanged(int); void progressColorChanged(QColor); void backgroundColorChanged(QColor); @@ -74,7 +74,7 @@ protected: private: int m_startAngle; - int m_endAngle; + int m_spanAngle; int m_lineWidth; QColor m_progressColor; QColor m_backgroundColor; -- cgit v1.2.3