aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/imports/controls/BusyIndicator.qml13
-rw-r--r--src/imports/controls/Dial.qml4
-rw-r--r--src/imports/controls/ProgressBar.qml10
-rw-r--r--src/imports/controls/RangeSlider.qml4
-rw-r--r--src/imports/controls/Slider.qml4
-rw-r--r--src/imports/controls/Tumbler.qml4
-rw-r--r--src/imports/controls/controls.pri10
-rw-r--r--src/imports/controls/material/BusyIndicator.qml19
-rw-r--r--src/imports/controls/material/Dial.qml2
-rw-r--r--src/imports/controls/material/ProgressBar.qml10
-rw-r--r--src/imports/controls/material/RangeSlider.qml2
-rw-r--r--src/imports/controls/material/Slider.qml2
-rw-r--r--src/imports/controls/material/Tumbler.qml4
-rw-r--r--src/imports/controls/material/material.pri12
-rw-r--r--src/imports/controls/material/qquickmaterialbusyindicator.cpp (renamed from src/imports/controls/material/qquickmaterialprogressring.cpp)234
-rw-r--r--src/imports/controls/material/qquickmaterialbusyindicator_p.h (renamed from src/imports/controls/material/qquickmaterialprogressring_p.h)31
-rw-r--r--src/imports/controls/material/qquickmaterialprogressbar.cpp (renamed from src/imports/controls/material/qquickmaterialprogressstrip.cpp)206
-rw-r--r--src/imports/controls/material/qquickmaterialprogressbar_p.h (renamed from src/imports/controls/material/qquickmaterialprogressstrip_p.h)27
-rw-r--r--src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp10
-rw-r--r--src/imports/controls/qquickbusyindicatorring.cpp231
-rw-r--r--src/imports/controls/qquickdefaultbusyindicator.cpp188
-rw-r--r--src/imports/controls/qquickdefaultbusyindicator_p.h (renamed from src/imports/controls/qquickbusyindicatorring_p.h)28
-rw-r--r--src/imports/controls/qquickdefaultprogressbar.cpp277
-rw-r--r--src/imports/controls/qquickdefaultprogressbar_p.h (renamed from src/imports/controls/qquickprogressstrip_p.h)25
-rw-r--r--src/imports/controls/qquickprogressstrip.cpp315
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp20
-rw-r--r--src/imports/controls/universal/BusyIndicator.qml10
-rw-r--r--src/imports/controls/universal/Dial.qml2
-rw-r--r--src/imports/controls/universal/ProgressBar.qml11
-rw-r--r--src/imports/controls/universal/RangeSlider.qml2
-rw-r--r--src/imports/controls/universal/Slider.qml2
-rw-r--r--src/imports/controls/universal/Tumbler.qml4
-rw-r--r--src/imports/controls/universal/qquickuniversalbusyindicator.cpp (renamed from src/imports/controls/universal/qquickuniversalprogressring.cpp)201
-rw-r--r--src/imports/controls/universal/qquickuniversalbusyindicator_p.h (renamed from src/imports/controls/universal/qquickuniversalprogressring_p.h)35
-rw-r--r--src/imports/controls/universal/qquickuniversalprogressbar.cpp (renamed from src/imports/controls/universal/qquickuniversalprogressstrip.cpp)223
-rw-r--r--src/imports/controls/universal/qquickuniversalprogressbar_p.h (renamed from src/imports/controls/universal/qquickuniversalprogressstrip_p.h)27
-rw-r--r--src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp10
-rw-r--r--src/imports/controls/universal/universal.pri8
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp6
-rw-r--r--src/quicktemplates2/qquickdial.cpp46
-rw-r--r--src/quicktemplates2/qquickdial_p.h5
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp46
-rw-r--r--src/quicktemplates2/qquickrangeslider_p.h5
-rw-r--r--src/quicktemplates2/qquickslider.cpp51
-rw-r--r--src/quicktemplates2/qquickslider_p.h5
-rw-r--r--src/quicktemplates2/qquicktumbler.cpp15
-rw-r--r--src/quicktemplates2/qquicktumbler_p.h4
-rw-r--r--tests/auto/controls/data/tst_dial.qml18
-rw-r--r--tests/auto/controls/data/tst_rangeslider.qml12
-rw-r--r--tests/auto/controls/data/tst_slider.qml18
-rw-r--r--tests/auto/controls/data/tst_tumbler.qml28
52 files changed, 1225 insertions, 1263 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 0104dac8..8114dfd7 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -4,4 +4,4 @@ DEFINES += QT_NO_FOREACH
QQC2_SOURCE_TREE = $$PWD
-MODULE_VERSION = 5.8.0
+MODULE_VERSION = 5.9.0
diff --git a/src/imports/controls/BusyIndicator.qml b/src/imports/controls/BusyIndicator.qml
index 936764fa..16fb6091 100644
--- a/src/imports/controls/BusyIndicator.qml
+++ b/src/imports/controls/BusyIndicator.qml
@@ -48,18 +48,13 @@ T.BusyIndicator {
padding: 6
//! [contentItem]
- contentItem: BusyRing {
- id: ring
+ contentItem: BusyIndicatorImpl {
implicitWidth: 48
implicitHeight: 48
- opacity: control.running ? 1 : 0
-
- Behavior on opacity { OpacityAnimator { duration: 250 } }
- BusyRingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ opacity: control.running ? 1 : 0
+ visible: control.running || animator.running
+ Behavior on opacity { OpacityAnimator { id: animator; duration: 250 } }
}
//! [contentItem]
}
diff --git a/src/imports/controls/Dial.qml b/src/imports/controls/Dial.qml
index f19fcc2b..e4579ca9 100644
--- a/src/imports/controls/Dial.qml
+++ b/src/imports/controls/Dial.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Dial {
id: control
diff --git a/src/imports/controls/ProgressBar.qml b/src/imports/controls/ProgressBar.qml
index a0d0912a..130adcec 100644
--- a/src/imports/controls/ProgressBar.qml
+++ b/src/imports/controls/ProgressBar.qml
@@ -48,18 +48,12 @@ T.ProgressBar {
contentItem.implicitHeight + topPadding + bottomPadding)
//! [contentItem]
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 6
implicitWidth: 116
scale: control.mirrored ? -1 : 1
progress: control.position
- indeterminate: control.indeterminate
-
- ProgressStripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
//! [contentItem]
diff --git a/src/imports/controls/RangeSlider.qml b/src/imports/controls/RangeSlider.qml
index 6b892fd1..005fa99c 100644
--- a/src/imports/controls/RangeSlider.qml
+++ b/src/imports/controls/RangeSlider.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.RangeSlider {
id: control
diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml
index f7e95db9..d2aba229 100644
--- a/src/imports/controls/Slider.qml
+++ b/src/imports/controls/Slider.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Slider {
id: control
diff --git a/src/imports/controls/Tumbler.qml b/src/imports/controls/Tumbler.qml
index 6c89b86d..0be6c074 100644
--- a/src/imports/controls/Tumbler.qml
+++ b/src/imports/controls/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
T.Tumbler {
id: control
diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri
index 79e03db5..8a262694 100644
--- a/src/imports/controls/controls.pri
+++ b/src/imports/controls/controls.pri
@@ -1,13 +1,13 @@
HEADERS += \
- $$PWD/qquickbusyindicatorring_p.h \
- $$PWD/qquickprogressstrip_p.h \
$$PWD/qquickdialring_p.h \
- $$PWD/qquickdefaultstyle_p.h
+ $$PWD/qquickdefaultbusyindicator_p.h \
+ $$PWD/qquickdefaultprogressbar_p.h \
+ $$PWD/qquickdefaultstyle_p.h \
SOURCES += \
- $$PWD/qquickbusyindicatorring.cpp \
- $$PWD/qquickprogressstrip.cpp \
$$PWD/qquickdialring.cpp \
+ $$PWD/qquickdefaultbusyindicator.cpp \
+ $$PWD/qquickdefaultprogressbar.cpp \
$$PWD/qquickdefaultstyle.cpp
QML_CONTROLS = \
diff --git a/src/imports/controls/material/BusyIndicator.qml b/src/imports/controls/material/BusyIndicator.qml
index 3077ceb7..5a17c002 100644
--- a/src/imports/controls/material/BusyIndicator.qml
+++ b/src/imports/controls/material/BusyIndicator.qml
@@ -47,24 +47,13 @@ T.BusyIndicator {
padding: 6
- contentItem: ProgressRing {
- id: ring
- x: control.leftPadding + (control.availableWidth - width) / 2
- y: control.topPadding + (control.availableHeight - height) / 2
+ contentItem: BusyIndicatorImpl {
implicitWidth: 48
implicitHeight: 48
- width: size
- height: size
- opacity: control.running ? 1 : 0
color: control.Material.accentColor
- readonly property real size: Math.min(control.availableWidth, control.availableHeight)
-
- Behavior on opacity { OpacityAnimator { duration: 250 } }
-
- RingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ opacity: control.running ? 1 : 0
+ visible: control.running || animator.running
+ Behavior on opacity { OpacityAnimator { id: animator; duration: 250 } }
}
}
diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml
index ce76c2a7..30bc9308 100644
--- a/src/imports/controls/material/Dial.qml
+++ b/src/imports/controls/material/Dial.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/ProgressBar.qml b/src/imports/controls/material/ProgressBar.qml
index 2b78be49..54152895 100644
--- a/src/imports/controls/material/ProgressBar.qml
+++ b/src/imports/controls/material/ProgressBar.qml
@@ -47,19 +47,13 @@ T.ProgressBar {
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentItem.implicitHeight + topPadding + bottomPadding)
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 4
scale: control.mirrored ? -1 : 1
- indeterminate: control.indeterminate
color: control.Material.accentColor
progress: control.position
-
- StripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
background: Rectangle {
diff --git a/src/imports/controls/material/RangeSlider.qml b/src/imports/controls/material/RangeSlider.qml
index 4381fd41..2442a38b 100644
--- a/src/imports/controls/material/RangeSlider.qml
+++ b/src/imports/controls/material/RangeSlider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/Slider.qml b/src/imports/controls/material/Slider.qml
index 7cf858e7..fb871a02 100644
--- a/src/imports/controls/material/Slider.qml
+++ b/src/imports/controls/material/Slider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
import QtQuick.Controls.Material.impl 2.1
diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml
index 88750855..06a012f6 100644
--- a/src/imports/controls/material/Tumbler.qml
+++ b/src/imports/controls/material/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.1
T.Tumbler {
diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri
index 3170a695..355d62a5 100644
--- a/src/imports/controls/material/material.pri
+++ b/src/imports/controls/material/material.pri
@@ -1,16 +1,16 @@
HEADERS += \
+ $$PWD/qquickmaterialbusyindicator_p.h \
+ $$PWD/qquickmaterialprogressbar_p.h \
$$PWD/qquickmaterialripple_p.h \
$$PWD/qquickmaterialstyle_p.h \
- $$PWD/qquickmaterialtheme_p.h \
- $$PWD/qquickmaterialprogressring_p.h \
- $$PWD/qquickmaterialprogressstrip_p.h
+ $$PWD/qquickmaterialtheme_p.h
SOURCES += \
+ $$PWD/qquickmaterialbusyindicator.cpp \
+ $$PWD/qquickmaterialprogressbar.cpp \
$$PWD/qquickmaterialripple.cpp \
$$PWD/qquickmaterialstyle.cpp \
- $$PWD/qquickmaterialtheme.cpp \
- $$PWD/qquickmaterialprogressring.cpp \
- $$PWD/qquickmaterialprogressstrip.cpp
+ $$PWD/qquickmaterialtheme.cpp
QML_FILES += \
$$PWD/ApplicationWindow.qml \
diff --git a/src/imports/controls/material/qquickmaterialprogressring.cpp b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
index a3564c17..d55b131b 100644
--- a/src/imports/controls/material/qquickmaterialprogressring.cpp
+++ b/src/imports/controls/material/qquickmaterialbusyindicator.cpp
@@ -34,14 +34,12 @@
**
****************************************************************************/
-#include "qquickmaterialprogressring_p.h"
+#include "qquickmaterialbusyindicator_p.h"
-#include <cmath>
-
-#include <QtCore/qset.h>
+#include <QtCore/qeasingcurve.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtGui/qpainter.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/qsgrectanglenode.h>
#include <QtQuick/qsgimagenode.h>
#include <QtQuick/qquickwindow.h>
@@ -61,200 +59,186 @@ QT_BEGIN_NAMESPACE
different path commands available.
*/
-class QQuickMaterialRingAnimatorJob : public QQuickAnimatorJob
+static const int SpanAnimationDuration = 700;
+static const int RotationAnimationDuration = SpanAnimationDuration * 6;
+static const int TargetRotation = 720;
+static const int OneDegree = 16;
+static const qreal MinSweepSpan = 10 * OneDegree;
+static const qreal MaxSweepSpan = 300 * OneDegree;
+
+class QQuickMaterialBusyIndicatorNode : public QObject, public QSGNode
{
public:
- QQuickMaterialRingAnimatorJob();
- ~QQuickMaterialRingAnimatorJob();
+ QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item);
+
+ int elapsed() const;
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void animate();
+ void sync(QQuickMaterialBusyIndicator *item);
private:
+ int m_offset;
int m_lastStartAngle;
int m_lastEndAngle;
+ qreal m_width;
+ qreal m_height;
qreal m_devicePixelRatio;
QSGNode *m_containerNode;
QQuickWindow *m_window;
+ QElapsedTimer m_timer;
QColor m_color;
};
-QQuickMaterialProgressRing::QQuickMaterialProgressRing(QQuickItem *parent) :
- QQuickItem(parent)
-{
- setFlag(QQuickItem::ItemHasContents);
-}
-
-QQuickMaterialProgressRing::~QQuickMaterialProgressRing()
-{
-}
-
-QSGNode *QQuickMaterialProgressRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+QQuickMaterialBusyIndicatorNode::QQuickMaterialBusyIndicatorNode(QQuickMaterialBusyIndicator *item) :
+ m_offset(item->elapsed()),
+ m_lastStartAngle(0),
+ m_lastEndAngle(0),
+ m_width(0),
+ m_height(0),
+ m_devicePixelRatio(1),
+ m_window(item->window())
{
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(boundingRect());
+ connect(m_window, &QQuickWindow::frameSwapped, m_window, &QQuickWindow::update);
+ connect(m_window, &QQuickWindow::beforeRendering, this, &QQuickMaterialBusyIndicatorNode::animate);
- QSGImageNode *textureNode = static_cast<QSGImageNode *>(oldNode->firstChild());
- if (!textureNode) {
- textureNode = window()->createImageNode();
- textureNode->setOwnsTexture(true);
- oldNode->appendChildNode(textureNode);
- }
+ QSGImageNode *textureNode = m_window->createImageNode();
+ textureNode->setOwnsTexture(true);
+ appendChildNode(textureNode);
// A texture seems to be required here, but we don't have one yet, as we haven't drawn anything,
// so just use a blank image.
- QImage blankImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
+ QImage blankImage(item->width(), item->height(), QImage::Format_ARGB32_Premultiplied);
blankImage.fill(Qt::transparent);
- textureNode->setRect(boundingRect());
- textureNode->setTexture(window()->createTextureFromImage(blankImage));
-
- return oldNode;
-}
-
-QColor QQuickMaterialProgressRing::color() const
-{
- return m_color;
-}
-
-void QQuickMaterialProgressRing::setColor(QColor color)
-{
- if (m_color == color)
- return;
-
- m_color = color;
- update();
- emit colorChanged();
-}
-
-static const int spanAnimationDuration = 700;
-static const int rotationAnimationDuration = spanAnimationDuration * 6;
-static const int targetRotation = 720;
-static const int oneDegree = 16;
-static const qreal minSweepSpan = 10 * oneDegree;
-static const qreal maxSweepSpan = 300 * oneDegree;
+ textureNode->setTexture(m_window->createTextureFromImage(blankImage));
-QQuickMaterialRingAnimator::QQuickMaterialRingAnimator(QObject *parent) :
- QQuickAnimator(parent)
-{
- setDuration(rotationAnimationDuration);
- setLoops(QQuickAnimator::Infinite);
+ m_timer.restart();
}
-QString QQuickMaterialRingAnimator::propertyName() const
+int QQuickMaterialBusyIndicatorNode::elapsed() const
{
- return QString();
+ return m_timer.elapsed() + m_offset;
}
-QQuickAnimatorJob *QQuickMaterialRingAnimator::createJob() const
+void QQuickMaterialBusyIndicatorNode::animate()
{
- return new QQuickMaterialRingAnimatorJob;
-}
-
-QQuickMaterialRingAnimatorJob::QQuickMaterialRingAnimatorJob() :
- m_lastStartAngle(0),
- m_lastEndAngle(0),
- m_devicePixelRatio(1.0),
- m_containerNode(nullptr),
- m_window(nullptr)
-{
-}
-
-QQuickMaterialRingAnimatorJob::~QQuickMaterialRingAnimatorJob()
-{
-}
-
-void QQuickMaterialRingAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_containerNode = QQuickItemPrivate::get(m_target)->childContainerNode();
- m_window = m_target->window();
- m_devicePixelRatio = m_window->effectiveDevicePixelRatio();
-}
-
-void QQuickMaterialRingAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_containerNode)
- return;
-
- QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(m_containerNode->firstChild());
- if (!rectNode)
- return;
+ qint64 time = m_timer.elapsed() + m_offset;
+ if (time >= RotationAnimationDuration) {
+ m_timer.restart();
+ m_offset = 0;
+ }
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+ const qreal w = m_width;
+ const qreal h = m_height;
+ const qreal size = qMin(w, h);
+ const qreal dx = (w - size) / 2;
+ const qreal dy = (h - size) / 2;
- const qreal width = rectNode->rect().width() * m_devicePixelRatio;
- const qreal height = rectNode->rect().height() * m_devicePixelRatio;
- QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
+ QImage image(size * m_devicePixelRatio, size * m_devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing);
QPen pen;
- QSGImageNode *textureNode = static_cast<QSGImageNode *>(rectNode->firstChild());
+ QSGImageNode *textureNode = static_cast<QSGImageNode *>(firstChild());
pen.setColor(m_color);
pen.setWidth(4 * m_devicePixelRatio);
painter.setPen(pen);
- const qreal percentageComplete = time / qreal(rotationAnimationDuration);
- const qreal spanPercentageComplete = (time % spanAnimationDuration) / qreal(spanAnimationDuration);
- const int iteration = time / spanAnimationDuration;
+ const qreal percentageComplete = time / qreal(RotationAnimationDuration);
+ const qreal spanPercentageComplete = (time % SpanAnimationDuration) / qreal(SpanAnimationDuration);
+ const int iteration = time / SpanAnimationDuration;
int startAngle = 0;
int endAngle = 0;
if (iteration % 2 == 0) {
- if (m_lastStartAngle > 360 * oneDegree) {
- m_lastStartAngle -= 360 * oneDegree;
- }
+ if (m_lastStartAngle > 360 * OneDegree)
+ m_lastStartAngle -= 360 * OneDegree;
// The start angle is only affected by the rotation animation for the "grow" phase.
startAngle = m_lastStartAngle;
QEasingCurve angleCurve(QEasingCurve::OutQuad);
const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
- endAngle = m_lastStartAngle + minSweepSpan + percentage * (maxSweepSpan - minSweepSpan);
+ endAngle = m_lastStartAngle + MinSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
m_lastEndAngle = endAngle;
} else {
// Both the start angle *and* the span are affected by the "shrink" phase.
QEasingCurve angleCurve(QEasingCurve::InQuad);
const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete);
- startAngle = m_lastEndAngle - maxSweepSpan + percentage * (maxSweepSpan - minSweepSpan);
+ startAngle = m_lastEndAngle - MaxSweepSpan + percentage * (MaxSweepSpan - MinSweepSpan);
endAngle = m_lastEndAngle;
m_lastStartAngle = startAngle;
}
const int halfPen = pen.width() / 2;
- const QRectF arcBounds = QRectF(halfPen, halfPen, width - pen.width(), height - pen.width());
+ const QRectF arcBounds = QRectF(halfPen, halfPen,
+ m_devicePixelRatio * size - pen.width(),
+ m_devicePixelRatio * size - pen.width());
// The current angle of the rotation animation.
- const qreal rotation = oneDegree * percentageComplete * -targetRotation;
+ const qreal rotation = OneDegree * percentageComplete * -TargetRotation;
startAngle -= rotation;
endAngle -= rotation;
const int angleSpan = endAngle - startAngle;
painter.drawArc(arcBounds, -startAngle, -angleSpan);
painter.end();
+ textureNode->setRect(QRectF(dx, dy, size, size));
textureNode->setTexture(m_window->createTextureFromImage(image));
}
-void QQuickMaterialRingAnimatorJob::writeBack()
+void QQuickMaterialBusyIndicatorNode::sync(QQuickMaterialBusyIndicator *item)
{
+ m_color = item->color();
+ m_width = item->width();
+ m_height = item->height();
+ m_devicePixelRatio = m_window->effectiveDevicePixelRatio();
}
-void QQuickMaterialRingAnimatorJob::nodeWasDestroyed()
+QQuickMaterialBusyIndicator::QQuickMaterialBusyIndicator(QQuickItem *parent) :
+ QQuickItem(parent)
{
- m_containerNode = nullptr;
- m_window = nullptr;
+ setFlag(ItemHasContents);
}
-void QQuickMaterialRingAnimatorJob::afterNodeSync()
+QColor QQuickMaterialBusyIndicator::color() const
{
- m_containerNode = QQuickItemPrivate::get(m_target)->childContainerNode();
- m_color = static_cast<QQuickMaterialProgressRing *>(m_target.data())->color();
+ return m_color;
+}
+
+void QQuickMaterialBusyIndicator::setColor(QColor color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ update();
+}
+
+int QQuickMaterialBusyIndicator::elapsed() const
+{
+ return m_elapsed;
+}
+
+void QQuickMaterialBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickMaterialBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QQuickMaterialBusyIndicatorNode *node = static_cast<QQuickMaterialBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickMaterialBusyIndicatorNode(this);
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->elapsed() : 0;
+ delete node;
+ node = nullptr;
+ }
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialprogressring_p.h b/src/imports/controls/material/qquickmaterialbusyindicator_p.h
index 8d6cd578..4772d164 100644
--- a/src/imports/controls/material/qquickmaterialprogressring_p.h
+++ b/src/imports/controls/material/qquickmaterialbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKMATERIALPROGRESSRING_P_H
-#define QQUICKMATERIALPROGRESSRING_P_H
+#ifndef QQUICKMATERIALBUSYINDICATOR_P_H
+#define QQUICKMATERIALBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -50,44 +50,33 @@
#include <QtGui/qcolor.h>
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickMaterialProgressRing : public QQuickItem
+class QQuickMaterialBusyIndicator : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
+ Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
public:
- explicit QQuickMaterialProgressRing(QQuickItem *parent = nullptr);
- ~QQuickMaterialProgressRing();
+ explicit QQuickMaterialBusyIndicator(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(QColor color);
-Q_SIGNALS:
- void colorChanged();
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
+ int m_elapsed;
QColor m_color;
};
-class QQuickMaterialRingAnimator : public QQuickAnimator
-{
-public:
- QQuickMaterialRingAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickMaterialProgressRing)
+QML_DECLARE_TYPE(QQuickMaterialBusyIndicator)
-#endif // QQUICKMATERIALPROGRESSRING_P_H
+#endif // QQUICKMATERIALBUSYINDICATOR_P_H
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip.cpp b/src/imports/controls/material/qquickmaterialprogressbar.cpp
index 542d312f..36b18781 100644
--- a/src/imports/controls/material/qquickmaterialprogressstrip.cpp
+++ b/src/imports/controls/material/qquickmaterialprogressbar.cpp
@@ -34,12 +34,12 @@
**
****************************************************************************/
-#include "qquickmaterialprogressstrip_p.h"
+#include "qquickmaterialprogressbar_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgrectanglenode.h>
#include <QtQuick/qsgimagenode.h>
@@ -50,43 +50,36 @@ static const int PauseDuration = 520;
static const int SlideDuration = 1240;
static const int TotalDuration = SlideDuration + PauseDuration;
-class QQuickMaterialProgressStripAnimatorJob : public QQuickAnimatorJob
+class QQuickMaterialProgressBarNode : public QObject, public QSGNode
{
public:
- QQuickMaterialProgressStripAnimatorJob();
+ QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *item);
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void animate();
+ void sync(QQuickMaterialProgressBar *item);
+private:
void moveNode(QSGTransformNode *node, const QRectF &geometry, qreal progress);
-private:
- QSGNode *m_node;
+ bool m_indeterminate;
+ QElapsedTimer m_timer;
+ QEasingCurve m_easing;
};
-QQuickMaterialProgressStripAnimatorJob::QQuickMaterialProgressStripAnimatorJob() : m_node(nullptr)
-{
-}
-
-void QQuickMaterialProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller)
+QQuickMaterialProgressBarNode::QQuickMaterialProgressBarNode(QQuickMaterialProgressBar *)
+ : m_indeterminate(false), m_easing(QEasingCurve::OutCubic)
{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ m_timer.start();
}
-void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time)
+void QQuickMaterialProgressBarNode::animate()
{
- if (!m_node)
- return;
-
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
- Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
- if (!geometryNode)
- return;
+ qint64 time = m_timer.elapsed();
+ if (time >= TotalDuration)
+ m_timer.restart();
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ Q_ASSERT(geometryNode->type() == QSGNode::GeometryNodeType);
const QRectF geometry = geometryNode->rect();
QSGTransformNode *firstNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
@@ -106,21 +99,69 @@ void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickMaterialProgressStripAnimatorJob::writeBack()
+void QQuickMaterialProgressBarNode::sync(QQuickMaterialProgressBar *item)
{
-}
+ if (m_indeterminate != item->isIndeterminate()) {
+ m_indeterminate = item->isIndeterminate();
+ QQuickWindow *window = item->window();
+ if (m_indeterminate) {
+ connect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeRendering, this, &QQuickMaterialProgressBarNode::animate);
+ } else {
+ disconnect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ disconnect(window, &QQuickWindow::beforeRendering, this, &QQuickMaterialProgressBarNode::animate);
+ }
+ }
-void QQuickMaterialProgressStripAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
-void QQuickMaterialProgressStripAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ QRectF bounds = item->boundingRect();
+ bounds.setHeight(item->implicitHeight());
+ bounds.moveTop((item->height() - bounds.height()) / 2.0);
+
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ if (!geometryNode) {
+ geometryNode = item->window()->createRectangleNode();
+ geometryNode->setColor(Qt::transparent);
+ appendChildNode(geometryNode);
+ }
+ geometryNode->setRect(bounds);
+
+ const int count = m_indeterminate ? 2 : 1;
+ const qreal w = m_indeterminate ? 0 : item->progress() * item->width();
+ const QRectF rect(0, bounds.y(), w, bounds.height());
+
+ QSGNode *transformNode = geometryNode->firstChild();
+ for (int i = 0; i < count; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ geometryNode->appendChildNode(transformNode);
+
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ transformNode->appendChildNode(rectNode);
+ }
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+ static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4());
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ rectNode->setRect(rect);
+ rectNode->setColor(item->color());
+ rectNode->update();
+
+ transformNode = transformNode->nextSibling();
+ }
+
+ while (transformNode) {
+ QSGNode *nextSibling = transformNode->nextSibling();
+ delete transformNode;
+ transformNode = nextSibling;
+ }
}
-void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
+void QQuickMaterialProgressBarNode::moveNode(QSGTransformNode *transformNode, const QRectF &geometry, qreal progress)
{
const qreal value = m_easing.valueForProgress(progress);
const qreal x = value * geometry.width();
@@ -138,36 +179,18 @@ void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transfor
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)
+QQuickMaterialProgressBar::QQuickMaterialProgressBar(QQuickItem *parent)
: QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
{
setFlag(ItemHasContents);
}
-QColor QQuickMaterialProgressStrip::color() const
+QColor QQuickMaterialProgressBar::color() const
{
return m_color;
}
-void QQuickMaterialProgressStrip::setColor(const QColor &color)
+void QQuickMaterialProgressBar::setColor(const QColor &color)
{
if (color == m_color)
return;
@@ -176,12 +199,12 @@ void QQuickMaterialProgressStrip::setColor(const QColor &color)
update();
}
-qreal QQuickMaterialProgressStrip::progress() const
+qreal QQuickMaterialProgressBar::progress() const
{
return m_progress;
}
-void QQuickMaterialProgressStrip::setProgress(qreal progress)
+void QQuickMaterialProgressBar::setProgress(qreal progress)
{
if (progress == m_progress)
return;
@@ -190,12 +213,12 @@ void QQuickMaterialProgressStrip::setProgress(qreal progress)
update();
}
-bool QQuickMaterialProgressStrip::isIndeterminate() const
+bool QQuickMaterialProgressBar::isIndeterminate() const
{
return m_indeterminate;
}
-void QQuickMaterialProgressStrip::setIndeterminate(bool indeterminate)
+void QQuickMaterialProgressBar::setIndeterminate(bool indeterminate)
{
if (indeterminate == m_indeterminate)
return;
@@ -204,54 +227,25 @@ void QQuickMaterialProgressStrip::setIndeterminate(bool indeterminate)
update();
}
-QSGNode *QQuickMaterialProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+void QQuickMaterialProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- QRectF bounds = boundingRect();
- bounds.setHeight(implicitHeight());
- bounds.moveTop((height() - bounds.height()) / 2.0);
-
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(oldNode)->setRect(bounds);
-
- const int count = m_indeterminate ? 2 : 1;
- const qreal w = m_indeterminate ? 0 : m_progress * width();
- const QRectF rect(0, bounds.y(), w, bounds.height());
-
- QSGNode *transformNode = oldNode->firstChild();
- for (int i = 0; i < count; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- oldNode->appendChildNode(transformNode);
-
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- transformNode->appendChildNode(rectNode);
- }
- Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
- static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4());
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- rectNode->setRect(rect);
- rectNode->setColor(m_color);
- rectNode->update();
-
- transformNode = transformNode->nextSibling();
- }
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
- while (transformNode) {
- QSGNode *nextSibling = transformNode->nextSibling();
- delete transformNode;
- transformNode = nextSibling;
+QSGNode *QQuickMaterialProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickMaterialProgressBarNode *node = static_cast<QQuickMaterialProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickMaterialProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
}
-
- return oldNode;
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/material/qquickmaterialprogressstrip_p.h b/src/imports/controls/material/qquickmaterialprogressbar_p.h
index f441c09d..0b0b576f 100644
--- a/src/imports/controls/material/qquickmaterialprogressstrip_p.h
+++ b/src/imports/controls/material/qquickmaterialprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKMATERIALPROGRESSSTRIP_P_H
-#define QQUICKMATERIALPROGRESSSTRIP_P_H
+#ifndef QQUICKMATERIALPROGRESSBAR_P_H
+#define QQUICKMATERIALPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,11 +49,10 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickMaterialProgressStrip : public QQuickItem
+class QQuickMaterialProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
@@ -61,7 +60,7 @@ class QQuickMaterialProgressStrip : public QQuickItem
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL)
public:
- QQuickMaterialProgressStrip(QQuickItem *parent = nullptr);
+ explicit QQuickMaterialProgressBar(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
@@ -73,6 +72,7 @@ public:
void setIndeterminate(bool indeterminate);
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,21 +81,8 @@ private:
bool m_indeterminate;
};
-class QQuickMaterialStripAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickMaterialStripAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickMaterialProgressStrip)
-QML_DECLARE_TYPE(QQuickMaterialStripAnimator)
+QML_DECLARE_TYPE(QQuickMaterialProgressBar)
-#endif // QQUICKMATERIALPROGRESSSTRIP_P_H
+#endif // QQUICKMATERIALPROGRESSBAR_P_H
diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
index 27d2c5a6..bf617488 100644
--- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
+++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp
@@ -38,8 +38,8 @@
#include "qquickmaterialstyle_p.h"
#include "qquickmaterialtheme_p.h"
-#include "qquickmaterialprogressring_p.h"
-#include "qquickmaterialprogressstrip_p.h"
+#include "qquickmaterialbusyindicator_p.h"
+#include "qquickmaterialprogressbar_p.h"
#include "qquickmaterialripple_p.h"
#include <QtQuickControls2/private/qquickstyleselector_p.h>
@@ -91,11 +91,9 @@ void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, c
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterType<QQuickPaddedRectangle>(import, 2, 0, "PaddedRectangle");
qmlRegisterRevision<QQuickPaddedRectangle, 1>(import, 2, 1);
- qmlRegisterType<QQuickMaterialProgressRing>(import, 2, 0, "ProgressRing");
- qmlRegisterType<QQuickMaterialProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickMaterialRingAnimator>(import, 2, 0, "RingAnimator");
+ qmlRegisterType<QQuickMaterialBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickMaterialProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterType<QQuickMaterialRipple>(import, 2, 0, "Ripple");
- qmlRegisterType<QQuickMaterialStripAnimator>(import, 2, 0, "StripAnimator");
qmlRegisterType(typeUrl(QStringLiteral("BoxShadow.qml")), import, 2, 0, "BoxShadow");
qmlRegisterType(typeUrl(QStringLiteral("CheckIndicator.qml")), import, 2, 0, "CheckIndicator");
qmlRegisterType(typeUrl(QStringLiteral("ElevationEffect.qml")), import, 2, 0, "ElevationEffect");
diff --git a/src/imports/controls/qquickbusyindicatorring.cpp b/src/imports/controls/qquickbusyindicatorring.cpp
deleted file mode 100644
index d8c035d2..00000000
--- a/src/imports/controls/qquickbusyindicatorring.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Quick Controls 2 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/qsgnode.h>
-#include <QtQuick/qquickwindow.h>
-#include <QtQuick/qsgrectanglenode.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickBusyIndicatorAnimatorJob : public QQuickAnimatorJob
-{
-public:
- QQuickBusyIndicatorAnimatorJob();
- ~QQuickBusyIndicatorAnimatorJob();
-
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
-
-private:
- QSGNode *m_node;
-};
-
-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 = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(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;
- const QColor color(0x35, 0x36, 0x37);
-
- 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);
-
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- rectNode->setColor(color);
- rectNode->setPenColor(color);
- opacityNode->appendChildNode(rectNode);
- }
-
- QSGNode *opacityNode = transformNode->firstChild();
- Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(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() : m_node(nullptr)
-{
-}
-
-QQuickBusyIndicatorAnimatorJob::~QQuickBusyIndicatorAnimatorJob()
-{
-}
-
-void QQuickBusyIndicatorAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickBusyIndicatorAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_node)
- return;
-
- QSGRectangleNode *rootRectNode = static_cast<QSGRectangleNode *>(m_node->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());
- const QColor color(0x35, 0x36, 0x37);
- const QColor transparent(Qt::transparent);
- 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);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(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 ? color : transparent);
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
- }
-}
-
-void QQuickBusyIndicatorAnimatorJob::writeBack()
-{
-}
-
-void QQuickBusyIndicatorAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-void QQuickBusyIndicatorAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickdefaultbusyindicator.cpp b/src/imports/controls/qquickdefaultbusyindicator.cpp
new file mode 100644
index 00000000..5b952476
--- /dev/null
+++ b/src/imports/controls/qquickdefaultbusyindicator.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 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 "qquickdefaultbusyindicator_p.h"
+
+#include <QtCore/qset.h>
+#include <QtCore/qelapsedtimer.h>
+#include <QtGui/qpainter.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgnode.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int CircleCount = 10;
+static const int TotalDuration = 100 * CircleCount * 2;
+static const QRgb TransparentColor = 0x00000000;
+static const QRgb FillColor = 0xFF353637;
+
+static QPointF moveCircle(const QPointF &pos, qreal rotation, qreal distance)
+{
+ return pos - QTransform().rotate(rotation).map(QPointF(0, distance));
+}
+
+class QQuickDefaultBusyIndicatorNode : public QObject, public QSGNode
+{
+public:
+ QQuickDefaultBusyIndicatorNode(QQuickDefaultBusyIndicator *item);
+
+ int elapsed() const;
+
+ void animate();
+ void sync(QQuickDefaultBusyIndicator *item);
+
+private:
+ int m_offset;
+ QElapsedTimer m_timer;
+};
+
+QQuickDefaultBusyIndicatorNode::QQuickDefaultBusyIndicatorNode(QQuickDefaultBusyIndicator *item)
+ : m_offset(item->elapsed())
+{
+ QQuickWindow *window = item->window();
+ connect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeRendering, this, &QQuickDefaultBusyIndicatorNode::animate);
+
+ for (int i = 0; i < CircleCount; ++i) {
+ QSGTransformNode *transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ transformNode->appendChildNode(rectNode);
+ }
+
+ m_timer.restart();
+}
+
+int QQuickDefaultBusyIndicatorNode::elapsed() const
+{
+ return m_timer.elapsed() + m_offset;
+}
+
+void QQuickDefaultBusyIndicatorNode::animate()
+{
+ qint64 time = m_timer.elapsed() + m_offset;
+ if (time >= TotalDuration) {
+ m_timer.restart();
+ m_offset = 0;
+ }
+
+ const qreal percentageComplete = time / qreal(TotalDuration);
+ 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*>(firstChild());
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+ for (int i = 0; i < CircleCount; ++i) {
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ const bool fill = (firstPhaseProgress > qreal(i) / CircleCount) || (secondPhaseProgress > 0 && secondPhaseProgress < qreal(i) / CircleCount);
+ rectNode->setColor(QColor::fromRgba(fill ? FillColor : TransparentColor));
+ rectNode->setPenWidth(fill ? 0 : 1);
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
+ }
+}
+
+void QQuickDefaultBusyIndicatorNode::sync(QQuickDefaultBusyIndicator *item)
+{
+ const qreal w = item->width();
+ const qreal h = item->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 *>(firstChild());
+ for (int i = 0; i < CircleCount; ++i) {
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ QPointF pos = QPointF(sz / 2 - circleRadius, sz / 2 - circleRadius);
+ pos = moveCircle(pos, 360 / CircleCount * 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);
+
+ transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
+ }
+}
+
+QQuickDefaultBusyIndicator::QQuickDefaultBusyIndicator(QQuickItem *parent) :
+ QQuickItem(parent), m_elapsed(0)
+{
+ setFlag(ItemHasContents);
+}
+
+int QQuickDefaultBusyIndicator::elapsed() const
+{
+ return m_elapsed;
+}
+
+void QQuickDefaultBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickDefaultBusyIndicator::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickDefaultBusyIndicatorNode *node = static_cast<QQuickDefaultBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickDefaultBusyIndicatorNode(this);
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->elapsed() : 0;
+ delete node;
+ node = nullptr;
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickbusyindicatorring_p.h b/src/imports/controls/qquickdefaultbusyindicator_p.h
index ceac0471..6147b8e3 100644
--- a/src/imports/controls/qquickbusyindicatorring_p.h
+++ b/src/imports/controls/qquickdefaultbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKBUSYINDICATORRING_P_H
-#define QQUICKBUSYINDICATORRING_P_H
+#ifndef QQUICKDEFAULTBUSYINDICATOR_P_H
+#define QQUICKDEFAULTBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -49,34 +49,28 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickBusyIndicatorRing : public QQuickItem
+class QQuickDefaultBusyIndicator : public QQuickItem
{
Q_OBJECT
public:
- explicit QQuickBusyIndicatorRing(QQuickItem *parent = nullptr);
- ~QQuickBusyIndicatorRing();
+ explicit QQuickDefaultBusyIndicator(QQuickItem *parent = nullptr);
+
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
-};
-
-class QQuickBusyIndicatorAnimator : public QQuickAnimator
-{
-public:
- QQuickBusyIndicatorAnimator(QObject *parent = nullptr);
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
+private:
+ int m_elapsed;
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickBusyIndicatorRing)
+QML_DECLARE_TYPE(QQuickDefaultBusyIndicator)
-#endif // QQUICKBUSYINDICATORRING_P_H
+#endif // QQUICKDEFAULTBUSYINDICATOR_P_H
diff --git a/src/imports/controls/qquickdefaultprogressbar.cpp b/src/imports/controls/qquickdefaultprogressbar.cpp
new file mode 100644
index 00000000..a626bb32
--- /dev/null
+++ b/src/imports/controls/qquickdefaultprogressbar.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls 2 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 "qquickdefaultprogressbar_p.h"
+
+#include <QtCore/qeasingcurve.h>
+#include <QtCore/qelapsedtimer.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qsgadaptationlayer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int Blocks = 4;
+static const int BlockWidth = 16;
+static const int BlockRestingSpacing = 4;
+static const int BlockMovingSpacing = 48;
+static const int BlockSpan = Blocks * (BlockWidth + BlockRestingSpacing) - BlockRestingSpacing;
+static const int TotalDuration = 4000;
+static const int SecondPhaseStart = TotalDuration * 0.4;
+static const int ThirdPhaseStart = TotalDuration * 0.6;
+static const QRgb FillColor = 0x353637;
+
+static inline qreal blockStartX(int blockIndex)
+{
+ return ((blockIndex + 1) * -BlockWidth) - (blockIndex * BlockMovingSpacing);
+}
+
+static inline qreal blockRestX(int blockIndex, qreal availableWidth)
+{
+ const qreal spanRightEdgePos = availableWidth / 2 + BlockSpan / 2;
+ return spanRightEdgePos - (blockIndex + 1) * BlockWidth - (blockIndex * BlockRestingSpacing);
+}
+
+static inline qreal blockEndX(int blockIndex, qreal availableWidth)
+{
+ return availableWidth - blockStartX(Blocks - 1 - blockIndex) - BlockWidth;
+}
+
+class QQuickDefaultProgressBarNode : public QObject, public QSGTransformNode
+{
+public:
+ QQuickDefaultProgressBarNode(QQuickDefaultProgressBar *item);
+
+ void animate();
+ void sync(QQuickDefaultProgressBar *item);
+
+private:
+ bool m_indeterminate;
+ qreal m_pixelsPerSecond;
+ QElapsedTimer m_timer;
+};
+
+QQuickDefaultProgressBarNode::QQuickDefaultProgressBarNode(QQuickDefaultProgressBar *item)
+ : m_indeterminate(false), m_pixelsPerSecond(item->width())
+{
+ m_timer.start();
+}
+
+void QQuickDefaultProgressBarNode::animate()
+{
+ qint64 time = m_timer.elapsed();
+ if (time >= TotalDuration)
+ m_timer.restart();
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild());
+ for (int i = 0; i < Blocks; ++i) {
+ Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
+
+ QMatrix4x4 m;
+ const qreal restX = blockRestX(i, m_pixelsPerSecond);
+ const qreal timeInSeconds = time / 1000.0;
+
+ if (time < SecondPhaseStart) {
+ // Move into the resting position for the first phase.
+ QEasingCurve easingCurve(QEasingCurve::InQuad);
+ const qreal easedCompletion = easingCurve.valueForProgress(time / qreal(SecondPhaseStart));
+ const qreal distance = m_pixelsPerSecond * (easedCompletion * (SecondPhaseStart / 1000.0));
+ const qreal position = blockStartX(i) + distance;
+ const qreal destination = restX;
+ m.translate(qMin(position, destination), 0);
+ } else if (time < ThirdPhaseStart) {
+ // Stay in the same position for the second phase.
+ m.translate(restX, 0);
+ } else {
+ // Move out of view for the third phase.
+ const int thirdPhaseSubKickoff = (BlockMovingSpacing / m_pixelsPerSecond) * 1000;
+ const int subphase = (time - ThirdPhaseStart) / thirdPhaseSubKickoff;
+ // If we're not at this subphase yet, don't try to animate movement,
+ // because it will be incorrect.
+ if (subphase < i)
+ return;
+
+ const qreal timeSinceSecondPhase = timeInSeconds - (ThirdPhaseStart / 1000.0);
+ // We only want to start keeping track of time once our subphase has started,
+ // otherwise we move too much because we account for time that has already elapsed.
+ // For example, if we were 60 milliseconds into the third subphase:
+ //
+ // 0 ..... 1 ..... 2 ...
+ // 100 100 60
+ //
+ // i == 0, timeSinceOurKickoff == 260
+ // i == 1, timeSinceOurKickoff == 160
+ // i == 2, timeSinceOurKickoff == 60
+ const qreal timeSinceOurKickoff = timeSinceSecondPhase - (thirdPhaseSubKickoff / 1000.0 * i);
+ const qreal position = restX + (m_pixelsPerSecond * (timeSinceOurKickoff));
+ const qreal destination = blockEndX(i, m_pixelsPerSecond);
+ m.translate(qMin(position, destination), 0);
+ }
+
+ transformNode->setMatrix(m);
+
+ transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
+ }
+}
+
+void QQuickDefaultProgressBarNode::sync(QQuickDefaultProgressBar *item)
+{
+ m_pixelsPerSecond = item->width();
+ if (m_indeterminate != item->isIndeterminate()) {
+ m_indeterminate = item->isIndeterminate();
+ QQuickWindow *window = item->window();
+ if (m_indeterminate) {
+ connect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeRendering, this, &QQuickDefaultProgressBarNode::animate);
+ } else {
+ disconnect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ disconnect(window, &QQuickWindow::beforeRendering, this, &QQuickDefaultProgressBarNode::animate);
+ }
+ }
+
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
+
+ QMatrix4x4 m;
+ m.translate(0, (item->height() - item->implicitHeight()) / 2);
+ setMatrix(m);
+
+ if (item->isIndeterminate()) {
+ if (childCount() != Blocks) {
+ // This was previously a regular progress bar; remove the old nodes.
+ removeAllChildNodes();
+ }
+
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(firstChild());
+ for (int i = 0; i < Blocks; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
+ }
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
+ if (!rectNode) {
+ rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setColor(FillColor);
+ transformNode->appendChildNode(rectNode);
+ }
+
+ QMatrix4x4 m;
+ m.translate(blockStartX(i), 0);
+ transformNode->setMatrix(m);
+
+ rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(BlockWidth, item->implicitHeight())));
+ rectNode->update();
+
+ transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
+ }
+ } else {
+ if (childCount() > 1) {
+ // This was previously an indeterminate progress bar; remove the old nodes.
+ removeAllChildNodes();
+ }
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(firstChild());
+ if (!rectNode) {
+ rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setColor(FillColor);
+ appendChildNode(rectNode);
+ }
+
+ rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(item->progress() * item->width(), item->implicitHeight())));
+ rectNode->update();
+ }
+}
+
+QQuickDefaultProgressBar::QQuickDefaultProgressBar(QQuickItem *parent) :
+ QQuickItem(parent),
+ m_progress(0),
+ m_indeterminate(false)
+{
+ setFlag(ItemHasContents);
+}
+
+qreal QQuickDefaultProgressBar::progress() const
+{
+ return m_progress;
+}
+
+void QQuickDefaultProgressBar::setProgress(qreal progress)
+{
+ if (progress == m_progress)
+ return;
+
+ m_progress = progress;
+ update();
+ emit progressChanged();
+}
+
+bool QQuickDefaultProgressBar::isIndeterminate() const
+{
+ return m_indeterminate;
+}
+
+void QQuickDefaultProgressBar::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate == m_indeterminate)
+ return;
+
+ m_indeterminate = indeterminate;
+ setClip(m_indeterminate);
+ update();
+ emit indeterminateChanged();
+}
+
+void QQuickDefaultProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickDefaultProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickDefaultProgressBarNode *node = static_cast<QQuickDefaultProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickDefaultProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/controls/qquickprogressstrip_p.h b/src/imports/controls/qquickdefaultprogressbar_p.h
index d2e297f5..ec228eee 100644
--- a/src/imports/controls/qquickprogressstrip_p.h
+++ b/src/imports/controls/qquickdefaultprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKPROGRESSSTRIP_P_H
-#define QQUICKPROGRESSSTRIP_P_H
+#ifndef QQUICKDEFAULTPROGRESSBAR_P_H
+#define QQUICKDEFAULTPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,19 +49,17 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
QT_BEGIN_NAMESPACE
-class QQuickProgressStrip : public QQuickItem
+class QQuickDefaultProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate NOTIFY indeterminateChanged FINAL)
Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged FINAL)
public:
- explicit QQuickProgressStrip(QQuickItem *parent = nullptr);
- ~QQuickProgressStrip();
+ explicit QQuickDefaultProgressBar(QQuickItem *parent = nullptr);
bool isIndeterminate() const;
void setIndeterminate(bool indeterminate);
@@ -74,6 +72,7 @@ Q_SIGNALS:
void indeterminateChanged();
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,16 +80,8 @@ private:
bool m_indeterminate;
};
-class QQuickProgressAnimator : public QQuickAnimator
-{
-public:
- QQuickProgressAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-#endif // QQUICKPROGRESSSTRIP_P_H
+QML_DECLARE_TYPE(QQuickDefaultProgressBar)
+
+#endif // QQUICKDEFAULTPROGRESSBAR_P_H
diff --git a/src/imports/controls/qquickprogressstrip.cpp b/src/imports/controls/qquickprogressstrip.cpp
deleted file mode 100644
index 33a21848..00000000
--- a/src/imports/controls/qquickprogressstrip.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Quick Controls 2 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 "qquickprogressstrip_p.h"
-
-#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/qsgrectanglenode.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickProgressAnimatorJob : public QQuickAnimatorJob
-{
-public:
- QQuickProgressAnimatorJob();
- ~QQuickProgressAnimatorJob();
-
- void initialize(QQuickAnimatorController *controller) override;
- void afterNodeSync() override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
-
-private:
- QSGNode *m_node;
-};
-
-QQuickProgressStrip::QQuickProgressStrip(QQuickItem *parent) :
- QQuickItem(parent),
- m_progress(0),
- m_indeterminate(false)
-{
- setFlag(QQuickItem::ItemHasContents);
-}
-
-QQuickProgressStrip::~QQuickProgressStrip()
-{
-}
-
-qreal QQuickProgressStrip::progress() const
-{
- return m_progress;
-}
-
-void QQuickProgressStrip::setProgress(qreal progress)
-{
- if (progress == m_progress)
- return;
-
- m_progress = progress;
- update();
- emit progressChanged();
-}
-
-bool QQuickProgressStrip::isIndeterminate() const
-{
- return m_indeterminate;
-}
-
-void QQuickProgressStrip::setIndeterminate(bool indeterminate)
-{
- if (indeterminate == m_indeterminate)
- return;
-
- m_indeterminate = indeterminate;
- setClip(m_indeterminate);
- update();
- emit indeterminateChanged();
-}
-
-static const int blocks = 4;
-static const int blockWidth = 16;
-static const int blockRestingSpacing = 4;
-static const int blockMovingSpacing = 48;
-static const int blockSpan = blocks * (blockWidth + blockRestingSpacing) - blockRestingSpacing;
-static const int animationDuration = 4000;
-static const int secondPhaseStart = animationDuration * 0.4;
-static const int thirdPhaseStart = animationDuration * 0.6;
-
-static inline qreal blockStartX(int blockIndex)
-{
- return ((blockIndex + 1) * -blockWidth) - (blockIndex * blockMovingSpacing);
-}
-
-static inline qreal blockRestX(int blockIndex, qreal availableWidth)
-{
- const qreal spanRightEdgePos = availableWidth / 2 + blockSpan / 2;
- return spanRightEdgePos - (blockIndex + 1) * blockWidth - (blockIndex * blockRestingSpacing);
-}
-
-static inline qreal blockEndX(int blockIndex, qreal availableWidth)
-{
- return availableWidth - blockStartX(blocks - 1 - blockIndex) - blockWidth;
-}
-
-QSGNode *QQuickProgressStrip::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
-{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- if (!oldNode) {
- oldNode = window()->createRectangleNode();
- static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent);
- }
- static_cast<QSGRectangleNode *>(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 y = (height() - implicitHeight()) / 2;
- const QColor color(0x35, 0x36, 0x37);
- if (m_indeterminate) {
- if (rootTransformNode->childCount() != blocks) {
- // This was previously a regular progress bar; remove the old nodes.
- rootTransformNode->removeAllChildNodes();
- }
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
- for (int i = 0; i < blocks; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- rootTransformNode->appendChildNode(transformNode);
- }
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
- if (!rectNode) {
- rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setColor(color);
- transformNode->appendChildNode(rectNode);
- }
-
- QMatrix4x4 m;
- m.translate(blockStartX(i), 0);
- transformNode->setMatrix(m);
-
- rectNode->setRect(QRectF(QPointF(0, y), QSizeF(blockWidth, implicitHeight())));
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling());
- }
- } else {
- if (rootTransformNode->childCount() > 1) {
- // This was previously an indeterminate progress bar; remove the old nodes.
- rootTransformNode->removeAllChildNodes();
- }
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(rootTransformNode->firstChild());
- if (!rectNode) {
- rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setColor(color);
- rootTransformNode->appendChildNode(rectNode);
- }
-
- rectNode->setRect(QRectF(QPointF(0, y), QSizeF(m_progress * width(), implicitHeight())));
- rectNode->update();
- }
-
- return oldNode;
-}
-
-QQuickProgressAnimator::QQuickProgressAnimator(QObject *parent) :
- QQuickAnimator(parent)
-{
- setDuration(animationDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickProgressAnimator::propertyName() const
-{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickProgressAnimator::createJob() const
-{
- return new QQuickProgressAnimatorJob;
-}
-
-QQuickProgressAnimatorJob::QQuickProgressAnimatorJob() :
- m_node(nullptr)
-{
-}
-
-QQuickProgressAnimatorJob::~QQuickProgressAnimatorJob()
-{
-}
-
-void QQuickProgressAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickProgressAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-void QQuickProgressAnimatorJob::updateCurrentTime(int time)
-{
- if (!m_node)
- return;
-
- QSGRectangleNode *rootRectNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
- if (!rootRectNode)
- return;
- Q_ASSERT(rootRectNode->type() == QSGNode::GeometryNodeType);
-
- QSGTransformNode *rootTransformNode = static_cast<QSGTransformNode*>(rootRectNode->firstChild());
- Q_ASSERT(rootTransformNode->type() == QSGNode::TransformNodeType);
-
- QSGTransformNode *transformNode = static_cast<QSGTransformNode*>(rootTransformNode->firstChild());
- // This function can be called without the relevant nodes having been created yet,
- // which can happen if you set indeterminate to true at runtime.
- if (!transformNode || transformNode->type() != QSGNode::TransformNodeType)
- return;
-
- const qreal pixelsPerSecond = rootRectNode->rect().width();
-
- for (int i = 0; i < blocks; ++i) {
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode*>(transformNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- QMatrix4x4 m;
- const qreal restX = blockRestX(i, rootRectNode->rect().width());
- const qreal timeInSeconds = time / 1000.0;
-
- if (time < secondPhaseStart) {
- // Move into the resting position for the first phase.
- QEasingCurve easingCurve(QEasingCurve::InQuad);
- const qreal easedCompletion = easingCurve.valueForProgress(time / qreal(secondPhaseStart));
- const qreal distance = pixelsPerSecond * (easedCompletion * (secondPhaseStart / 1000.0));
- const qreal position = blockStartX(i) + distance;
- const qreal destination = restX;
- m.translate(qMin(position, destination), 0);
- } else if (time < thirdPhaseStart) {
- // Stay in the same position for the second phase.
- m.translate(restX, 0);
- } else {
- // Move out of view for the third phase.
- const int thirdPhaseSubKickoff = (blockMovingSpacing / pixelsPerSecond) * 1000;
- const int subphase = (time - thirdPhaseStart) / thirdPhaseSubKickoff;
- // If we're not at this subphase yet, don't try to animate movement,
- // because it will be incorrect.
- if (subphase < i)
- return;
-
- const qreal timeSinceSecondPhase = timeInSeconds - (thirdPhaseStart / 1000.0);
- // We only want to start keeping track of time once our subphase has started,
- // otherwise we move too much because we account for time that has already elapsed.
- // For example, if we were 60 milliseconds into the third subphase:
- //
- // 0 ..... 1 ..... 2 ...
- // 100 100 60
- //
- // i == 0, timeSinceOurKickoff == 260
- // i == 1, timeSinceOurKickoff == 160
- // i == 2, timeSinceOurKickoff == 60
- const qreal timeSinceOurKickoff = timeSinceSecondPhase - (thirdPhaseSubKickoff / 1000.0 * i);
- const qreal position = restX + (pixelsPerSecond * (timeSinceOurKickoff));
- const qreal destination = blockEndX(i, rootRectNode->rect().width());
- m.translate(qMin(position, destination), 0);
- }
-
- transformNode->setMatrix(m);
- rectNode->update();
-
- transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling());
- }
-}
-
-void QQuickProgressAnimatorJob::writeBack()
-{
-}
-
-void QQuickProgressAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index 5b8868fe..6802171f 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -41,12 +41,16 @@
#include <QtQuickControls2/private/qquickstyleselector_p.h>
#include <QtQuickControls2/private/qquickcolorimageprovider_p.h>
#include <QtQuickTemplates2/private/qquickbuttongroup_p.h>
+#include <QtQuickTemplates2/private/qquickdial_p.h>
+#include <QtQuickTemplates2/private/qquickrangeslider_p.h>
+#include <QtQuickTemplates2/private/qquickslider_p.h>
+#include <QtQuickTemplates2/private/qquicktumbler_p.h>
#include <QtQuickControls2/private/qquicktumblerview_p.h>
-#include "qquickbusyindicatorring_p.h"
+#include "qquickdefaultbusyindicator_p.h"
+#include "qquickdefaultprogressbar_p.h"
#include "qquickdefaultstyle_p.h"
#include "qquickdialring_p.h"
-#include "qquickprogressstrip_p.h"
static inline void initResources()
{
@@ -137,6 +141,12 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
qmlRegisterType(selector.select(QStringLiteral("MenuSeparator.qml")), uri, 2, 1, "MenuSeparator");
qmlRegisterType(selector.select(QStringLiteral("RoundButton.qml")), uri, 2, 1, "RoundButton");
qmlRegisterType(selector.select(QStringLiteral("ToolSeparator.qml")), uri, 2, 1, "ToolSeparator");
+
+ // QtQuick.Controls 2.2 (Qt 5.9)
+ qmlRegisterRevision<QQuickDial, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickRangeSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickTumbler, 2>(uri, 2, 2);
}
static QObject *styleSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -153,10 +163,8 @@ void QtQuickControls2Plugin::initializeEngine(QQmlEngine *engine, const char *ur
engine->addImageProvider(QStringLiteral("default"), new QQuickColorImageProvider(QStringLiteral(":/qt-project.org/imports/QtQuick/Controls.2/images")));
const QByteArray import = QByteArray(uri) + ".impl";
- qmlRegisterType<QQuickBusyIndicatorRing>(import, 2, 0, "BusyRing");
- qmlRegisterType<QQuickBusyIndicatorAnimator>(import, 2, 0, "BusyRingAnimator");
- qmlRegisterType<QQuickProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickProgressAnimator>(import, 2, 0, "ProgressStripAnimator");
+ qmlRegisterType<QQuickDefaultBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickDefaultProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterType<QQuickDialRing>(import, 2, 0, "DialRing");
qmlRegisterType<QQuickTumblerView>(import, 2, 1, "TumblerView");
qmlRegisterSingletonType<QQuickDefaultStyle>(import, 2, 1, "Default", styleSingleton);
diff --git a/src/imports/controls/universal/BusyIndicator.qml b/src/imports/controls/universal/BusyIndicator.qml
index 514a233e..180396f2 100644
--- a/src/imports/controls/universal/BusyIndicator.qml
+++ b/src/imports/controls/universal/BusyIndicator.qml
@@ -45,9 +45,7 @@ T.BusyIndicator {
implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding
implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding
- contentItem: ProgressRing {
- id: ring
-
+ contentItem: BusyIndicatorImpl {
implicitWidth: 20
implicitHeight: 20
@@ -55,10 +53,6 @@ T.BusyIndicator {
count: size < 60 ? 5 : 6 // "Small" vs. "Large"
color: control.Universal.accent
-
- ProgressRingAnimator {
- target: ring
- running: control.visible && control.running
- }
+ visible: control.running
}
}
diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml
index 9eaf69ba..e473379f 100644
--- a/src/imports/controls/universal/Dial.qml
+++ b/src/imports/controls/universal/Dial.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.Dial {
diff --git a/src/imports/controls/universal/ProgressBar.qml b/src/imports/controls/universal/ProgressBar.qml
index cd314c27..b85a4581 100644
--- a/src/imports/controls/universal/ProgressBar.qml
+++ b/src/imports/controls/universal/ProgressBar.qml
@@ -47,20 +47,13 @@ T.ProgressBar {
implicitHeight: Math.max(background ? background.implicitHeight : 0,
contentItem.implicitHeight + topPadding + bottomPadding)
- contentItem: ProgressStrip {
- id: strip
+ contentItem: ProgressBarImpl {
implicitHeight: 10
scale: control.mirrored ? -1 : 1
- indeterminate: control.indeterminate
color: control.Universal.accent
progress: control.position
- clip: control.indeterminate
-
- ProgressStripAnimator {
- target: strip
- running: control.visible && control.indeterminate
- }
+ indeterminate: control.visible && control.indeterminate
}
background: Rectangle {
diff --git a/src/imports/controls/universal/RangeSlider.qml b/src/imports/controls/universal/RangeSlider.qml
index fec8bb18..cfbeb878 100644
--- a/src/imports/controls/universal/RangeSlider.qml
+++ b/src/imports/controls/universal/RangeSlider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.RangeSlider {
diff --git a/src/imports/controls/universal/Slider.qml b/src/imports/controls/universal/Slider.qml
index 472f5455..b46f2393 100644
--- a/src/imports/controls/universal/Slider.qml
+++ b/src/imports/controls/universal/Slider.qml
@@ -35,7 +35,7 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
T.Slider {
diff --git a/src/imports/controls/universal/Tumbler.qml b/src/imports/controls/universal/Tumbler.qml
index e7093d0a..a8033551 100644
--- a/src/imports/controls/universal/Tumbler.qml
+++ b/src/imports/controls/universal/Tumbler.qml
@@ -35,9 +35,9 @@
****************************************************************************/
import QtQuick 2.8
-import QtQuick.Templates 2.1 as T
+import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Universal 2.1
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Controls.impl 2.1
T.Tumbler {
diff --git a/src/imports/controls/universal/qquickuniversalprogressring.cpp b/src/imports/controls/universal/qquickuniversalbusyindicator.cpp
index 1d733fed..acefc5e3 100644
--- a/src/imports/controls/universal/qquickuniversalprogressring.cpp
+++ b/src/imports/controls/universal/qquickuniversalbusyindicator.cpp
@@ -34,12 +34,12 @@
**
****************************************************************************/
-#include "qquickuniversalprogressring_p.h"
+#include "qquickuniversalbusyindicator_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
QT_BEGIN_NAMESPACE
@@ -48,16 +48,15 @@ static const int PhaseCount = 6;
static const int Interval = 167;
static const int TotalDuration = 4052;
-class QQuickUniversalProgressRingAnimatorJob : public QQuickAnimatorJob
+class QQuickUniversalBusyIndicatorNode : public QObject, public QSGTransformNode
{
public:
- QQuickUniversalProgressRingAnimatorJob();
+ QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item);
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ int elapsed() const;
+
+ void animate();
+ void sync(QQuickUniversalBusyIndicator *item);
private:
struct Phase {
@@ -69,12 +68,18 @@ private:
QEasingCurve curve;
};
- QSGNode *m_node;
+ int m_offset;
+ QElapsedTimer m_timer;
Phase m_phases[PhaseCount];
};
-QQuickUniversalProgressRingAnimatorJob::QQuickUniversalProgressRingAnimatorJob() : m_node(nullptr)
+QQuickUniversalBusyIndicatorNode::QQuickUniversalBusyIndicatorNode(QQuickUniversalBusyIndicator *item)
+ : m_offset(item->elapsed())
{
+ QQuickWindow *window = item->window();
+ connect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeRendering, this, &QQuickUniversalBusyIndicatorNode::animate);
+
m_phases[0] = Phase(433, -110, 10, QEasingCurve::BezierSpline);
m_phases[1] = Phase(767, 10, 93, QEasingCurve::Linear );
m_phases[2] = Phase(417, 93, 205, QEasingCurve::BezierSpline);
@@ -86,27 +91,26 @@ QQuickUniversalProgressRingAnimatorJob::QQuickUniversalProgressRingAnimatorJob()
m_phases[2].curve.addCubicBezierSegment(QPointF(0.57, 0.17), QPointF(0.95, 0.75), QPointF(1.00, 1.00));
m_phases[3].curve.addCubicBezierSegment(QPointF(0.00, 0.19), QPointF(0.07, 0.72), QPointF(1.00, 1.00));
m_phases[5].curve.addCubicBezierSegment(QPointF(0.00, 0.00), QPointF(0.95, 0.37), QPointF(1.00, 1.00));
+
+ m_timer.restart();
}
-void QQuickUniversalProgressRingAnimatorJob::initialize(QQuickAnimatorController *controller)
+int QQuickUniversalBusyIndicatorNode::elapsed() const
{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ return m_timer.elapsed() + m_offset;
}
-void QQuickUniversalProgressRingAnimatorJob::updateCurrentTime(int time)
+void QQuickUniversalBusyIndicatorNode::animate()
{
- if (!m_node)
- return;
-
- QSGNode *containerNode = m_node->firstChild();
- Q_ASSERT(!containerNode || containerNode->type() == QSGNode::TransformNodeType);
- if (!containerNode)
- return;
+ qint64 time = m_timer.elapsed() + m_offset;
+ if (time >= TotalDuration) {
+ m_timer.restart();
+ m_offset = 0;
+ }
int nodeIndex = 0;
- int count = containerNode->childCount();
- QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(containerNode->firstChild());
+ int count = childCount();
+ QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(firstChild());
while (transformNode) {
Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType);
@@ -147,126 +151,115 @@ void QQuickUniversalProgressRingAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickUniversalProgressRingAnimatorJob::writeBack()
+void QQuickUniversalBusyIndicatorNode::sync(QQuickUniversalBusyIndicator *item)
{
-}
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
-void QQuickUniversalProgressRingAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
+ QMatrix4x4 matrix;
+ matrix.translate(item->width() / 2, item->height() / 2);
+ setMatrix(matrix);
-void QQuickUniversalProgressRingAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
+ qreal size = qMin(item->width(), item->height());
+ qreal diameter = size / 10.0;
+ qreal radius = diameter / 2;
+ qreal offset = (size - diameter * 2) / M_PI;
+ const QRectF rect(offset, offset, diameter, diameter);
-QQuickUniversalProgressRingAnimator::QQuickUniversalProgressRingAnimator(QObject *parent)
- : QQuickAnimator(parent)
-{
- setDuration(TotalDuration);
- setLoops(QQuickAnimator::Infinite);
-}
+ int count = item->count();
+ QSGNode *transformNode = firstChild();
+ for (int i = 0; i < count; ++i) {
+ if (!transformNode) {
+ transformNode = new QSGTransformNode;
+ appendChildNode(transformNode);
-QString QQuickUniversalProgressRingAnimator::propertyName() const
-{
- return QString();
-}
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ transformNode->appendChildNode(opacityNode);
-QQuickAnimatorJob *QQuickUniversalProgressRingAnimator::createJob() const
-{
- return new QQuickUniversalProgressRingAnimatorJob;
+ QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
+ rectNode->setAntialiasing(true);
+ opacityNode->appendChildNode(rectNode);
+ }
+
+ QSGNode *opacityNode = transformNode->firstChild();
+ Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
+
+ QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
+ Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
+
+ rectNode->setRect(rect);
+ rectNode->setColor(item->color());
+ rectNode->setRadius(radius);
+ rectNode->update();
+
+ transformNode = transformNode->nextSibling();
+ }
+
+ while (transformNode) {
+ QSGNode *nextSibling = transformNode->nextSibling();
+ delete transformNode;
+ transformNode = nextSibling;
+ }
}
-QQuickUniversalProgressRing::QQuickUniversalProgressRing(QQuickItem *parent)
- : QQuickItem(parent), m_count(5), m_color(Qt::black)
+QQuickUniversalBusyIndicator::QQuickUniversalBusyIndicator(QQuickItem *parent)
+ : QQuickItem(parent), m_count(5), m_elapsed(0), m_color(Qt::black)
{
setFlag(ItemHasContents);
}
-int QQuickUniversalProgressRing::count() const
+int QQuickUniversalBusyIndicator::count() const
{
return m_count;
}
-void QQuickUniversalProgressRing::setCount(int count)
+void QQuickUniversalBusyIndicator::setCount(int count)
{
if (m_count == count)
return;
m_count = count;
update();
- emit countChanged();
}
-QColor QQuickUniversalProgressRing::color() const
+QColor QQuickUniversalBusyIndicator::color() const
{
return m_color;
}
-void QQuickUniversalProgressRing::setColor(const QColor &color)
+void QQuickUniversalBusyIndicator::setColor(const QColor &color)
{
if (m_color == color)
return;
m_color = color;
update();
- emit colorChanged();
}
-QSGNode *QQuickUniversalProgressRing::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+int QQuickUniversalBusyIndicator::elapsed() const
{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
-
- if (!oldNode)
- oldNode = new QSGTransformNode;
- Q_ASSERT(oldNode->type() == QSGNode::TransformNodeType);
-
- QMatrix4x4 matrix;
- matrix.translate(width() / 2, height() / 2);
- static_cast<QSGTransformNode *>(oldNode)->setMatrix(matrix);
-
- qreal size = qMin(width(), height());
- qreal diameter = size / 10.0;
- qreal radius = diameter / 2;
- qreal offset = (size - diameter * 2) / M_PI;
- const QRectF rect(offset, offset, diameter, diameter);
-
- QSGNode *transformNode = oldNode->firstChild();
- for (int i = 0; i < m_count; ++i) {
- if (!transformNode) {
- transformNode = new QSGTransformNode;
- oldNode->appendChildNode(transformNode);
-
- QSGOpacityNode *opacityNode = new QSGOpacityNode;
- transformNode->appendChildNode(opacityNode);
-
- QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode();
- rectNode->setAntialiasing(true);
- opacityNode->appendChildNode(rectNode);
- }
-
- QSGNode *opacityNode = transformNode->firstChild();
- Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType);
-
- QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
- Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
-
- rectNode->setRect(rect);
- rectNode->setColor(m_color);
- rectNode->setRadius(radius);
- rectNode->update();
+ return m_elapsed;
+}
- transformNode = transformNode->nextSibling();
- }
+void QQuickUniversalBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
- while (transformNode) {
- QSGNode *nextSibling = transformNode->nextSibling();
- delete transformNode;
- transformNode = nextSibling;
+QSGNode *QQuickUniversalBusyIndicator::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ QQuickUniversalBusyIndicatorNode *node = static_cast<QQuickUniversalBusyIndicatorNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickUniversalBusyIndicatorNode(this);
+ node->sync(this);
+ } else {
+ m_elapsed = node ? node->elapsed() : 0;
+ delete node;
+ node = nullptr;
}
-
- return oldNode;
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/universal/qquickuniversalprogressring_p.h b/src/imports/controls/universal/qquickuniversalbusyindicator_p.h
index ef73ebed..7e3484d8 100644
--- a/src/imports/controls/universal/qquickuniversalprogressring_p.h
+++ b/src/imports/controls/universal/qquickuniversalbusyindicator_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKUNIVERSALPROGRESSRING_P_H
-#define QQUICKUNIVERSALPROGRESSRING_P_H
+#ifndef QQUICKUNIVERSALBUSYINDICATOR_P_H
+#define QQUICKUNIVERSALBUSYINDICATOR_P_H
//
// W A R N I N G
@@ -49,18 +49,17 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickUniversalProgressRing : public QQuickItem
+class QQuickUniversalBusyIndicator : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged FINAL)
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL)
+ Q_PROPERTY(int count READ count WRITE setCount FINAL)
+ Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
public:
- QQuickUniversalProgressRing(QQuickItem *parent = nullptr);
+ explicit QQuickUniversalBusyIndicator(QQuickItem *parent = nullptr);
int count() const;
void setCount(int count);
@@ -68,32 +67,20 @@ public:
QColor color() const;
void setColor(const QColor &color);
-Q_SIGNALS:
- void countChanged();
- void colorChanged();
+ int elapsed() const;
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
int m_count;
+ int m_elapsed;
QColor m_color;
};
-class QQuickUniversalProgressRingAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickUniversalProgressRingAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickUniversalProgressRing)
+QML_DECLARE_TYPE(QQuickUniversalBusyIndicator)
-#endif // QQUICKUNIVERSALPROGRESSRING_P_H
+#endif // QQUICKUNIVERSALBUSYINDICATOR_P_H
diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip.cpp b/src/imports/controls/universal/qquickuniversalprogressbar.cpp
index 32af5113..5e889f55 100644
--- a/src/imports/controls/universal/qquickuniversalprogressstrip.cpp
+++ b/src/imports/controls/universal/qquickuniversalprogressbar.cpp
@@ -34,12 +34,12 @@
**
****************************************************************************/
-#include "qquickuniversalprogressstrip_p.h"
+#include "qquickuniversalprogressbar_p.h"
#include <QtCore/qmath.h>
#include <QtCore/qeasingcurve.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtQuick/private/qquickitem_p.h>
-#include <QtQuick/private/qquickanimatorjob_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>
#include <QtQuick/qsgrectanglenode.h>
@@ -57,16 +57,13 @@ static const qreal ContainerAnimationEndPosition = 0.435222; // relative
static const qreal EllipseAnimationWellPosition = 0.333333333333333; // relative
static const qreal EllipseAnimationEndPosition = 0.666666666666667; // relative
-class QQuickUniversalProgressStripAnimatorJob : public QQuickAnimatorJob
+class QQuickUniversalProgressBarNode : public QObject, public QSGNode
{
public:
- QQuickUniversalProgressStripAnimatorJob();
+ QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *item);
- void initialize(QQuickAnimatorController *controller) override;
- void updateCurrentTime(int time) override;
- void writeBack() override;
- void nodeWasDestroyed() override;
- void afterNodeSync() override;
+ void animate();
+ void sync(QQuickUniversalProgressBar *item);
private:
struct Phase {
@@ -77,12 +74,14 @@ private:
qreal to;
};
- QSGNode *m_node;
+ bool m_indeterminate;
+ QElapsedTimer m_timer;
Phase m_borderPhases[PhaseCount];
Phase m_ellipsePhases[PhaseCount];
};
-QQuickUniversalProgressStripAnimatorJob::QQuickUniversalProgressStripAnimatorJob() : m_node(nullptr)
+QQuickUniversalProgressBarNode::QQuickUniversalProgressBarNode(QQuickUniversalProgressBar *)
+ : m_indeterminate(false)
{
m_borderPhases[0] = Phase( 500, -50, 0);
m_borderPhases[1] = Phase(1500, 0, 0);
@@ -93,20 +92,17 @@ QQuickUniversalProgressStripAnimatorJob::QQuickUniversalProgressStripAnimatorJob
m_ellipsePhases[1] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationWellPosition);
m_ellipsePhases[2] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition);
m_ellipsePhases[3] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition);
-}
-void QQuickUniversalProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller)
-{
- QQuickAnimatorJob::initialize(controller);
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
+ m_timer.start();
}
-void QQuickUniversalProgressStripAnimatorJob::updateCurrentTime(int time)
+void QQuickUniversalProgressBarNode::animate()
{
- if (!m_node)
- return;
+ qint64 time = m_timer.elapsed();
+ if (time >= TotalDuration)
+ m_timer.restart();
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(m_node->firstChild());
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType);
if (!geometryNode)
return;
@@ -197,105 +193,40 @@ void QQuickUniversalProgressStripAnimatorJob::updateCurrentTime(int time)
}
}
-void QQuickUniversalProgressStripAnimatorJob::writeBack()
-{
-}
-
-void QQuickUniversalProgressStripAnimatorJob::nodeWasDestroyed()
-{
- m_node = nullptr;
-}
-
-void QQuickUniversalProgressStripAnimatorJob::afterNodeSync()
-{
- m_node = QQuickItemPrivate::get(m_target)->childContainerNode();
-}
-
-QQuickUniversalProgressStripAnimator::QQuickUniversalProgressStripAnimator(QObject *parent)
- : QQuickAnimator(parent)
-{
- setDuration(TotalDuration);
- setLoops(QQuickAnimator::Infinite);
-}
-
-QString QQuickUniversalProgressStripAnimator::propertyName() const
+void QQuickUniversalProgressBarNode::sync(QQuickUniversalProgressBar *item)
{
- return QString();
-}
-
-QQuickAnimatorJob *QQuickUniversalProgressStripAnimator::createJob() const
-{
- return new QQuickUniversalProgressStripAnimatorJob;
-}
-
-QQuickUniversalProgressStrip::QQuickUniversalProgressStrip(QQuickItem *parent)
- : QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
-{
- setFlag(ItemHasContents);
-}
-
-QColor QQuickUniversalProgressStrip::color() const
-{
- return m_color;
-}
-
-void QQuickUniversalProgressStrip::setColor(const QColor &color)
-{
- if (m_color == color)
- return;
-
- m_color = color;
- update();
-}
-
-qreal QQuickUniversalProgressStrip::progress() const
-{
- return m_progress;
-}
-
-void QQuickUniversalProgressStrip::setProgress(qreal progress)
-{
- if (progress == m_progress)
- return;
-
- m_progress = progress;
- update();
-}
-
-bool QQuickUniversalProgressStrip::isIndeterminate() const
-{
- return m_indeterminate;
-}
-
-void QQuickUniversalProgressStrip::setIndeterminate(bool indeterminate)
-{
- if (indeterminate == m_indeterminate)
- return;
-
- m_indeterminate = indeterminate;
- update();
-}
+ if (m_indeterminate != item->isIndeterminate()) {
+ m_indeterminate = item->isIndeterminate();
+ QQuickWindow *window = item->window();
+ if (m_indeterminate) {
+ connect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ connect(window, &QQuickWindow::beforeRendering, this, &QQuickUniversalProgressBarNode::animate);
+ } else {
+ disconnect(window, &QQuickWindow::frameSwapped, window, &QQuickWindow::update);
+ disconnect(window, &QQuickWindow::beforeRendering, this, &QQuickUniversalProgressBarNode::animate);
+ }
+ }
-QSGNode *QQuickUniversalProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
- QQuickItemPrivate *d = QQuickItemPrivate::get(this);
+ QQuickItemPrivate *d = QQuickItemPrivate::get(item);
- QRectF bounds = boundingRect();
- bounds.setHeight(implicitHeight());
- bounds.moveTop((height() - bounds.height()) / 2.0);
+ QRectF bounds = item->boundingRect();
+ bounds.setHeight(item->implicitHeight());
+ bounds.moveTop((item->height() - bounds.height()) / 2.0);
if (!m_indeterminate)
- bounds.setWidth(m_progress * bounds.width());
+ bounds.setWidth(item->progress() * bounds.width());
- QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(oldNode);
- if (!geometryNode)
- geometryNode = window()->createRectangleNode();
+ QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(firstChild());
+ if (!geometryNode) {
+ geometryNode = item->window()->createRectangleNode();
+ appendChildNode(geometryNode);
+ }
geometryNode->setRect(bounds);
- geometryNode->setColor(m_indeterminate ? Qt::transparent : m_color);
+ geometryNode->setColor(m_indeterminate ? Qt::transparent : item->color());
if (!m_indeterminate) {
while (QSGNode *node = geometryNode->firstChild())
delete node;
- return geometryNode;
+ return;
}
QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild());
@@ -333,14 +264,82 @@ QSGNode *QQuickUniversalProgressStrip::updatePaintNode(QSGNode *oldNode, UpdateP
QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(opacityNode->firstChild());
Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType);
- rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter));
- rectNode->setColor(m_color);
+ rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (item->height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter));
+ rectNode->setColor(item->color());
rectNode->update();
borderNode = borderNode->nextSibling();
}
+}
+
+QQuickUniversalProgressBar::QQuickUniversalProgressBar(QQuickItem *parent)
+ : QQuickItem(parent), m_color(Qt::black), m_progress(0.0), m_indeterminate(false)
+{
+ setFlag(ItemHasContents);
+}
+
+QColor QQuickUniversalProgressBar::color() const
+{
+ return m_color;
+}
+
+void QQuickUniversalProgressBar::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+
+ m_color = color;
+ update();
+}
+
+qreal QQuickUniversalProgressBar::progress() const
+{
+ return m_progress;
+}
+
+void QQuickUniversalProgressBar::setProgress(qreal progress)
+{
+ if (progress == m_progress)
+ return;
+
+ m_progress = progress;
+ update();
+}
+
+bool QQuickUniversalProgressBar::isIndeterminate() const
+{
+ return m_indeterminate;
+}
+
+void QQuickUniversalProgressBar::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate == m_indeterminate)
+ return;
+
+ m_indeterminate = indeterminate;
+ setClip(m_indeterminate);
+ update();
+}
- return geometryNode;
+void QQuickUniversalProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+ QQuickItem::itemChange(change, data);
+ if (change == ItemVisibleHasChanged)
+ update();
+}
+
+QSGNode *QQuickUniversalProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QQuickUniversalProgressBarNode *node = static_cast<QQuickUniversalProgressBarNode *>(oldNode);
+ if (isVisible() && width() > 0 && height() > 0) {
+ if (!node)
+ node = new QQuickUniversalProgressBarNode(this);
+ node->sync(this);
+ } else {
+ delete node;
+ node = nullptr;
+ }
+ return node;
}
QT_END_NAMESPACE
diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip_p.h b/src/imports/controls/universal/qquickuniversalprogressbar_p.h
index 89350e4d..04e5ff3c 100644
--- a/src/imports/controls/universal/qquickuniversalprogressstrip_p.h
+++ b/src/imports/controls/universal/qquickuniversalprogressbar_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QQUICKUNIVERSALPROGRESSSTRIP_P_H
-#define QQUICKUNIVERSALPROGRESSSTRIP_P_H
+#ifndef QQUICKUNIVERSALPROGRESSBAR_P_H
+#define QQUICKUNIVERSALPROGRESSBAR_P_H
//
// W A R N I N G
@@ -49,11 +49,10 @@
//
#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquickanimator_p.h>
QT_BEGIN_NAMESPACE
-class QQuickUniversalProgressStrip : public QQuickItem
+class QQuickUniversalProgressBar : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor FINAL)
@@ -61,7 +60,7 @@ class QQuickUniversalProgressStrip : public QQuickItem
Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL)
public:
- QQuickUniversalProgressStrip(QQuickItem *parent = nullptr);
+ explicit QQuickUniversalProgressBar(QQuickItem *parent = nullptr);
QColor color() const;
void setColor(const QColor &color);
@@ -73,6 +72,7 @@ public:
void setIndeterminate(bool indeterminate);
protected:
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private:
@@ -81,21 +81,8 @@ private:
bool m_indeterminate;
};
-class QQuickUniversalProgressStripAnimator : public QQuickAnimator
-{
- Q_OBJECT
-
-public:
- QQuickUniversalProgressStripAnimator(QObject *parent = nullptr);
-
-protected:
- QString propertyName() const override;
- QQuickAnimatorJob *createJob() const override;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickUniversalProgressStrip)
-QML_DECLARE_TYPE(QQuickUniversalProgressStripAnimator)
+QML_DECLARE_TYPE(QQuickUniversalProgressBar)
-#endif // QQUICKUNIVERSALPROGRESSSTRIP_P_H
+#endif // QQUICKUNIVERSALPROGRESSBAR_P_H
diff --git a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
index 394e9162..be7c8a76 100644
--- a/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
+++ b/src/imports/controls/universal/qtquickcontrols2universalstyleplugin.cpp
@@ -36,9 +36,9 @@
#include <QtQuickControls2/private/qquickstyleplugin_p.h>
+#include "qquickuniversalbusyindicator_p.h"
#include "qquickuniversalfocusrectangle_p.h"
-#include "qquickuniversalprogressring_p.h"
-#include "qquickuniversalprogressstrip_p.h"
+#include "qquickuniversalprogressbar_p.h"
#include "qquickuniversalstyle_p.h"
#include "qquickuniversaltheme_p.h"
@@ -88,11 +88,9 @@ void QtQuickControls2UniversalStylePlugin::initializeEngine(QQmlEngine *engine,
QByteArray import = QByteArray(uri) + ".impl";
qmlRegisterType<QQuickUniversalFocusRectangle>(import, 2, 0, "FocusRectangle");
+ qmlRegisterType<QQuickUniversalBusyIndicator>(import, 2, 0, "BusyIndicatorImpl");
+ qmlRegisterType<QQuickUniversalProgressBar>(import, 2, 0, "ProgressBarImpl");
qmlRegisterRevision<QQuickUniversalFocusRectangle, 1>(import, 2, 1);
- qmlRegisterType<QQuickUniversalProgressRing>(import, 2, 0, "ProgressRing");
- qmlRegisterType<QQuickUniversalProgressRingAnimator>(import, 2, 0, "ProgressRingAnimator");
- qmlRegisterType<QQuickUniversalProgressStrip>(import, 2, 0, "ProgressStrip");
- qmlRegisterType<QQuickUniversalProgressStripAnimator>(import, 2, 0, "ProgressStripAnimator");
qmlRegisterType(typeUrl(QStringLiteral("RadioIndicator.qml")), import, 2, 0, "RadioIndicator");
qmlRegisterType(typeUrl(QStringLiteral("SwitchIndicator.qml")), import, 2, 0, "SwitchIndicator");
diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri
index 3697a2a6..833bf2b6 100644
--- a/src/imports/controls/universal/universal.pri
+++ b/src/imports/controls/universal/universal.pri
@@ -47,15 +47,15 @@ QML_FILES += \
$$PWD/Tumbler.qml
HEADERS += \
+ $$PWD/qquickuniversalbusyindicator_p.h \
$$PWD/qquickuniversalfocusrectangle_p.h \
- $$PWD/qquickuniversalprogressring_p.h \
- $$PWD/qquickuniversalprogressstrip_p.h \
+ $$PWD/qquickuniversalprogressbar_p.h \
$$PWD/qquickuniversalstyle_p.h \
$$PWD/qquickuniversaltheme_p.h
SOURCES += \
+ $$PWD/qquickuniversalbusyindicator.cpp \
$$PWD/qquickuniversalfocusrectangle.cpp \
- $$PWD/qquickuniversalprogressring.cpp \
- $$PWD/qquickuniversalprogressstrip.cpp \
+ $$PWD/qquickuniversalprogressbar.cpp \
$$PWD/qquickuniversalstyle.cpp \
$$PWD/qquickuniversaltheme.cpp
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index cc344a80..88ee9b58 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -197,6 +197,12 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickTextField, 1>(uri, 2, 1, "TextField");
qmlRegisterType<QQuickToolSeparator>(uri, 2, 1, "ToolSeparator");
qmlRegisterType<QQuickTumbler, 1>(uri, 2, 1, "Tumbler");
+
+ // QtQuick.Templates 2.2 (Qt 5.9)
+ qmlRegisterRevision<QQuickDial, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickRangeSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickSlider, 2>(uri, 2, 2);
+ qmlRegisterRevision<QQuickTumbler, 2>(uri, 2, 2);
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 48d02faa..eb60c93c 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -95,6 +95,7 @@ public:
pressed(false),
snapMode(QQuickDial::NoSnap),
wrap(false),
+ live(false),
handle(nullptr)
{
}
@@ -116,6 +117,7 @@ public:
QPoint pressPoint;
QQuickDial::SnapMode snapMode;
bool wrap;
+ bool live;
QQuickItem *handle;
};
@@ -246,11 +248,12 @@ void QQuickDial::setTo(qreal to)
This property holds the value in the range \c from - \c to. The default
value is \c 0.0.
- Unlike the \l position property, the \c value is not updated while the
- handle is dragged. The value is updated after the value has been chosen
- and the dial has been released.
+ Unlike the \l position property, the \c value is not updated by default
+ while the handle is dragged. The value is updated after the value has
+ been chosen and the dial has been released. The \l live property can be
+ used to make the dial provide live updates for the \c value property.
- \sa position
+ \sa position, live
*/
qreal QQuickDial::value() const
{
@@ -445,6 +448,33 @@ void QQuickDial::setPressed(bool pressed)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::Dial::live
+
+ This property holds whether the dial provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c false.
+
+ \sa value
+*/
+bool QQuickDial::live() const
+{
+ Q_D(const QQuickDial);
+ return d->live;
+}
+
+void QQuickDial::setLive(bool live)
+{
+ Q_D(QQuickDial);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::Dial::increase()
Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined.
@@ -571,8 +601,12 @@ void QQuickDial::mouseMoveEvent(QMouseEvent *event)
if (d->snapMode == SnapAlways)
pos = d->snapPosition(pos);
- if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos)))
- d->setPosition(pos);
+ if (d->wrap || (!d->wrap && !d->isLargeChange(event->pos(), pos))) {
+ if (d->live)
+ setValue(d->valueAt(pos));
+ else
+ d->setPosition(pos);
+ }
}
}
diff --git a/src/quicktemplates2/qquickdial_p.h b/src/quicktemplates2/qquickdial_p.h
index 2d87d6d9..17a44b7a 100644
--- a/src/quicktemplates2/qquickdial_p.h
+++ b/src/quicktemplates2/qquickdial_p.h
@@ -69,6 +69,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDial : public QQuickControl
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
Q_PROPERTY(bool wrap READ wrap WRITE setWrap NOTIFY wrapChanged FINAL)
Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL)
public:
@@ -106,6 +107,9 @@ public:
bool isPressed() const;
void setPressed(bool pressed);
+ bool live() const;
+ void setLive(bool live);
+
QQuickItem *handle() const;
void setHandle(QQuickItem *handle);
@@ -123,6 +127,7 @@ Q_SIGNALS:
void snapModeChanged();
void wrapChanged();
void pressedChanged();
+ Q_REVISION(2) void liveChanged();
void handleChanged();
protected:
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 3caf5042..83f34b5b 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -316,6 +316,7 @@ class QQuickRangeSliderPrivate : public QQuickControlPrivate
public:
QQuickRangeSliderPrivate() :
+ live(false),
from(defaultFrom),
to(defaultTo),
stepSize(0),
@@ -328,6 +329,7 @@ public:
void updateHover(const QPointF &pos);
+ bool live;
qreal from;
qreal to;
qreal stepSize;
@@ -474,8 +476,10 @@ void QQuickRangeSlider::setTo(qreal to)
If \l to is greater than \l from, the value of the first handle
must be greater than the second, and vice versa.
- Unlike \l {first.position}{position}, value is not updated while the
- handle is dragged, but rather when it has been released.
+ Unlike \l {first.position}{position}, value is not updated by default
+ while the handle is dragged, but rather when it has been released. The
+ \l live property can be used to make the slider provide live updates
+ for value.
The default value is \c 0.0.
\row
@@ -536,8 +540,10 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const
If \l to is greater than \l from, the value of the first handle
must be greater than the second, and vice versa.
- Unlike \l {second.position}{position}, value is not updated while the
- handle is dragged, but rather when it has been released.
+ Unlike \l {second.position}{position}, value is not updated by default
+ while the handle is dragged, but rather when it has been released. The
+ \l live property can be used to make the slider provide live updates
+ for value.
The default value is \c 0.0.
\row
@@ -657,6 +663,33 @@ void QQuickRangeSlider::setOrientation(Qt::Orientation orientation)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::RangeSlider::live
+
+ This property holds whether the slider provides live updates for the \l first.value
+ and \l second.value properties while the respective handles are dragged.
+
+ The default value is \c false.
+
+ \sa first.value, second.value
+*/
+bool QQuickRangeSlider::live() const
+{
+ Q_D(const QQuickRangeSlider);
+ return d->live;
+}
+
+void QQuickRangeSlider::setLive(bool live)
+{
+ Q_D(QQuickRangeSlider);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::RangeSlider::setValues(real firstValue, real secondValue)
Sets \l first.value and \l second.value with the given arguments.
@@ -874,7 +907,10 @@ void QQuickRangeSlider::mouseMoveEvent(QMouseEvent *event)
qreal pos = positionAt(this, pressedNode->handle(), event->pos());
if (d->snapMode == SnapAlways)
pos = snapPosition(this, pos);
- QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos);
+ if (d->live)
+ pressedNode->setValue(valueAt(this, pos));
+ else
+ QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos);
}
}
}
diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h
index 1b102e87..08e68b0e 100644
--- a/src/quicktemplates2/qquickrangeslider_p.h
+++ b/src/quicktemplates2/qquickrangeslider_p.h
@@ -65,6 +65,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl
Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
public:
explicit QQuickRangeSlider(QQuickItem *parent = nullptr);
@@ -94,6 +95,9 @@ public:
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation);
+ bool live() const;
+ void setLive(bool live);
+
Q_INVOKABLE void setValues(qreal firstValue, qreal secondValue);
Q_SIGNALS:
@@ -102,6 +106,7 @@ Q_SIGNALS:
void stepSizeChanged();
void snapModeChanged();
void orientationChanged();
+ Q_REVISION(2) void liveChanged();
protected:
void focusInEvent(QFocusEvent *event) override;
diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp
index 63fc50ac..f587460f 100644
--- a/src/quicktemplates2/qquickslider.cpp
+++ b/src/quicktemplates2/qquickslider.cpp
@@ -80,7 +80,7 @@ class QQuickSliderPrivate : public QQuickControlPrivate
Q_DECLARE_PUBLIC(QQuickSlider)
public:
- QQuickSliderPrivate() : from(0), to(1), value(0), position(0), stepSize(0), pressed(false),
+ QQuickSliderPrivate() : from(0), to(1), value(0), position(0), stepSize(0), live(false), pressed(false),
orientation(Qt::Horizontal), snapMode(QQuickSlider::NoSnap),
handle(nullptr)
{
@@ -96,6 +96,7 @@ public:
qreal value;
qreal position;
qreal stepSize;
+ bool live;
bool pressed;
QPoint pressPoint;
Qt::Orientation orientation;
@@ -225,12 +226,12 @@ void QQuickSlider::setTo(qreal to)
This property holds the value in the range \c from - \c to. The default value is \c 0.0.
- Unlike the \l position property, the \c value is not updated while the
- handle is dragged, but only after the value has been chosen and the slider
- has been released. The \l valueAt() method can be used to get continuous
- updates.
+ Unlike the \l position property, the \c value is not updated by default
+ while the handle is dragged, but only after the value has been chosen and
+ the slider has been released. The \l live property can be used to make the
+ slider provide live updates for the \c value property.
- \sa position, valueAt()
+ \sa position, live, valueAt()
*/
qreal QQuickSlider::value() const
{
@@ -259,9 +260,9 @@ void QQuickSlider::setValue(qreal value)
This property holds the logical position of the handle.
The position is defined as a percentage of the control's size, scaled
- to \c {0.0 - 1.0}. Unlike the \l value property, the \c position is
- continuously updated while the handle is dragged. For visualizing a
- slider, the right-to-left aware \l visualPosition should be used instead.
+ to \c {0.0 - 1.0}. The \c position is continuously updated while the
+ handle is dragged. For visualizing a slider, the right-to-left aware
+ \l visualPosition should be used instead.
\sa value, visualPosition, valueAt()
*/
@@ -356,6 +357,33 @@ void QQuickSlider::setSnapMode(SnapMode mode)
}
/*!
+ \since QtQuick.Controls 2.2
+ \qmlproperty bool QtQuick.Controls::Slider::live
+
+ This property holds whether the slider provides live updates for the \l value
+ property while the handle is dragged.
+
+ The default value is \c false.
+
+ \sa value
+*/
+bool QQuickSlider::live() const
+{
+ Q_D(const QQuickSlider);
+ return d->live;
+}
+
+void QQuickSlider::setLive(bool live)
+{
+ Q_D(QQuickSlider);
+ if (d->live == live)
+ return;
+
+ d->live = live;
+ emit liveChanged();
+}
+
+/*!
\qmlproperty bool QtQuick.Controls::Slider::pressed
This property holds whether the slider is pressed.
@@ -536,7 +564,10 @@ void QQuickSlider::mouseMoveEvent(QMouseEvent *event)
qreal pos = d->positionAt(event->pos());
if (d->snapMode == SnapAlways)
pos = d->snapPosition(pos);
- d->setPosition(pos);
+ if (d->live)
+ setValue(valueAt(pos));
+ else
+ d->setPosition(pos);
}
}
diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h
index d17af5c4..7ddffc7e 100644
--- a/src/quicktemplates2/qquickslider_p.h
+++ b/src/quicktemplates2/qquickslider_p.h
@@ -64,6 +64,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl
Q_PROPERTY(qreal visualPosition READ visualPosition NOTIFY visualPositionChanged FINAL)
Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL)
Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged FINAL)
+ Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged FINAL REVISION 2)
Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged FINAL)
Q_PROPERTY(QQuickItem *handle READ handle WRITE setHandle NOTIFY handleChanged FINAL)
@@ -96,6 +97,9 @@ public:
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
+ bool live() const;
+ void setLive(bool live);
+
bool isPressed() const;
void setPressed(bool pressed);
@@ -119,6 +123,7 @@ Q_SIGNALS:
void visualPositionChanged();
void stepSizeChanged();
void snapModeChanged();
+ Q_REVISION(2) void liveChanged();
void pressedChanged();
void orientationChanged();
void handleChanged();
diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp
index 49a9c087..068720bb 100644
--- a/src/quicktemplates2/qquicktumbler.cpp
+++ b/src/quicktemplates2/qquicktumbler.cpp
@@ -439,6 +439,19 @@ void QQuickTumbler::resetWrap()
d->setWrapBasedOnCount();
}
+/*!
+ \qmlproperty bool QtQuick.Controls::Tumbler::moving
+ \since QtQuick.Controls 2.2
+
+ This property describes whether the tumbler is currently moving, due to
+ the user either dragging or flicking it.
+*/
+bool QQuickTumbler::isMoving() const
+{
+ Q_D(const QQuickTumbler);
+ return d->view && d->view->property("moving").toBool();
+}
+
QQuickTumblerAttached *QQuickTumbler::qmlAttachedProperties(QObject *object)
{
return new QQuickTumblerAttached(object);
@@ -505,6 +518,7 @@ void QQuickTumblerPrivate::disconnectFromView()
QObject::disconnect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged()));
QObject::disconnect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
QObject::disconnect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged()));
+ QObject::disconnect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
QQuickItemPrivate *oldViewContentItemPrivate = QQuickItemPrivate::get(viewContentItem);
oldViewContentItemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Children);
@@ -529,6 +543,7 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem)
QObject::connect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged()));
QObject::connect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
QObject::connect(view, SIGNAL(countChanged()), q, SLOT(_q_onViewCountChanged()));
+ QObject::connect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
QQuickItemPrivate *viewContentItemPrivate = QQuickItemPrivate::get(viewContentItem);
viewContentItemPrivate->addItemChangeListener(this, QQuickItemPrivate::Children);
diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h
index 1c8cfa18..3ec4044c 100644
--- a/src/quicktemplates2/qquicktumbler_p.h
+++ b/src/quicktemplates2/qquicktumbler_p.h
@@ -67,6 +67,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumbler : public QQuickControl
Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL)
Q_PROPERTY(int visibleItemCount READ visibleItemCount WRITE setVisibleItemCount NOTIFY visibleItemCountChanged FINAL)
Q_PROPERTY(bool wrap READ wrap WRITE setWrap RESET resetWrap NOTIFY wrapChanged FINAL REVISION 1)
+ Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged FINAL REVISION 2)
public:
explicit QQuickTumbler(QQuickItem *parent = nullptr);
@@ -91,6 +92,8 @@ public:
void setWrap(bool wrap);
void resetWrap();
+ bool isMoving() const;
+
static QQuickTumblerAttached *qmlAttachedProperties(QObject *object);
Q_SIGNALS:
@@ -101,6 +104,7 @@ Q_SIGNALS:
void delegateChanged();
void visibleItemCountChanged();
Q_REVISION(1) void wrapChanged();
+ Q_REVISION(2) void movingChanged();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
diff --git a/tests/auto/controls/data/tst_dial.qml b/tests/auto/controls/data/tst_dial.qml
index e6446d3e..6dd65593 100644
--- a/tests/auto/controls/data/tst_dial.qml
+++ b/tests/auto/controls/data/tst_dial.qml
@@ -172,9 +172,10 @@ TestCase {
function test_dragging_data() {
return [
- { tag: "default", from: 0, to: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0 },
- { tag: "scaled2", from: 0, to: 2, leftValue: 0.4, topValue: 1.0, rightValue: 1.6, bottomValue: 2.0 },
- { tag: "scaled1", from: -1, to: 0, leftValue: -0.8, topValue: -0.5, rightValue: -0.2, bottomValue: 0.0 }
+ { tag: "default", from: 0, to: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0, live: false },
+ { tag: "scaled2", from: 0, to: 2, leftValue: 0.4, topValue: 1.0, rightValue: 1.6, bottomValue: 2.0, live: false },
+ { tag: "scaled1", from: -1, to: 0, leftValue: -0.8, topValue: -0.5, rightValue: -0.2, bottomValue: 0.0, live: false },
+ { tag: "live", from: 0, to: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0, live: true }
]
}
@@ -183,32 +184,35 @@ TestCase {
verify(dial.wrap);
dial.from = data.from;
dial.to = data.to;
+ dial.live = data.live;
valueSpy.target = dial;
verify(valueSpy.valid);
+ var minimumExpectedValueCount = data.live ? 2 : 1;
+
// drag to the left
mouseDrag(dial, dial.width / 2, dial.height / 2, -dial.width / 2, 0, Qt.LeftButton);
fuzzyCompare(dial.value, data.leftValue, 0.1);
- verify(valueSpy.count > 0);
+ verify(valueSpy.count >= minimumExpectedValueCount);
valueSpy.clear();
// drag to the top
mouseDrag(dial, dial.width / 2, dial.height / 2, 0, -dial.height / 2, Qt.LeftButton);
fuzzyCompare(dial.value, data.topValue, 0.1);
- verify(valueSpy.count > 0);
+ verify(valueSpy.count >= minimumExpectedValueCount);
valueSpy.clear();
// drag to the right
mouseDrag(dial, dial.width / 2, dial.height / 2, dial.width / 2, 0, Qt.LeftButton);
fuzzyCompare(dial.value, data.rightValue, 0.1);
- verify(valueSpy.count > 0);
+ verify(valueSpy.count >= minimumExpectedValueCount);
valueSpy.clear();
// drag to the bottom (* 0.6 to ensure we don't go over to the minimum position)
mouseDrag(dial, dial.width / 2, dial.height / 2, 10, dial.height / 2, Qt.LeftButton);
fuzzyCompare(dial.value, data.bottomValue, 0.1);
- verify(valueSpy.count > 0);
+ verify(valueSpy.count >= minimumExpectedValueCount);
valueSpy.clear();
}
diff --git a/tests/auto/controls/data/tst_rangeslider.qml b/tests/auto/controls/data/tst_rangeslider.qml
index eb654bbc..42155dc0 100644
--- a/tests/auto/controls/data/tst_rangeslider.qml
+++ b/tests/auto/controls/data/tst_rangeslider.qml
@@ -40,7 +40,7 @@
import QtQuick 2.2
import QtTest 1.0
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
TestCase {
id: testCase
@@ -274,13 +274,15 @@ TestCase {
function test_mouse_data() {
return [
- { tag: "horizontal", orientation: Qt.Horizontal },
- { tag: "vertical", orientation: Qt.Vertical }
+ { tag: "horizontal", orientation: Qt.Horizontal, live: false },
+ { tag: "vertical", orientation: Qt.Vertical, live: false },
+ { tag: "horizontal:live", orientation: Qt.Horizontal, live: true },
+ { tag: "vertical:live", orientation: Qt.Vertical, live: true }
]
}
function test_mouse(data) {
- var control = sliderComponent.createObject(testCase, { orientation: data.orientation })
+ var control = sliderComponent.createObject(testCase, { orientation: data.orientation, live: data.live })
verify(control)
var firstPressedSpy = signalSpy.createObject(control, {target: control.first, signalName: "pressedChanged"})
@@ -366,7 +368,7 @@ TestCase {
compare(firstPressedSpy.count, 5)
compare(secondPressedSpy.count, 2)
compare(control.first.pressed, true)
- compare(control.first.value, 0.0)
+ compare(control.first.value, data.live ? 0.5 : 0.0)
compare(control.first.position, 0.5)
compare(control.first.visualPosition, 0.5)
compare(control.second.pressed, false)
diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml
index 029aff14..c5884273 100644
--- a/tests/auto/controls/data/tst_slider.qml
+++ b/tests/auto/controls/data/tst_slider.qml
@@ -40,7 +40,7 @@
import QtQuick 2.2
import QtTest 1.0
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
TestCase {
id: testCase
@@ -213,13 +213,15 @@ TestCase {
function test_mouse_data() {
return [
- { tag: "horizontal", orientation: Qt.Horizontal },
- { tag: "vertical", orientation: Qt.Vertical }
+ { tag: "horizontal", orientation: Qt.Horizontal, live: false },
+ { tag: "vertical", orientation: Qt.Vertical, live: false },
+ { tag: "horizontal:live", orientation: Qt.Horizontal, live: true },
+ { tag: "vertical:live", orientation: Qt.Vertical, live: true }
]
}
function test_mouse(data) {
- var control = slider.createObject(testCase, {orientation: data.orientation})
+ var control = slider.createObject(testCase, {orientation: data.orientation, live: data.live})
verify(control)
var pressedSpy = signalSpy.createObject(control, {target: control, signalName: "pressedChanged"})
@@ -241,8 +243,8 @@ TestCase {
mouseMove(control, control.width * 0.5, control.height * 0.5, 0, Qt.LeftButton)
compare(pressedSpy.count, 1)
compare(control.pressed, true)
- compare(control.value, 0.0)
- verify(control.position, 0.5)
+ compare(control.value, data.live ? 0.5 : 0.0)
+ compare(control.position, 0.5)
mouseRelease(control, control.width * 0.5, control.height * 0.5, Qt.LeftButton)
compare(pressedSpy.count, 2)
@@ -260,13 +262,13 @@ TestCase {
mouseMove(control, control.width * 2, -control.height, 0, Qt.LeftButton)
compare(pressedSpy.count, 3)
compare(control.pressed, true)
- compare(control.value, 0.5)
+ compare(control.value, data.live ? 1.0 : 0.5)
compare(control.position, 1.0)
mouseMove(control, control.width * 0.75, control.height * 0.25, 0, Qt.LeftButton)
compare(pressedSpy.count, 3)
compare(control.pressed, true)
- compare(control.value, 0.5)
+ compare(control.value, data.live ? control.position : 0.5)
verify(control.position >= 0.75)
mouseRelease(control, control.width * 0.25, control.height * 0.75, Qt.LeftButton)
diff --git a/tests/auto/controls/data/tst_tumbler.qml b/tests/auto/controls/data/tst_tumbler.qml
index b3230ca4..bca2e976 100644
--- a/tests/auto/controls/data/tst_tumbler.qml
+++ b/tests/auto/controls/data/tst_tumbler.qml
@@ -40,7 +40,7 @@
import QtQuick 2.2
import QtTest 1.0
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
TestCase {
id: testCase
@@ -1045,4 +1045,30 @@ TestCase {
++tumbler.currentIndex;
tryCompare(tumblerView, "offset", 4, tumblerView.highlightMoveDuration * 2);
}
+
+ function test_moving_data() {
+ return [
+ { tag: "wrap:true", wrap: true },
+ { tag: "wrap:false", wrap: false }
+ ]
+ }
+
+ function test_moving(data) {
+ createTumbler({wrap: data.wrap, model: 5})
+ compare(tumbler.wrap, data.wrap)
+ compare(tumbler.moving, false)
+
+ waitForRendering(tumbler)
+
+ mousePress(tumbler, tumbler.width / 2, tumbler.height / 2, Qt.LeftButton)
+ compare(tumbler.moving, false)
+
+ for (var y = tumbler.height / 2; y >= tumbler.height / 4; y -= 10)
+ mouseMove(tumbler, tumbler.width / 2, y, 1)
+ compare(tumbler.moving, true)
+
+ mouseRelease(tumbler, tumbler.width / 2, tumbler.height / 4, Qt.LeftButton)
+ compare(tumbler.moving, true)
+ tryCompare(tumbler, "moving", false)
+ }
}