aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/controls/qquickbusyindicatorring.cpp
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2015-12-15 09:21:39 +0100
committerMitch Curtis <mitch.curtis@theqtcompany.com>2015-12-16 17:24:47 +0000
commit2600bd0eedeaff3dd7727a57ee6149f5211780b4 (patch)
tree4a04a4bb12568fc0b5c76db0ccabf7a41f63a076 /src/imports/controls/qquickbusyindicatorring.cpp
parent2b81cdd40cdd265a50f91b4775cf5638b987d69f (diff)
Implement BusyIndicator according to designs
Change-Id: Iffaafc1d5512b4e47a7c6c304a3883ab8d986b12 Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com> Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src/imports/controls/qquickbusyindicatorring.cpp')
-rw-r--r--src/imports/controls/qquickbusyindicatorring.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/imports/controls/qquickbusyindicatorring.cpp b/src/imports/controls/qquickbusyindicatorring.cpp
new file mode 100644
index 00000000..4711ae1b
--- /dev/null
+++ b/src/imports/controls/qquickbusyindicatorring.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick 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 "qquickbusyindicatorring_p.h"
+
+#include <QtCore/qset.h>
+#include <QtGui/qpainter.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/qsgsimplerectnode.h>
+#include <QtQuick/qquickwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickBusyIndicatorAnimatorJob : public QQuickAnimatorJob
+{
+public:
+ QQuickBusyIndicatorAnimatorJob();
+ ~QQuickBusyIndicatorAnimatorJob();
+
+ void updateCurrentTime(int time) Q_DECL_OVERRIDE;
+ void writeBack() Q_DECL_OVERRIDE;
+ void nodeWasDestroyed() Q_DECL_OVERRIDE;
+};
+
+static const int circles = 10;
+static const int animationDuration = 100 * circles * 2;
+
+QQuickBusyIndicatorRing::QQuickBusyIndicatorRing(QQuickItem *parent) :
+ QQuickItem(parent)
+{
+ setFlag(QQuickItem::ItemHasContents);
+ setImplicitWidth(116);
+ setImplicitHeight(116);
+}
+
+QQuickBusyIndicatorRing::~QQuickBusyIndicatorRing()
+{
+}
+
+static QPointF moveBy(const QPointF &pos, qreal rotation, qreal distance)
+{
+ return pos - QTransform().rotate(rotation).map(QPointF(0, distance));
+}
+
+QSGNode *QQuickBusyIndicatorRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickItemPrivate *d = QQuickItemPrivate::get(this);
+
+ if (!oldNode)
+ oldNode = new QSGSimpleRectNode(boundingRect(), Qt::transparent);
+ static_cast<QSGSimpleRectNode *>(oldNode)->setRect(boundingRect());
+
+ QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode *>(oldNode->firstChild());
+ if (!rootTransformNode) {
+ rootTransformNode = new QSGTransformNode;
+ oldNode->appendChildNode(rootTransformNode);
+ }
+ Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
+
+ const qreal w = width();
+ const qreal h = height();
+ const qreal sz = qMin(w, h);
+ const qreal dx = (w - sz) / 2;
+ const qreal dy = (h - sz) / 2;
+ const int circleRadius = sz / 12;
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(rootTransformNode->firstChild());
+ for (int i = 0; i < circles; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ rootTransformNode->appendChildNode(transformNode);
+
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ transformNode->appendChildNode(opacityNode);
+
+ QSGRectangleNode *rectNode = d->sceneGraphContext()->createRectangleNode();
+ rectNode->setAntialiasing(true);
+ rectNode->setColor(QColor("#353637"));
+ rectNode->setPenColor(QColor("#353637"));
+ opacityNode->appendChildNode(rectNode);
+ }
+
+ QSGNode *opacityNode = transformNode->firstChild();
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius);
+ pos = moveBy(pos, 360 / circles * i, sz / 2 - circleRadius);
+
+ QMatrix4x4 m;
+ m.translate(dx + pos.x(), dy + pos.y());
+ transformNode->setMatrix(m);
+
+ rectNode->setRect(QRectF(QPointF(), QSizeF(circleRadius * 2, circleRadius * 2)));
+ rectNode->setRadius(circleRadius);
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
+ }
+
+ return oldNode;
+}
+
+QQuickBusyIndicatorAnimator::QQuickBusyIndicatorAnimator(QObject *parent) :
+ QQuickAnimator(parent)
+{
+ setDuration(animationDuration);
+ setLoops(QQuickAnimator::Infinite);
+}
+
+QString QQuickBusyIndicatorAnimator::propertyName() const
+{
+ return QString();
+}
+
+QQuickAnimatorJob *QQuickBusyIndicatorAnimator::createJob() const
+{
+ return new QQuickBusyIndicatorAnimatorJob;
+}
+
+QQuickBusyIndicatorAnimatorJob::QQuickBusyIndicatorAnimatorJob()
+{
+}
+
+QQuickBusyIndicatorAnimatorJob::~QQuickBusyIndicatorAnimatorJob()
+{
+}
+
+void QQuickBusyIndicatorAnimatorJob::updateCurrentTime(int time)
+{
+ if (!m_target)
+ return;
+
+ QSGNode *childContainerNode = QQuickItemPrivate::get(m_target)->childContainerNode();
+ QSGSimpleRectNode *rootRectNode = static_cast<QSGSimpleRectNode*>(childContainerNode->firstChild());
+ if (!rootRectNode)
+ return;
+
+ Q_ASSERT(rootRectNode->type() == QSGNode::GeometryNodeType);
+
+ QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode*>(rootRectNode->firstChild());
+ Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
+
+ const qreal percentageComplete = time / qreal(animationDuration);
+ const qreal firstPhaseProgress = percentageComplete <= 0.5 ? percentageComplete * 2 : 0;
+ const qreal secondPhaseProgress = percentageComplete > 0.5 ? (percentageComplete - 0.5) * 2 : 0;
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+ for (int i = 0; i < circles; ++i) {
+ QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode*>(transformNode->firstChild());
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGRectangleNode *rectNode = static_cast<QSGRectangleNode*>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ const bool fill = (firstPhaseProgress > qreal(i) / circles) || (secondPhaseProgress > 0 && secondPhaseProgress < qreal(i) / circles);
+ rectNode->setPenWidth(fill ? 0 : 1);
+ rectNode->setColor(fill ? QColor("#353637") : QColor("transparent"));
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
+ }
+}
+
+void QQuickBusyIndicatorAnimatorJob::writeBack()
+{
+}
+
+void QQuickBusyIndicatorAnimatorJob::nodeWasDestroyed()
+{
+}
+
+QT_END_NAMESPACE