aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/controls
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2016-01-26 14:24:04 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2016-01-28 09:29:30 +0000
commit147c215ec9174c394bcaa2c33760df735f4d1ebf (patch)
tree4234dc2fa594f1bb02384d6c2b1fddcb83e1d121 /src/imports/controls
parent39af88a8da473afe039201164a4c2a7980f7c2f9 (diff)
Material ProgressBar: implement indeterminate animator
The indicator is now a single QQuickItem, and runs in the render thread, so keeps animating even if the app is busy. Before: RESULT : tst_CreationTime::material():"ProgressBar": 0.30 msecs per iteration (total: 79, iterations: 256) After: RESULT : tst_CreationTime::material():"ProgressBar": 0.18 msecs per iteration (total: 93, iterations: 512) Change-Id: I3ec0982da9a02751725692c72da10a01d2afbfdc Task-number: QTBUG-50161 Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src/imports/controls')
-rw-r--r--src/imports/controls/material/ProgressBar.qml40
-rw-r--r--src/imports/controls/material/material.pri6
-rw-r--r--src/imports/controls/material/qquickmaterialprogressstrip.cpp248
-rw-r--r--src/imports/controls/material/qquickmaterialprogressstrip_p.h101
-rw-r--r--src/imports/controls/material/qtlabsmaterialstyleplugin.cpp3
5 files changed, 367 insertions, 31 deletions
diff --git a/src/imports/controls/material/ProgressBar.qml b/src/imports/controls/material/ProgressBar.qml
index 59c03204..52df1660 100644
--- a/src/imports/controls/material/ProgressBar.qml
+++ b/src/imports/controls/material/ProgressBar.qml
@@ -37,6 +37,7 @@
import QtQuick 2.6
import Qt.labs.templates 1.0 as T
import Qt.labs.controls.material 1.0
+import Qt.labs.controls.material.impl 1.0
T.ProgressBar {
id: control
@@ -47,40 +48,21 @@ T.ProgressBar {
indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding
//! [indicator]
- indicator: Item {
+ indicator: ProgressStrip {
+ id: strip
x: control.leftPadding
- y: control.topPadding
+ y: control.topPadding + (control.availableHeight - height) / 2
width: control.availableWidth
- height: control.availableHeight
+ height: 4
scale: control.mirrored ? -1 : 1
+ indeterminate: control.indeterminate
+ color: control.Material.accentColor
+ progress: control.position
- Repeater {
- model: indeterminate ? 2 : 1
-
- Rectangle {
- property real offset: indeterminate ? 0 : control.position
-
- x: (indeterminate ? offset * parent.width : 0)
- y: (parent.height - height) / 2
- width: offset * (parent.width - x)
- height: 4
-
- color: control.Material.accentColor
-
- SequentialAnimation on offset {
- loops: Animation.Infinite
- running: indeterminate && visible
- PauseAnimation { duration: index ? 520 : 0 }
- NumberAnimation {
- easing.type: Easing.OutCubic
- duration: 1240
- from: 0
- to: 1
- }
- PauseAnimation { duration: index ? 0 : 520 }
- }
- }
+ StripAnimator {
+ target: strip
+ running: control.visible && control.indeterminate
}
}
//! [indicator]
diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri
index bcdc0de9..e41c7d2d 100644
--- a/src/imports/controls/material/material.pri
+++ b/src/imports/controls/material/material.pri
@@ -1,12 +1,14 @@
HEADERS += \
$$PWD/qquickmaterialstyle_p.h \
$$PWD/qquickmaterialtheme_p.h \
- $$PWD/qquickmaterialprogressring_p.h
+ $$PWD/qquickmaterialprogressring_p.h \
+ $$PWD/qquickmaterialprogressstrip_p.h
SOURCES += \
$$PWD/qquickmaterialstyle.cpp \
$$PWD/qquickmaterialtheme.cpp \
- $$PWD/qquickmaterialprogressring.cpp
+ $$PWD/qquickmaterialprogressring.cpp \
+ $$PWD/qquickmaterialprogressstrip.cpp
QML_FILES += \
$$PWD/ApplicationWindow.qml \
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip.cpp b/src/imports/controls/material/qquickmaterialprogressstrip.cpp
new file mode 100644
index 00000000..3ac09e24
--- /dev/null
+++ b/src/imports/controls/material/qquickmaterialprogressstrip.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmaterialprogressstrip_p.h"
+
+#include <QtCore/qmath.h>
+#include <QtCore/qeasingcurve.h>
+#include <QtQuick/qsgsimplerectnode.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickanimatorjob_p.h>
+#include <QtQuick/private/qsgadaptationlayer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int PauseDuration = 520;
+static const int SlideDuration = 1240;
+static const int TotalDuration = SlideDuration + PauseDuration;
+
+class QQuickMaterialProgressStripAnimatorJob : public QQuickAnimatorJob
+{
+public:
+ QQuickMaterialProgressStripAnimatorJob();
+
+ void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE;
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
+ void nodeWasDestroyed() Q_DECL_OVERRIDE;
+ void afterNodeSync() Q_DECL_OVERRIDE;
+
+ void moveNode(QSGTransformNode *node, const QRectF &geometry, qreal progress);
+
+private:
+ QSGNode *m_node;
+};
+
+QQuickMaterialProgressStripAnimatorJob::QQuickMaterialProgressStripAnimatorJob() : m_node(Q_NULLPTR)
+{
+}
+
+void QQuickMaterialProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller)
+{
+ QQuickAnimatorJob::initialize(controller);
+ m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+}
+
+void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time)
+{
+ if (!m_node)
+ return;
+
+ QSGSimpleRectNode *geometryNode = static_cast<QSGSimpleRectNode *>(m_node->firstChild());
+ Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
+ if (!geometryNode)
+ return;
+
+ const QRectF geometry = geometryNode->rect();
+
+ QSGTransformNode *firstNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
+ if (firstNode) {
+ Q_ASSERT(firstNode->type() == QSGNode::TransformNodeType);
+
+ const qreal progress = qMin<qreal>(1.0, static_cast<qreal>(time) / SlideDuration);
+ moveNode(static_cast<QSGTransformNode *>(firstNode), geometry, progress);
+ }
+
+ QSGTransformNode *secondNode = static_cast<QSGTransformNode *>(geometryNode->lastChild());
+ if (secondNode) {
+ Q_ASSERT(secondNode->type() == QSGNode::TransformNodeType);
+
+ const qreal progress = qMax<qreal>(0.0, static_cast<qreal>(time - PauseDuration) / SlideDuration);
+ moveNode(static_cast<QSGTransformNode *>(secondNode), geometry, progress);
+ }
+}
+
+void QQuickMaterialProgressStripAnimatorJob::writeBack()
+{
+}
+
+void QQuickMaterialProgressStripAnimatorJob::nodeWasDestroyed()
+{
+ m_node = Q_NULLPTR;
+}
+
+void QQuickMaterialProgressStripAnimatorJob::afterNodeSync()
+{
+ m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+}
+
+void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
+{
+ const qreal value = m_easing.valueForProgress(progress);
+ const qreal x = value * geometry.width();
+
+ QMatrix4x4 matrix;
+ matrix.translate(x, 0);
+ transformNode->setMatrix(matrix);
+
+ QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ QRectF r = geometry;
+ r.setWidth(value * (geometry.width() - x));
+ rectNode->setRect(r);
+ rectNode->update();
+}
+
+QQuickMaterialStripAnimator::QQuickMaterialStripAnimator(QObject *parent)
+ : QQuickAnimator(parent)
+{
+ setLoops(Infinite);
+ setDuration(TotalDuration);
+ setEasing(QEasingCurve::OutCubic);
+}
+
+QString QQuickMaterialStripAnimator::propertyName() const
+{
+ return QString();
+}
+
+QQuickAnimatorJob *QQuickMaterialStripAnimator::createJob() const
+{
+ return new QQuickMaterialProgressStripAnimatorJob;
+}
+
+QQuickMaterialProgressStrip::QQuickMaterialProgressStrip(QQuickItem *parent)
+ : QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
+{
+ setFlag(ItemHasContents);
+}
+
+QColor QQuickMaterialProgressStrip::color() const
+{
+ return m_color;
+}
+
+void QQuickMaterialProgressStrip::setColor(const QColor &color)
+{
+ if (color == m_color)
+ return;
+
+ m_color = color;
+ update();
+}
+
+qreal QQuickMaterialProgressStrip::progress() const
+{
+ return m_progress;
+}
+
+void QQuickMaterialProgressStrip::setProgress(qreal progress)
+{
+ if (progress == m_progress)
+ return;
+
+ m_progress = progress;
+ update();
+}
+
+bool QQuickMaterialProgressStrip::isIndeterminate() const
+{
+ return m_indeterminate;
+}
+
+void QQuickMaterialProgressStrip::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate == m_indeterminate)
+ return;
+
+ m_indeterminate = indeterminate;
+ update();
+}
+
+QSGNode *QQuickMaterialProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QQuickItemPrivate *d = QQuickItemPrivate::get(this);
+
+ if (!oldNode)
+ oldNode = new QSGSimpleRectNode(boundingRect(), Qt::transparent);
+ static_cast<QSGSimpleRectNode *>(oldNode)->setRect(boundingRect());
+
+ const int count = m_indeterminate ? 2 : 1;
+ const qreal w = m_indeterminate ? 0 : m_progress * width();
+
+ QSGNode *transformNode = oldNode->firstChild();
+ for (int i = 0; i < count; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ oldNode->appendChildNode(transformNode);
+
+ QSGRectangleNode *rectNode = d->sceneGraphContext()->createRectangleNode();
+ rectNode->setAntialiasing(true);
+ transformNode->appendChildNode(rectNode);
+ }
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+
+ QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ rectNode->setRect(QRectF(0, 0, w, height()));
+ rectNode->setColor(m_color);
+ rectNode->update();
+
+ transformNode = transformNode->nextSibling();
+ }
+
+ while (transformNode) {
+ QSGNode *nextSibling = transformNode->nextSibling();
+ delete transformNode;
+ transformNode = nextSibling;
+ }
+
+ return oldNode;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip_p.h b/src/imports/controls/material/qquickmaterialprogressstrip_p.h
new file mode 100644
index 00000000..d0618af6
--- /dev/null
+++ b/src/imports/controls/material/qquickmaterialprogressstrip_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Labs Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKMATERIALPROGRESSSTRIP_P_H
+#define QQUICKMATERIALPROGRESSSTRIP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickanimator_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickMaterialProgressStrip : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
+ Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL)
+ Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL)
+
+public:
+ QQuickMaterialProgressStrip(QQuickItem *parent = Q_NULLPTR);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ qreal progress() const;
+ void setProgress(qreal progress);
+
+ bool isIndeterminate() const;
+ void setIndeterminate(bool indeterminate);
+
+protected:
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+
+private:
+ QColor m_color;
+ qreal m_progress;
+ bool m_indeterminate;
+};
+
+class QQuickMaterialStripAnimator : public QQuickAnimator
+{
+ Q_OBJECT
+
+public:
+ QQuickMaterialStripAnimator(QObject *parent = Q_NULLPTR);
+
+protected:
+ QString propertyName() const Q_DECL_OVERRIDE;
+ QQuickAnimatorJob *createJob() const Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickMaterialProgressStrip)
+QML_DECLARE_TYPE(QQuickMaterialStripAnimator)
+
+#endif // QQUICKMATERIALPROGRESSSTRIP_P_H
diff --git a/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp b/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp
index 62db204e..ca10c289 100644
--- a/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp
+++ b/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp
@@ -39,6 +39,7 @@
#include "qquickmaterialstyle_p.h"
#include "qquickmaterialtheme_p.h"
#include "qquickmaterialprogressring_p.h"
+#include "qquickmaterialprogressstrip_p.h"
#include <QtGui/private/qguiapplication_p.h>
#include <QtLabsControls/private/qquickstyleselector_p.h>
@@ -98,7 +99,9 @@ void QtLabsMaterialStylePlugin::initializeEngine(QQmlEngine *engine, const char
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterType<QQuickMaterialProgressRing>(import, 1, 0, "ProgressRing");
+ qmlRegisterType<QQuickMaterialProgressStrip>(import, 1, 0, "ProgressStrip");
qmlRegisterType<QQuickMaterialRingAnimator>(import, 1, 0, "RingAnimator");
+ qmlRegisterType<QQuickMaterialStripAnimator>(import, 1, 0, "StripAnimator");
}
QT_END_NAMESPACE