diff options
Diffstat (limited to 'src/imports/controls/basic/impl')
10 files changed, 1022 insertions, 0 deletions
diff --git a/src/imports/controls/basic/impl/CMakeLists.txt b/src/imports/controls/basic/impl/CMakeLists.txt new file mode 100644 index 00000000..08bffb5d --- /dev/null +++ b/src/imports/controls/basic/impl/CMakeLists.txt @@ -0,0 +1,41 @@ +# Generated from basic-impl.pro. + +##################################################################### +## qtquickcontrols2basicstyleimplplugin Plugin: +##################################################################### + +qt_add_qml_module(qtquickcontrols2basicstyleimplplugin + URI "QtQuick.Controls.Basic.impl" + VERSION "${CMAKE_PROJECT_VERSION}" + CLASSNAME QtQuickControls2BasicStyleImplPlugin + SKIP_TYPE_REGISTRATION + GENERATE_QMLTYPES + SOURCES + qquickbasicbusyindicator.cpp qquickbasicbusyindicator_p.h + qquickbasicdial.cpp qquickbasicdial_p.h + qquickbasicprogressbar.cpp qquickbasicprogressbar_p.h + qtquickcontrols2basicstyleimplplugin.cpp + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +#### Keys ignored in scope 1:.:.:basic-impl.pro:<TRUE>: +# OTHER_FILES = "qmldir" +# QML_IMPORT_NAME = "QtQuick.Controls.Basic.impl" +# QML_IMPORT_VERSION = "$$QT_VERSION" +# QT_FOR_CONFIG = "quickcontrols2-private" +# TARGETPATH = "QtQuick/Controls/Basic/impl" +# _REQUIREMENTS = "qtConfig(quickcontrols2-basic)" diff --git a/src/imports/controls/basic/impl/basic-impl.pro b/src/imports/controls/basic/impl/basic-impl.pro new file mode 100644 index 00000000..ba60b081 --- /dev/null +++ b/src/imports/controls/basic/impl/basic-impl.pro @@ -0,0 +1,30 @@ +TARGET = qtquickcontrols2basicstyleimplplugin +TARGETPATH = QtQuick/Controls/Basic/impl + +QML_IMPORT_NAME = QtQuick.Controls.Basic.impl +QML_IMPORT_VERSION = $$QT_VERSION + +QT += qml quick +QT_PRIVATE += core-private gui qml-private quick-private quicktemplates2-private quickcontrols2impl-private +QT_FOR_CONFIG = quickcontrols2-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII + +OTHER_FILES += \ + qmldir + +HEADERS += \ + $$PWD/qquickbasicbusyindicator_p.h \ + $$PWD/qquickbasicdial_p.h \ + $$PWD/qquickbasicprogressbar_p.h + +SOURCES += \ + $$PWD/qquickbasicbusyindicator.cpp \ + $$PWD/qquickbasicdial.cpp \ + $$PWD/qquickbasicprogressbar.cpp \ + $$PWD/qtquickcontrols2basicstyleimplplugin.cpp + +CONFIG += qmltypes install_qmltypes no_cxx_module +load(qml_plugin) + +requires(qtConfig(quickcontrols2-basic)) diff --git a/src/imports/controls/basic/impl/qmldir b/src/imports/controls/basic/impl/qmldir new file mode 100644 index 00000000..a5fabe7f --- /dev/null +++ b/src/imports/controls/basic/impl/qmldir @@ -0,0 +1,3 @@ +module QtQuick.Controls.Basic.impl +plugin qtquickcontrols2basicstyleimplplugin +classname QtQuickControls2BasicStyleImplPlugin diff --git a/src/imports/controls/basic/impl/qquickbasicbusyindicator.cpp b/src/imports/controls/basic/impl/qquickbasicbusyindicator.cpp new file mode 100644 index 00000000..7fb3b024 --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicbusyindicator.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "qquickbasicbusyindicator_p.h" + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_p.h> + +QT_BEGIN_NAMESPACE + +static const int CircleCount = 10; +static const int TotalDuration = 100 * CircleCount * 2; +static const QRgb TransparentColor = 0x00000000; + +static QPointF moveCircle(const QPointF &pos, qreal rotation, qreal distance) +{ + return pos - QTransform().rotate(rotation).map(QPointF(0, distance)); +} + +class QQuickBasicBusyIndicatorNode : public QQuickAnimatedNode +{ +public: + QQuickBasicBusyIndicatorNode(QQuickBasicBusyIndicator *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + QColor m_pen; + QColor m_fill; +}; + +QQuickBasicBusyIndicatorNode::QQuickBasicBusyIndicatorNode(QQuickBasicBusyIndicator *item) + : QQuickAnimatedNode(item) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); + setCurrentTime(item->elapsed()); + + 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); + } +} + +void QQuickBasicBusyIndicatorNode::updateCurrentTime(int time) +{ + 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(fill ? m_fill : QColor::fromRgba(TransparentColor)); + rectNode->setPenColor(m_pen); + rectNode->setPenWidth(1); + rectNode->update(); + + transformNode = static_cast<QSGTransformNode*>(transformNode->nextSibling()); + } +} + +void QQuickBasicBusyIndicatorNode::sync(QQuickItem *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; + + m_pen = static_cast<QQuickBasicBusyIndicator *>(item)->pen(); + m_fill = static_cast<QQuickBasicBusyIndicator *>(item)->fill(); + + 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.0 / 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()); + } +} + +QQuickBasicBusyIndicator::QQuickBasicBusyIndicator(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +QColor QQuickBasicBusyIndicator::pen() const +{ + return m_pen; +} + +void QQuickBasicBusyIndicator::setPen(const QColor &pen) +{ + if (pen == m_pen) + return; + + m_pen = pen; + update(); +} + +QColor QQuickBasicBusyIndicator::fill() const +{ + return m_fill; +} + +void QQuickBasicBusyIndicator::setFill(const QColor &fill) +{ + if (fill == m_fill) + return; + + m_fill = fill; + update(); +} + +bool QQuickBasicBusyIndicator::isRunning() const +{ + return isVisible(); +} + +void QQuickBasicBusyIndicator::setRunning(bool running) +{ + if (running) + setVisible(true); +} + +int QQuickBasicBusyIndicator::elapsed() const +{ + return m_elapsed; +} + +void QQuickBasicBusyIndicator::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + switch (change) { + case ItemOpacityHasChanged: + if (qFuzzyIsNull(data.realValue)) + setVisible(false); + break; + case ItemVisibleHasChanged: + update(); + break; + default: + break; + } +} + +QSGNode *QQuickBasicBusyIndicator::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickBasicBusyIndicatorNode *node = static_cast<QQuickBasicBusyIndicatorNode *>(oldNode); + if (isRunning() && width() > 0 && height() > 0) { + if (!node) { + node = new QQuickBasicBusyIndicatorNode(this); + node->start(); + } + node->sync(this); + } else { + m_elapsed = node ? node->currentTime() : 0; + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/basic/impl/qquickbasicbusyindicator_p.h b/src/imports/controls/basic/impl/qquickbasicbusyindicator_p.h new file mode 100644 index 00000000..7eea6656 --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicbusyindicator_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTBUSYINDICATOR_P_H +#define QQUICKDEFAULTBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicBusyIndicator : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor pen READ pen WRITE setPen FINAL) + Q_PROPERTY(QColor fill READ fill WRITE setFill FINAL) + Q_PROPERTY(bool running READ isRunning WRITE setRunning) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicBusyIndicator(QQuickItem *parent = nullptr); + + QColor pen() const; + void setPen(const QColor &pen); + + QColor fill() const; + void setFill(const QColor &fill); + + bool isRunning() const; + void setRunning(bool running); + + int elapsed() const; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + int m_elapsed = 0; + QColor m_pen; + QColor m_fill; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickBasicBusyIndicator) + +#endif // QQUICKDEFAULTBUSYINDICATOR_P_H diff --git a/src/imports/controls/basic/impl/qquickbasicdial.cpp b/src/imports/controls/basic/impl/qquickbasicdial.cpp new file mode 100644 index 00000000..223e8042 --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicdial.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "qquickbasicdial_p.h" + +#include <QtCore/qmath.h> +#include <QtGui/qpainter.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickBasicDial::QQuickBasicDial(QQuickItem *parent) : + QQuickPaintedItem(parent) +{ +} + +qreal QQuickBasicDial::progress() const +{ + return m_progress; +} + +void QQuickBasicDial::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +QColor QQuickBasicDial::color() const +{ + return m_color; +} + +void QQuickBasicDial::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +void QQuickBasicDial::paint(QPainter *painter) +{ + if (width() <= 0 || height() <= 0) + return; + + QPen pen(m_color); + pen.setWidth(8); + pen.setCapStyle(Qt::FlatCap); + painter->setPen(pen); + + const QRectF bounds = boundingRect(); + const qreal smallest = qMin(bounds.width(), bounds.height()); + QRectF rect = QRectF(pen.widthF() / 2.0 + 1, pen.widthF() / 2.0 + 1, smallest - pen.widthF() - 2, smallest - pen.widthF() - 2); + rect.moveCenter(bounds.center()); + + // Make sure the arc is aligned to whole pixels. + if (rect.x() - int(rect.x()) > 0) + rect.setX(qCeil(rect.x())); + if (rect.y() - int(rect.y()) > 0) + rect.setY(qCeil(rect.y())); + if (rect.width() - int(rect.width()) > 0) + rect.setWidth(qFloor(rect.width())); + if (rect.height() - int(rect.height()) > 0) + rect.setHeight(qFloor(rect.height())); + + painter->setRenderHint(QPainter::Antialiasing); + + const qreal startAngle = (140 + 90); + const qreal spanAngle = (m_progress * 280) * -1; + QPainterPath path; + path.arcMoveTo(rect, startAngle); + path.arcTo(rect, startAngle, spanAngle); + painter->drawPath(path); + + rect.adjust(-pen.widthF() / 2.0, -pen.widthF() / 2.0, pen.widthF() / 2.0, pen.widthF() / 2.0); + pen.setWidth(1); + painter->setPen(pen); + + path = QPainterPath(); + path.arcMoveTo(rect, 0); + path.arcTo(rect, 0, 360); + painter->drawPath(path); +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/basic/impl/qquickbasicdial_p.h b/src/imports/controls/basic/impl/qquickbasicdial_p.h new file mode 100644 index 00000000..bd9bbb72 --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicdial_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTDIAL_P_H +#define QQUICKDEFAULTDIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickpainteditem.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicDial : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + QML_NAMED_ELEMENT(DialImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicDial(QQuickItem *parent = nullptr); + + qreal progress() const; + void setProgress(qreal progress); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter) override; + +private: + qreal m_progress = 0; + QColor m_color = Qt::black; +}; + +QT_END_NAMESPACE + +#endif // QQUICKDEFAULTDIAL_P_H diff --git a/src/imports/controls/basic/impl/qquickbasicprogressbar.cpp b/src/imports/controls/basic/impl/qquickbasicprogressbar.cpp new file mode 100644 index 00000000..717082af --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicprogressbar.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "qquickbasicprogressbar_p.h" + +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickControls2Impl/private/qquickanimatednode_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 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.0; + return spanRightEdgePos - (blockIndex + 1) * BlockWidth - (blockIndex * BlockRestingSpacing); +} + +static inline qreal blockEndX(int blockIndex, qreal availableWidth) +{ + return availableWidth - blockStartX(Blocks - 1 - blockIndex) - BlockWidth; +} + +class QQuickBasicProgressBarNode : public QQuickAnimatedNode +{ +public: + QQuickBasicProgressBarNode(QQuickBasicProgressBar *item); + + void updateCurrentTime(int time) override; + void sync(QQuickItem *item) override; + +private: + bool m_indeterminate = false; + qreal m_pixelsPerSecond = 0; +}; + +QQuickBasicProgressBarNode::QQuickBasicProgressBarNode(QQuickBasicProgressBar *item) + : QQuickAnimatedNode(item), + m_pixelsPerSecond(item->width()) +{ + setLoopCount(Infinite); + setDuration(TotalDuration); +} + +void QQuickBasicProgressBarNode::updateCurrentTime(int time) +{ + 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 QQuickBasicProgressBarNode::sync(QQuickItem *item) +{ + QQuickBasicProgressBar *bar = static_cast<QQuickBasicProgressBar *>(item); + if (m_indeterminate != bar->isIndeterminate()) { + m_indeterminate = bar->isIndeterminate(); + if (m_indeterminate) + start(); + else + stop(); + } + m_pixelsPerSecond = item->width(); + + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + + QMatrix4x4 m; + m.translate(0, (item->height() - item->implicitHeight()) / 2); + setMatrix(m); + + if (m_indeterminate) { + 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(bar->color()); + 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(bar->color()); + appendChildNode(rectNode); + } + + rectNode->setRect(QRectF(QPointF(0, 0), QSizeF(bar->progress() * item->width(), item->implicitHeight()))); + rectNode->update(); + } +} + +QQuickBasicProgressBar::QQuickBasicProgressBar(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(ItemHasContents); +} + +qreal QQuickBasicProgressBar::progress() const +{ + return m_progress; +} + +void QQuickBasicProgressBar::setProgress(qreal progress) +{ + if (progress == m_progress) + return; + + m_progress = progress; + update(); +} + +bool QQuickBasicProgressBar::isIndeterminate() const +{ + return m_indeterminate; +} + +void QQuickBasicProgressBar::setIndeterminate(bool indeterminate) +{ + if (indeterminate == m_indeterminate) + return; + + m_indeterminate = indeterminate; + setClip(m_indeterminate); + update(); +} + +QColor QQuickBasicProgressBar::color() const +{ + return m_color; +} + +void QQuickBasicProgressBar::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +void QQuickBasicProgressBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + if (change == ItemVisibleHasChanged) + update(); +} + +QSGNode *QQuickBasicProgressBar::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + QQuickBasicProgressBarNode *node = static_cast<QQuickBasicProgressBarNode *>(oldNode); + if (isVisible() && width() > 0 && height() > 0) { + if (!node) + node = new QQuickBasicProgressBarNode(this); + node->sync(this); + } else { + delete node; + node = nullptr; + } + return node; +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/basic/impl/qquickbasicprogressbar_p.h b/src/imports/controls/basic/impl/qquickbasicprogressbar_p.h new file mode 100644 index 00000000..1d853ecb --- /dev/null +++ b/src/imports/controls/basic/impl/qquickbasicprogressbar_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + +#ifndef QQUICKDEFAULTPROGRESSBAR_P_H +#define QQUICKDEFAULTPROGRESSBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtGui/qcolor.h> + +QT_BEGIN_NAMESPACE + +class QQuickBasicProgressBar : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate FINAL) + Q_PROPERTY(qreal progress READ progress WRITE setProgress FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + QML_NAMED_ELEMENT(ProgressBarImpl) + QML_ADDED_IN_VERSION(2, 0) + +public: + explicit QQuickBasicProgressBar(QQuickItem *parent = nullptr); + + bool isIndeterminate() const; + void setIndeterminate(bool indeterminate); + + qreal progress() const; + void setProgress(qreal progress); + + QColor color() const; + void setColor(const QColor &color); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + +private: + qreal m_progress = 0; + bool m_indeterminate = false; + QColor m_color; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickBasicProgressBar) + +#endif // QQUICKDEFAULTPROGRESSBAR_P_H diff --git a/src/imports/controls/basic/impl/qtquickcontrols2basicstyleimplplugin.cpp b/src/imports/controls/basic/impl/qtquickcontrols2basicstyleimplplugin.cpp new file mode 100644 index 00000000..8a8bba46 --- /dev/null +++ b/src/imports/controls/basic/impl/qtquickcontrols2basicstyleimplplugin.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2020 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 <QtQml/qqmlextensionplugin.h> + +QT_BEGIN_NAMESPACE + +class QtQuickControls2BasicStyleImplPlugin : public QQmlEngineExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2BasicStyleImplPlugin(QObject *parent = nullptr); +}; + +QtQuickControls2BasicStyleImplPlugin::QtQuickControls2BasicStyleImplPlugin(QObject *parent) + : QQmlEngineExtensionPlugin(parent) +{ +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2basicstyleimplplugin.moc" |