From 7c284809df7e8f1a2adbee1d768a07d13f0403cc Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 7 Jul 2016 13:11:19 +0200 Subject: Material: implement the ripple effect Consequently, the controls that were previously using the old Ripple type have now gained hover effects (when hoverEnabled: true). The rest of the Material style controls will be adjusted to use the ripple effect in follow up commits. Task-number: QTBUG-50003 Change-Id: I436f3794411fe75de9ccbe3ecda71029130db613 Reviewed-by: Mitch Curtis --- src/imports/controls/material/CheckIndicator.qml | 14 +- src/imports/controls/material/RadioIndicator.qml | 14 +- src/imports/controls/material/Ripple.qml | 51 --- src/imports/controls/material/SliderHandle.qml | 11 +- src/imports/controls/material/SwitchIndicator.qml | 10 +- src/imports/controls/material/material.pri | 3 +- .../controls/material/qquickmaterialripple.cpp | 396 +++++++++++++++++++++ .../controls/material/qquickmaterialripple_p.h | 107 ++++++ .../qtquickcontrols2materialstyleplugin.cpp | 2 + 9 files changed, 532 insertions(+), 76 deletions(-) delete mode 100644 src/imports/controls/material/Ripple.qml create mode 100644 src/imports/controls/material/qquickmaterialripple.cpp create mode 100644 src/imports/controls/material/qquickmaterialripple_p.h (limited to 'src') diff --git a/src/imports/controls/material/CheckIndicator.qml b/src/imports/controls/material/CheckIndicator.qml index 224d7dbc..3e765593 100644 --- a/src/imports/controls/material/CheckIndicator.qml +++ b/src/imports/controls/material/CheckIndicator.qml @@ -47,7 +47,7 @@ Rectangle { border.width: control.checked ? width / 2 : 2 radius: 2 - property alias control: ripple.control + property Item control Behavior on border.width { NumberAnimation { @@ -64,12 +64,12 @@ Rectangle { } Ripple { - id: ripple - width: parent.width - height: width - control: control - colored: control.checked - opacity: control.down || control.visualFocus ? 1 : 0 + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor } // TODO: This needs to be transparent diff --git a/src/imports/controls/material/RadioIndicator.qml b/src/imports/controls/material/RadioIndicator.qml index 1cf5829a..304176e4 100644 --- a/src/imports/controls/material/RadioIndicator.qml +++ b/src/imports/controls/material/RadioIndicator.qml @@ -46,15 +46,15 @@ Rectangle { border.color: control.checked || control.down ? control.Material.accentColor : control.Material.secondaryTextColor color: "transparent" - property alias control: ripple.control + property Item control Ripple { - id: ripple - width: parent.width - height: width - control: control - colored: control.checked - opacity: control.down || control.visualFocus ? 1 : 0 + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor } Rectangle { diff --git a/src/imports/controls/material/Ripple.qml b/src/imports/controls/material/Ripple.qml deleted file mode 100644 index c4209e78..00000000 --- a/src/imports/controls/material/Ripple.qml +++ /dev/null @@ -1,51 +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$ -** -****************************************************************************/ - -import QtQuick 2.6 -import QtQuick.Controls.Material 2.1 - -Rectangle { - property Item control - property bool colored: false - - radius: width / 2 - scale: 2.5 - color: colored ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor - - Behavior on opacity { - NumberAnimation {} - } -} diff --git a/src/imports/controls/material/SliderHandle.qml b/src/imports/controls/material/SliderHandle.qml index 149c2c3f..d8f7ef4f 100644 --- a/src/imports/controls/material/SliderHandle.qml +++ b/src/imports/controls/material/SliderHandle.qml @@ -66,10 +66,11 @@ Item { } Ripple { - width: parent.width - height: width - control: root.control - colored: true - opacity: root.handleHasFocus && !root.handlePressed ? 1 : 0 + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 22; height: 22 + pressed: root.handlePressed + active: root.handlePressed || root.handleHasFocus || control.hovered + color: control.Material.checkBoxUncheckedRippleColor } } diff --git a/src/imports/controls/material/SwitchIndicator.qml b/src/imports/controls/material/SwitchIndicator.qml index e5474356..84898270 100644 --- a/src/imports/controls/material/SwitchIndicator.qml +++ b/src/imports/controls/material/SwitchIndicator.qml @@ -43,7 +43,7 @@ Item { implicitWidth: 38 implicitHeight: 32 - property alias control: ripple.control + property Item control Material.elevation: 1 @@ -51,10 +51,10 @@ Item { id: ripple x: handle.x + handle.width / 2 - width / 2 y: handle.y + handle.height / 2 - height / 2 - width: handle.width - height: width - colored: control.checked - opacity: control.pressed || control.visualFocus ? 1 : 0 + width: 28; height: 28 + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor } Rectangle { diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri index 89d98131..76b865e4 100644 --- a/src/imports/controls/material/material.pri +++ b/src/imports/controls/material/material.pri @@ -1,10 +1,12 @@ HEADERS += \ + $$PWD/qquickmaterialripple_p.h \ $$PWD/qquickmaterialstyle_p.h \ $$PWD/qquickmaterialtheme_p.h \ $$PWD/qquickmaterialprogressring_p.h \ $$PWD/qquickmaterialprogressstrip_p.h SOURCES += \ + $$PWD/qquickmaterialripple.cpp \ $$PWD/qquickmaterialstyle.cpp \ $$PWD/qquickmaterialtheme.cpp \ $$PWD/qquickmaterialprogressring.cpp \ @@ -38,7 +40,6 @@ QML_FILES += \ $$PWD/RadioDelegate.qml \ $$PWD/RadioIndicator.qml \ $$PWD/RangeSlider.qml \ - $$PWD/Ripple.qml \ $$PWD/ScrollBar.qml \ $$PWD/ScrollIndicator.qml \ $$PWD/Slider.qml \ diff --git a/src/imports/controls/material/qquickmaterialripple.cpp b/src/imports/controls/material/qquickmaterialripple.cpp new file mode 100644 index 00000000..1923d554 --- /dev/null +++ b/src/imports/controls/material/qquickmaterialripple.cpp @@ -0,0 +1,396 @@ +/**************************************************************************** +** +** 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 "qquickmaterialripple_p.h" + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace { + enum WavePhase { WaveEnter, WaveExit }; +} + +static const int RIPPLE_ENTER_DELAY = 80; +static const int OPACITY_ENTER_DURATION_FAST = 120; +static const int WAVE_OPACITY_DECAY_DURATION = 333; +static const qreal WAVE_TOUCH_UP_ACCELERATION = 3400.0; +static const qreal WAVE_TOUCH_DOWN_ACCELERATION = 1024.0; + +class QQuickMaterialRippleAnimatorJob : public QQuickAnimatorJob +{ +public: + QQuickMaterialRippleAnimatorJob(WavePhase phase, const QPointF &anchor, const QRectF &bounds); + + void initialize(QQuickAnimatorController *controller) override; + void updateCurrentTime(int time) override; + void writeBack() override; + void nodeWasDestroyed() override; + void afterNodeSync() override; + +private: + qreal m_diameter; + WavePhase m_phase; + QRectF m_bounds; + QPointF m_anchor; + QSGTransformNode *m_itemNode; + QSGOpacityNode *m_opacityNode; + QSGInternalRectangleNode *m_rectNode; +}; + +QQuickMaterialRippleAnimatorJob::QQuickMaterialRippleAnimatorJob(WavePhase phase, const QPointF &anchor, const QRectF &bounds) + : m_diameter(qSqrt(bounds.width() * bounds.width() + bounds.height() * bounds.height())), + m_phase(phase), + m_bounds(bounds), + m_anchor(anchor), + m_itemNode(nullptr), + m_opacityNode(nullptr), + m_rectNode(nullptr) +{ +} + +void QQuickMaterialRippleAnimatorJob::initialize(QQuickAnimatorController *controller) +{ + QQuickAnimatorJob::initialize(controller); + afterNodeSync(); +} + +void QQuickMaterialRippleAnimatorJob::updateCurrentTime(int time) +{ + if (!m_itemNode || !m_rectNode || (m_phase == WaveEnter && time < RIPPLE_ENTER_DELAY)) + return; + + qreal duration = 0; + if (m_phase == WaveEnter) + duration = QQuickAnimatorJob::duration(); + else + duration = 1000.0 * qSqrt((m_diameter - m_from) / 2.0 / (WAVE_TOUCH_UP_ACCELERATION + WAVE_TOUCH_DOWN_ACCELERATION)); + + qreal p = 1.0; + if (!qFuzzyIsNull(duration) && time < duration) + p = time / duration; + + m_value = m_from + (m_to - m_from) * p; + p = m_value / m_diameter; + + const qreal dx = (1.0 - p) * (m_anchor.x() - m_bounds.width() / 2); + const qreal dy = (1.0 - p) * (m_anchor.y() - m_bounds.height() / 2); + + m_rectNode->setRect(QRectF(0, 0, m_value, m_value)); + m_rectNode->setRadius(m_value / 2); + m_rectNode->update(); + + QMatrix4x4 m; + m.translate((m_bounds.width() - m_value) / 2 + dx, + (m_bounds.height() - m_value) / 2 + dy); + m_itemNode->setMatrix(m); + + if (m_opacityNode) { + qreal opacity = 1.0; + if (m_phase == WaveExit) + opacity -= static_cast(time) / WAVE_OPACITY_DECAY_DURATION; + m_opacityNode->setOpacity(opacity); + } +} + +void QQuickMaterialRippleAnimatorJob::writeBack() +{ + if (m_target) + m_target->setSize(QSizeF(m_value, m_value)); + if (m_phase == WaveExit) + m_target->deleteLater(); +} + +void QQuickMaterialRippleAnimatorJob::nodeWasDestroyed() +{ + m_itemNode = nullptr; + m_opacityNode = nullptr; + m_rectNode = nullptr; +} + +void QQuickMaterialRippleAnimatorJob::afterNodeSync() +{ + m_itemNode = QQuickItemPrivate::get(m_target)->itemNode(); + m_opacityNode = QQuickItemPrivate::get(m_target)->opacityNode(); + m_rectNode = static_cast(QQuickItemPrivate::get(m_target)->childContainerNode()->firstChild()); +} + +class QQuickMaterialRippleAnimator : public QQuickAnimator +{ +public: + QQuickMaterialRippleAnimator(const QPointF &anchor, const QRectF &bounds, QObject *parent = nullptr); + + WavePhase phase() const; + void setPhase(WavePhase phase); + +protected: + QString propertyName() const override; + QQuickAnimatorJob *createJob() const override; + +private: + QPointF m_anchor; + QRectF m_bounds; + WavePhase m_phase; +}; + +QQuickMaterialRippleAnimator::QQuickMaterialRippleAnimator(const QPointF &anchor, const QRectF &bounds, QObject *parent) + : QQuickAnimator(parent), m_anchor(anchor), m_bounds(bounds), m_phase(WaveEnter) +{ +} + +WavePhase QQuickMaterialRippleAnimator::phase() const +{ + return m_phase; +} + +void QQuickMaterialRippleAnimator::setPhase(WavePhase phase) +{ + if (m_phase == phase) + return; + + m_phase = phase; +} + +QString QQuickMaterialRippleAnimator::propertyName() const +{ + return QString(); +} + +QQuickAnimatorJob *QQuickMaterialRippleAnimator::createJob() const +{ + return new QQuickMaterialRippleAnimatorJob(m_phase, m_anchor, m_bounds); +} + +QQuickMaterialRipple::QQuickMaterialRipple(QQuickItem *parent) + : QQuickItem(parent), m_active(false), m_pressed(false), m_anchored(false), m_clipRadius(0.0), m_opacityAnimator(nullptr) +{ + setOpacity(0.0); + setFlag(ItemHasContents); +} + +bool QQuickMaterialRipple::isActive() const +{ + return m_active; +} + +void QQuickMaterialRipple::setActive(bool active) +{ + if (active == m_active) + return; + + m_active = active; + + if (!m_opacityAnimator) { + m_opacityAnimator = new QQuickOpacityAnimator(this); + m_opacityAnimator->setTargetItem(this); + } + m_opacityAnimator->setDuration(active ? OPACITY_ENTER_DURATION_FAST : WAVE_OPACITY_DECAY_DURATION); + + const int time = m_opacityAnimator->currentTime(); + m_opacityAnimator->stop(); + m_opacityAnimator->setFrom(opacity()); + m_opacityAnimator->setTo(active ? 1.0 : 0.0); + m_opacityAnimator->setCurrentTime(time); + m_opacityAnimator->start(); +} + +QColor QQuickMaterialRipple::color() const +{ + return m_color; +} + +void QQuickMaterialRipple::setColor(const QColor &color) +{ + if (m_color == color) + return; + + m_color = color; + update(); +} + +qreal QQuickMaterialRipple::clipRadius() const +{ + return m_clipRadius; +} + +void QQuickMaterialRipple::setClipRadius(qreal radius) +{ + if (qFuzzyCompare(m_clipRadius, radius)) + return; + + m_clipRadius = radius; + setClip(!qFuzzyIsNull(radius)); + update(); +} + +bool QQuickMaterialRipple::isPressed() const +{ + return m_pressed; +} + +void QQuickMaterialRipple::setPressed(bool pressed) +{ + if (pressed == m_pressed) + return; + + m_pressed = pressed; + + if (pressed) + enterWave(); + else + exitWave(); +} + +QPointF QQuickMaterialRipple::anchor() const +{ + const QRectF bounds = boundingRect(); + const QPointF center = bounds.center(); + if (!m_anchored) + return center; + + // calculate whether the anchor point is within the ripple circle bounds, + // that is, whether waves should start expanding from the anchor point + const qreal r = qSqrt(bounds.width() * bounds.width() + bounds.height() * bounds.height()) / 2; + if (QLineF(center, m_anchor).length() < r) + return m_anchor; + + // if the anchor point is outside the ripple circle bounds, start expanding + // from the intersection point of the ripple circle and a line from its center + // to the the anchor point + const qreal p = qAtan2(m_anchor.y() - center.y(), m_anchor.x() - center.x()); + return QPointF(center.x() + r * qCos(p), center.y() + r * qSin(p)); +} + +void QQuickMaterialRipple::setAnchor(const QPointF &anchor) +{ + m_anchor = anchor; + m_anchored = true; +} + +void QQuickMaterialRipple::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + + if (change == ItemChildRemovedChange) { + QQuickMaterialRippleAnimator *animator = data.item->findChild(); + if (animator) + m_rippleAnimators.removeOne(animator); + } +} + +QSGNode *QQuickMaterialRipple::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + QQuickDefaultClipNode *clipNode = d->clipNode(); + if (clipNode) { + // TODO: QTBUG-51894 + // clipNode->setRadius(m_clipRadius); + clipNode->setRect(boundingRect()); + clipNode->update(); + } + + const qreal w = width(); + const qreal h = height(); + const qreal sz = qSqrt(w * w + h * h); + + QSGTransformNode *transformNode = static_cast(oldNode); + if (!transformNode) + transformNode = new QSGTransformNode; + + QSGInternalRectangleNode *rectNode = static_cast(transformNode->firstChild()); + if (!rectNode) { + rectNode = d->sceneGraphContext()->createInternalRectangleNode(); + rectNode->setAntialiasing(true); + transformNode->appendChildNode(rectNode); + } + + QMatrix4x4 matrix; + if (qFuzzyIsNull(m_clipRadius)) { + matrix.translate((w - sz) / 2, (h - sz) / 2); + rectNode->setRect(QRectF(0, 0, sz, sz)); + rectNode->setRadius(sz / 2); + } else { + rectNode->setRect(QRectF(0, 0, w, h)); + rectNode->setRadius(m_clipRadius); + } + transformNode->setMatrix(matrix); + rectNode->setColor(m_color); + rectNode->update(); + + return transformNode; +} + +void QQuickMaterialRipple::enterWave() +{ + const qreal w = width(); + const qreal h = height(); + const qreal sz = qSqrt(w * w + h * h); + + QQuickRectangle *wave = new QQuickRectangle(this); + wave->setPosition(QPointF((w - sz) / 2, (h - sz) / 2)); + wave->setSize(QSizeF(sz, sz)); + wave->setRadius(sz / 2); + wave->setColor(color()); + wave->setOpacity(0.0); + + QQuickMaterialRippleAnimator *animator = new QQuickMaterialRippleAnimator(anchor(), boundingRect(), wave); + animator->setDuration(qRound(RIPPLE_ENTER_DELAY + 1000.0 * qSqrt(sz / 2.0 / WAVE_TOUCH_DOWN_ACCELERATION))); + animator->setTargetItem(wave); + animator->setTo(sz); + animator->start(); + m_rippleAnimators += animator; +} + +void QQuickMaterialRipple::exitWave() +{ + for (QQuickMaterialRippleAnimator *animator : m_rippleAnimators) { + if (animator->phase() == WaveEnter) { + animator->stop(); // -> writeBack() -> setSize() + if (QQuickItem *wave = animator->targetItem()) + animator->setFrom(wave->width()); + animator->setDuration(WAVE_OPACITY_DECAY_DURATION); + animator->setPhase(WaveExit); + animator->restart(); + } + } +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/material/qquickmaterialripple_p.h b/src/imports/controls/material/qquickmaterialripple_p.h new file mode 100644 index 00000000..bff714ea --- /dev/null +++ b/src/imports/controls/material/qquickmaterialripple_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QQUICKMATERIALRIPPLE_P_H +#define QQUICKMATERIALRIPPLE_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 + +QT_BEGIN_NAMESPACE + +class QQuickOpacityAnimator; +class QQuickMaterialRippleAnimator; + +class QQuickMaterialRipple : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(qreal clipRadius READ clipRadius WRITE setClipRadius FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed FINAL) + Q_PROPERTY(bool active READ isActive WRITE setActive FINAL) + Q_PROPERTY(QPointF anchor READ anchor WRITE setAnchor FINAL) + +public: + QQuickMaterialRipple(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + qreal clipRadius() const; + void setClipRadius(qreal radius); + + bool isActive() const; + void setActive(bool active); + + bool isPressed() const; + void setPressed(bool pressed); + + QPointF anchor() const; + void setAnchor(const QPointF &anchor); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + + void enterWave(); + void exitWave(); + +private: + bool m_active; + bool m_pressed; + bool m_anchored; + qreal m_clipRadius; + QPointF m_anchor; + QColor m_color; + QQuickOpacityAnimator *m_opacityAnimator; + QVector m_rippleAnimators; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMaterialRipple) + +#endif // QQUICKMATERIALRIPPLE_P_H diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp index 30c10bc1..8214d5ac 100644 --- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp +++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp @@ -40,6 +40,7 @@ #include "qquickmaterialtheme_p.h" #include "qquickmaterialprogressring_p.h" #include "qquickmaterialprogressstrip_p.h" +#include "qquickmaterialripple_p.h" #include #include @@ -89,6 +90,7 @@ void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, c qmlRegisterType(import, 2, 1, "ProgressRing"); qmlRegisterType(import, 2, 1, "ProgressStrip"); qmlRegisterType(import, 2, 1, "RingAnimator"); + qmlRegisterType(import, 2, 1, "Ripple"); qmlRegisterType(import, 2, 1, "StripAnimator"); qmlRegisterType(typeUrl(QStringLiteral("BoxShadow.qml")), import, 2, 1, "BoxShadow"); qmlRegisterType(typeUrl(QStringLiteral("CheckIndicator.qml")), import, 2, 1, "CheckIndicator"); -- cgit v1.2.3