diff options
Diffstat (limited to 'src/imports/controls/material')
64 files changed, 1616 insertions, 419 deletions
diff --git a/src/imports/controls/material/ApplicationWindow.qml b/src/imports/controls/material/ApplicationWindow.qml index db27f25b..0514e5e3 100644 --- a/src/imports/controls/material/ApplicationWindow.qml +++ b/src/imports/controls/material/ApplicationWindow.qml @@ -36,8 +36,8 @@ import QtQuick 2.6 import QtQuick.Window 2.2 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.ApplicationWindow { id: window diff --git a/src/imports/controls/material/BoxShadow.qml b/src/imports/controls/material/BoxShadow.qml index b70fcee5..02950a60 100644 --- a/src/imports/controls/material/BoxShadow.qml +++ b/src/imports/controls/material/BoxShadow.qml @@ -35,9 +35,10 @@ ****************************************************************************/ import QtQuick 2.6 -import QtGraphicalEffects 1.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 -/*! +/* A implementation of CSS's box-shadow, used by ElevationEffect for a Material Design elevation shadow effect. */ diff --git a/src/imports/controls/material/BusyIndicator.qml b/src/imports/controls/material/BusyIndicator.qml index 387ffb71..c2851b91 100644 --- a/src/imports/controls/material/BusyIndicator.qml +++ b/src/imports/controls/material/BusyIndicator.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.BusyIndicator { id: control diff --git a/src/imports/controls/material/Button.qml b/src/imports/controls/material/Button.qml index f2fad313..9ed5263c 100644 --- a/src/imports/controls/material/Button.qml +++ b/src/imports/controls/material/Button.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Button { id: control @@ -53,6 +53,8 @@ T.Button { leftPadding: padding - 4 rightPadding: padding - 4 + hoverEnabled: Qt.styleHints.useHoverEffects + Material.elevation: flat ? control.down || control.hovered ? 2 : 0 : control.down ? 8 : 2 Material.background: flat ? "transparent" : undefined @@ -78,16 +80,19 @@ T.Button { width: parent.width height: parent.height - 12 radius: 2 - color: !control.enabled - ? control.Material.buttonDisabledColor - : control.down - ? control.highlighted ? control.Material.highlightedButtonPressColor - : control.Material.buttonPressColor - : control.visualFocus || control.checked - ? control.highlighted ? control.Material.highlightedButtonHoverColor - : control.Material.buttonHoverColor - : control.highlighted ? control.Material.highlightedButtonColor - : control.Material.buttonColor + color: !control.enabled ? control.Material.buttonDisabledColor : + control.highlighted ? control.Material.highlightedButtonColor : control.Material.buttonColor + + PaddedRectangle { + y: parent.height - 4 + width: parent.width + height: 4 + radius: 2 + topPadding: -2 + clip: true + visible: control.checkable && (!control.highlighted || control.flat) + color: control.checked && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor + } Behavior on color { ColorAnimation { @@ -102,5 +107,16 @@ T.Button { layer.effect: ElevationEffect { elevation: control.Material.elevation } + + Ripple { + clipRadius: 2 + width: parent.width + height: parent.height + trigger: control.flat ? Ripple.Press : Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml index 1c6848d8..290dbe55 100644 --- a/src/imports/controls/material/CheckBox.qml +++ b/src/imports/controls/material/CheckBox.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.CheckBox { id: control @@ -54,10 +54,24 @@ T.CheckBox { topPadding: padding + 7 bottomPadding: padding + 7 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: CheckIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control + + Ripple { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + + z: -1 + anchor: control + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } } contentItem: Text { diff --git a/src/imports/controls/material/CheckDelegate.qml b/src/imports/controls/material/CheckDelegate.qml index d5785467..9fff50d2 100644 --- a/src/imports/controls/material/CheckDelegate.qml +++ b/src/imports/controls/material/CheckDelegate.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.CheckDelegate { id: control @@ -54,6 +54,8 @@ T.CheckDelegate { bottomPadding: 14 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: CheckIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 @@ -76,7 +78,18 @@ T.CheckDelegate { background: Rectangle { implicitHeight: 48 - visible: control.down || control.highlighted - color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/CheckIndicator.qml b/src/imports/controls/material/CheckIndicator.qml index f64ca168..a373bdb8 100644 --- a/src/imports/controls/material/CheckIndicator.qml +++ b/src/imports/controls/material/CheckIndicator.qml @@ -35,7 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 Rectangle { id: indicatorItem @@ -46,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 { @@ -62,15 +63,6 @@ Rectangle { } } - Ripple { - id: ripple - width: parent.width - height: width - control: control - colored: control.checked - opacity: control.down || control.visualFocus ? 1 : 0 - } - // TODO: This needs to be transparent Image { id: checkImage diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index f13c6922..a48c6884 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -36,16 +36,14 @@ import QtQuick 2.6 import QtQuick.Window 2.2 -import QtQuick.Controls 2.0 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Controls 2.1 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.ComboBox { id: control - Material.elevation: control.pressed ? 8 : 2 - implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, @@ -56,21 +54,25 @@ T.ComboBox { spacing: 6 padding: 16 - // Don't use toolTextColor, as that is often white when we have a white background. - Material.foreground: Material.foreground === Material.toolTextColor ? undefined : Material.foreground + hoverEnabled: Qt.styleHints.useHoverEffects + + Material.elevation: flat ? control.pressed || control.hovered ? 2 : 0 + : control.pressed ? 8 : 2 + Material.background: flat ? "transparent" : undefined + Material.foreground: flat ? undefined : Material.foreground delegate: MenuItem { width: control.popup.width text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData - Material.foreground: control.currentIndex === index ? control.Material.accent : control.Material.foreground + Material.foreground: control.currentIndex === index ? control.popup.Material.accent : control.popup.Material.foreground highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled } indicator: Image { x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding y: control.topPadding + (control.availableHeight - height) / 2 - opacity: !control.enabled ? 0.5 : 1.0 - source: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Material/images/drop-indicator.png" + source: "image://material/drop-indicator/" + (control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor) } contentItem: Text { @@ -89,7 +91,7 @@ T.ComboBox { implicitWidth: 120 implicitHeight: 48 - radius: 2 + radius: control.flat ? 0 : 2 color: control.Material.dialogColor Behavior on color { @@ -98,17 +100,21 @@ T.ComboBox { } } - layer.enabled: control.enabled && control.Material.elevation > 0 + layer.enabled: control.enabled && control.Material.background.a > 0 layer.effect: ElevationEffect { elevation: control.Material.elevation } - Rectangle { + Ripple { + clip: control.flat + clipRadius: control.flat ? 0 : 2 width: parent.width height: parent.height - radius: parent.radius - visible: control.visualFocus - color: control.Material.checkBoxUncheckedRippleColor + trigger: Ripple.Press + pressed: control.pressed + anchor: control + active: control.pressed || control.visualFocus || control.hovered + color: control.Material.rippleColor } } @@ -146,7 +152,7 @@ T.ComboBox { background: Rectangle { radius: 2 - color: control.Material.dialogColor + color: control.popup.Material.dialogColor layer.enabled: control.enabled layer.effect: ElevationEffect { diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml index c07cd423..7fbf351c 100644 --- a/src/imports/controls/material/Dial.qml +++ b/src/imports/controls/material/Dial.qml @@ -35,8 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Dial { id: control @@ -44,6 +45,8 @@ T.Dial { implicitWidth: 100 implicitHeight: 100 + hoverEnabled: Qt.styleHints.useHoverEffects + background: Rectangle { x: control.width / 2 - width / 2 y: control.height / 2 - height / 2 @@ -55,7 +58,7 @@ T.Dial { border.color: control.enabled ? control.Material.accentColor : control.Material.hintTextColor } - handle: Rectangle { + handle: SliderHandle { id: handleItem x: background.x + background.width / 2 - handle.width / 2 @@ -72,7 +75,10 @@ T.Dial { ] implicitWidth: 14 implicitHeight: 14 - radius: width / 2 - color: control.enabled ? control.Material.accentColor : control.Material.hintTextColor + + value: control.value + handleHasFocus: control.visualFocus + handlePressed: control.pressed + handleHovered: control.hovered } } diff --git a/src/imports/controls/material/Dialog.qml b/src/imports/controls/material/Dialog.qml new file mode 100644 index 00000000..55ff671b --- /dev/null +++ b/src/imports/controls/material/Dialog.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** 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.Templates 2.1 as T +import QtQuick.Controls 2.1 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 + +T.Dialog { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + header ? header.implicitWidth : 0, + footer ? footer.implicitWidth : 0, + contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + (header ? header.implicitHeight : 0) + (footer ? footer.implicitHeight : 0)) + + (contentHeight > 0 ? contentHeight + topPadding + bottomPadding : 0) + + contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0) + contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0) + + padding: 24 + + Material.elevation: 24 + + enter: Transition { + // grow_fade_in + NumberAnimation { property: "scale"; from: 0.9; to: 1.0; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; easing.type: Easing.OutCubic; duration: 150 } + } + + exit: Transition { + // shrink_fade_out + NumberAnimation { property: "scale"; from: 1.0; to: 0.9; easing.type: Easing.OutQuint; duration: 220 } + NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; easing.type: Easing.OutCubic; duration: 150 } + } + + contentItem: Item { } + + background: Rectangle { + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + buttonBox: DialogButtonBox { + position: DialogButtonBox.Footer + } +} diff --git a/src/imports/controls/material/DialogButtonBox.qml b/src/imports/controls/material/DialogButtonBox.qml new file mode 100644 index 00000000..46a2b3ba --- /dev/null +++ b/src/imports/controls/material/DialogButtonBox.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + + spacing: 8 + padding: 8 + topPadding: padding - 4 + bottomPadding: padding - 4 + alignment: Qt.AlignRight + + Material.foreground: Material.accent + + delegate: Button { flat: true } + + contentItem: ListView { + implicitWidth: contentWidth + implicitHeight: 48 + + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: PaddedRectangle { + implicitHeight: 52 + radius: 2 + color: control.Material.dialogColor + topPadding: control.position === T.DialogButtonBox.Footer ? -2 : 0 + bottomPadding: control.position === T.DialogButtonBox.Header ? -2 : 0 + clip: true + } +} diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml index b3ee94f7..e0b698e2 100644 --- a/src/imports/controls/material/Drawer.qml +++ b/src/imports/controls/material/Drawer.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Drawer { id: control diff --git a/src/imports/controls/material/ElevationEffect.qml b/src/imports/controls/material/ElevationEffect.qml index 4ee4369c..00d7b997 100644 --- a/src/imports/controls/material/ElevationEffect.qml +++ b/src/imports/controls/material/ElevationEffect.qml @@ -35,26 +35,26 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 -/*! +/* An effect for standard Material Design elevation shadows. Useful for using as \c layer.effect. */ Item { id: effect - /*! + /* The source the effect is applied to. */ property var source - /*! + /* The elevation of the \l source Item. */ property int elevation: 0 - /*! + /* Set to \c true if the \l source Item is the same width as its parent and the shadow should be full width instead of rounding around the corner of the Item. @@ -62,7 +62,7 @@ Item { */ property bool fullWidth: false - /*! + /* Set to \c true if the \l source Item is the same height as its parent and the shadow should be full height instead of rounding around the corner of the Item. @@ -70,7 +70,7 @@ Item { */ property bool fullHeight: false - /*! + /* \internal The actual source Item the effect is applied to. @@ -102,7 +102,7 @@ Item { * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - /*! + /* \internal The shadows to use for each possible elevation. There are three shadows that when combined @@ -210,7 +210,7 @@ Item { {offset: 9, blur: 46, spread: 8}] ] - /*! + /* \internal The current shadow based on the elevation. diff --git a/src/imports/controls/material/Frame.qml b/src/imports/controls/material/Frame.qml index c2f623ae..4c8b7f01 100644 --- a/src/imports/controls/material/Frame.qml +++ b/src/imports/controls/material/Frame.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Frame { id: control diff --git a/src/imports/controls/material/GroupBox.qml b/src/imports/controls/material/GroupBox.qml index 6d84197c..48827792 100644 --- a/src/imports/controls/material/GroupBox.qml +++ b/src/imports/controls/material/GroupBox.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.GroupBox { id: control diff --git a/src/imports/controls/material/ItemDelegate.qml b/src/imports/controls/material/ItemDelegate.qml index e43fc981..b9db276d 100644 --- a/src/imports/controls/material/ItemDelegate.qml +++ b/src/imports/controls/material/ItemDelegate.qml @@ -35,8 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.ItemDelegate { id: control @@ -51,6 +52,8 @@ T.ItemDelegate { padding: 16 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + contentItem: Text { leftPadding: control.checkable && !control.mirrored ? (control.indicator ? control.indicator.width : 0) + control.spacing : 0 rightPadding: control.checkable && control.mirrored ? (control.indicator ? control.indicator.width : 0) + control.spacing : 0 @@ -67,7 +70,18 @@ T.ItemDelegate { background: Rectangle { implicitHeight: 48 - visible: control.down || control.highlighted - color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/Label.qml b/src/imports/controls/material/Label.qml index 8bda5cc2..3a69207f 100644 --- a/src/imports/controls/material/Label.qml +++ b/src/imports/controls/material/Label.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.Label { id: control diff --git a/src/imports/controls/material/Menu.qml b/src/imports/controls/material/Menu.qml index b11c00b6..ed21dc46 100644 --- a/src/imports/controls/material/Menu.qml +++ b/src/imports/controls/material/Menu.qml @@ -35,10 +35,10 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Controls 2.1 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Menu { id: control diff --git a/src/imports/controls/material/MenuItem.qml b/src/imports/controls/material/MenuItem.qml index 27c2922c..d3348d35 100644 --- a/src/imports/controls/material/MenuItem.qml +++ b/src/imports/controls/material/MenuItem.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.MenuItem { id: control @@ -54,6 +54,8 @@ T.MenuItem { bottomPadding: 12 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: CheckIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 @@ -77,7 +79,17 @@ T.MenuItem { background: Rectangle { implicitWidth: 200 implicitHeight: 48 - visible: control.down || control.highlighted - color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/Ripple.qml b/src/imports/controls/material/MenuSeparator.qml index 15650384..c6ba401f 100644 --- a/src/imports/controls/material/Ripple.qml +++ b/src/imports/controls/material/MenuSeparator.qml @@ -35,17 +35,21 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 -Rectangle { - property Item control - property bool colored: false +T.MenuSeparator { + id: control - radius: width / 2 - scale: 2.5 - color: colored ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) - Behavior on opacity { - NumberAnimation {} + topPadding: 8 + bottomPadding: 8 + + contentItem: Rectangle { + implicitWidth: 200 + implicitHeight: 1 + color: control.Material.dividerColor } } diff --git a/src/imports/controls/material/Page.qml b/src/imports/controls/material/Page.qml index 92c85b58..f829788e 100644 --- a/src/imports/controls/material/Page.qml +++ b/src/imports/controls/material/Page.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.Page { id: control diff --git a/src/imports/controls/material/PageIndicator.qml b/src/imports/controls/material/PageIndicator.qml index 78372afe..d413adcc 100644 --- a/src/imports/controls/material/PageIndicator.qml +++ b/src/imports/controls/material/PageIndicator.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.PageIndicator { id: control diff --git a/src/imports/controls/material/Pane.qml b/src/imports/controls/material/Pane.qml index 251492ea..d9828a2a 100644 --- a/src/imports/controls/material/Pane.qml +++ b/src/imports/controls/material/Pane.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Pane { id: control diff --git a/src/imports/controls/material/Popup.qml b/src/imports/controls/material/Popup.qml index 19fd6b79..2cd85846 100644 --- a/src/imports/controls/material/Popup.qml +++ b/src/imports/controls/material/Popup.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Popup { id: control diff --git a/src/imports/controls/material/ProgressBar.qml b/src/imports/controls/material/ProgressBar.qml index eb8bf3ce..fa7867e6 100644 --- a/src/imports/controls/material/ProgressBar.qml +++ b/src/imports/controls/material/ProgressBar.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.ProgressBar { id: control diff --git a/src/imports/controls/material/RadioButton.qml b/src/imports/controls/material/RadioButton.qml index 3ea2cf4d..a2450f49 100644 --- a/src/imports/controls/material/RadioButton.qml +++ b/src/imports/controls/material/RadioButton.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.RadioButton { id: control @@ -54,10 +54,24 @@ T.RadioButton { topPadding: padding + 6 bottomPadding: padding + 6 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: RadioIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control + + Ripple { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 28; height: 28 + + z: -1 + anchor: control + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } } contentItem: Text { diff --git a/src/imports/controls/material/RadioDelegate.qml b/src/imports/controls/material/RadioDelegate.qml index 95bfb19b..1d056aa8 100644 --- a/src/imports/controls/material/RadioDelegate.qml +++ b/src/imports/controls/material/RadioDelegate.qml @@ -35,8 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.RadioDelegate { id: control @@ -53,6 +54,8 @@ T.RadioDelegate { bottomPadding: 8 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: RadioIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 @@ -75,7 +78,18 @@ T.RadioDelegate { background: Rectangle { implicitHeight: 48 - visible: control.down || control.highlighted - color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/RadioIndicator.qml b/src/imports/controls/material/RadioIndicator.qml index 4090c732..2a2fabe4 100644 --- a/src/imports/controls/material/RadioIndicator.qml +++ b/src/imports/controls/material/RadioIndicator.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 Rectangle { implicitWidth: 20 @@ -46,16 +46,7 @@ Rectangle { border.color: control.checked || control.down ? control.Material.accentColor : control.Material.secondaryTextColor color: "transparent" - property alias control: ripple.control - - Ripple { - id: ripple - width: parent.width - height: width - control: control - colored: control.checked - opacity: control.down || control.visualFocus ? 1 : 0 - } + property Item control Rectangle { x: (parent.width - width) / 2 diff --git a/src/imports/controls/material/RangeSlider.qml b/src/imports/controls/material/RangeSlider.qml index dc2c25fa..c2672703 100644 --- a/src/imports/controls/material/RangeSlider.qml +++ b/src/imports/controls/material/RangeSlider.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.RangeSlider { id: control @@ -51,12 +51,15 @@ T.RangeSlider { padding: 6 + hoverEnabled: Qt.styleHints.useHoverEffects + first.handle: SliderHandle { x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) value: first.value handleHasFocus: activeFocus handlePressed: first.pressed + handleHovered: first.hovered } second.handle: SliderHandle { @@ -65,6 +68,7 @@ T.RangeSlider { value: second.value handleHasFocus: activeFocus handlePressed: second.pressed + handleHovered: second.hovered } background: Rectangle { diff --git a/src/imports/controls/material/RectangularGlow.qml b/src/imports/controls/material/RectangularGlow.qml new file mode 100644 index 00000000..32c10500 --- /dev/null +++ b/src/imports/controls/material/RectangularGlow.qml @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** 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.0 + +/* + A cross-graphics API implementation of QtGraphicalEffects' RectangularGlow. + */ +Item { + id: rootItem + + /* + This property defines how many pixels outside the item area are reached + by the glow. + + The value ranges from 0.0 (no glow) to inf (infinite glow). By default, + the property is set to \c 0.0. + + \table + \header + \li Output examples with different glowRadius values + \li + \li + \row + \li \image RectangularGlow_glowRadius1.png + \li \image RectangularGlow_glowRadius2.png + \li \image RectangularGlow_glowRadius3.png + \row + \li \b { glowRadius: 10 } + \li \b { glowRadius: 20 } + \li \b { glowRadius: 40 } + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + + */ + property real glowRadius: 0.0 + + /* + This property defines how large part of the glow color is strenghtened + near the source edges. + + The value ranges from 0.0 (no strenght increase) to 1.0 (maximum + strenght increase). By default, the property is set to \c 0.0. + + \table + \header + \li Output examples with different spread values + \li + \li + \row + \li \image RectangularGlow_spread1.png + \li \image RectangularGlow_spread2.png + \li \image RectangularGlow_spread3.png + \row + \li \b { spread: 0.0 } + \li \b { spread: 0.5 } + \li \b { spread: 1.0 } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + */ + property real spread: 0.0 + + /* + This property defines the RGBA color value which is used for the glow. + + By default, the property is set to \c "white". + + \table + \header + \li Output examples with different color values + \li + \li + \row + \li \image RectangularGlow_color1.png + \li \image RectangularGlow_color2.png + \li \image RectangularGlow_color3.png + \row + \li \b { color: #ffffff } + \li \b { color: #55ff55 } + \li \b { color: #5555ff } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \li \l cornerRadius: 25 + \endtable + */ + property color color: "white" + + /* + This property defines the corner radius that is used to draw a glow with + rounded corners. + + The value ranges from 0.0 to half of the effective width or height of + the glow, whichever is smaller. This can be calculated with: \c{ + min(width, height) / 2.0 + glowRadius} + + By default, the property is bound to glowRadius property. The glow + behaves as if the rectangle was blurred when adjusting the glowRadius + property. + + \table + \header + \li Output examples with different cornerRadius values + \li + \li + \row + \li \image RectangularGlow_cornerRadius1.png + \li \image RectangularGlow_cornerRadius2.png + \li \image RectangularGlow_cornerRadius3.png + \row + \li \b { cornerRadius: 0 } + \li \b { cornerRadius: 25 } + \li \b { cornerRadius: 50 } + \row + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \li \l glowRadius: 20 + \row + \li \l spread: 0 + \li \l spread: 0 + \li \l spread: 0 + \row + \li \l color: #ffffff + \li \l color: #ffffff + \li \l color: #ffffff + \endtable + */ + property real cornerRadius: glowRadius + + /* + This property allows the effect output pixels to be cached in order to + improve the rendering performance. + + Every time the source or effect properties are changed, the pixels in + the cache must be updated. Memory consumption is increased, because an + extra buffer of memory is required for storing the effect output. + + It is recommended to disable the cache when the source or the effect + properties are animated. + + By default, the property is set to \c false. + */ + property bool cached: false + + ShaderEffectSource { + id: cacheItem + anchors.fill: shaderItem + visible: rootItem.cached + smooth: true + sourceItem: shaderItem + live: true + hideSource: visible + } + + ShaderEffect { + id: shaderItem + + x: (parent.width - width) / 2.0 + y: (parent.height - height) / 2.0 + width: parent.width + rootItem.glowRadius * 2 + cornerRadius * 2 + height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2 + + function clampedCornerRadius() { + var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + glowRadius; + return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius)) + } + + property color color: rootItem.color + property real inverseSpread: 1.0 - rootItem.spread + property real relativeSizeX: ((inverseSpread * inverseSpread) * rootItem.glowRadius + cornerRadius * 2.0) / width + property real relativeSizeY: relativeSizeX * (width / height) + property real spread: rootItem.spread / 2.0 + property real cornerRadius: clampedCornerRadius() + + fragmentShader: "qrc:/qt-project.org/imports/QtQuick/Controls.2/Material/shaders/RectangularGlow.frag" + } +} diff --git a/src/imports/controls/material/ScrollBar.qml b/src/imports/controls/material/ScrollBar.qml index 84f2d33a..4547a903 100644 --- a/src/imports/controls/material/ScrollBar.qml +++ b/src/imports/controls/material/ScrollBar.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.ScrollBar { id: control @@ -46,33 +46,45 @@ T.ScrollBar { implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) - padding: 2 - topPadding: padding + (control.orientation === Qt.Horizontal ? 12 : 0) - leftPadding: padding + (control.orientation === Qt.Vertical && !control.mirrored ? 12 : 0) - rightPadding: padding + (control.orientation === Qt.Vertical && control.mirrored ? 12 : 0) + padding: 1 + + hoverEnabled: Qt.styleHints.useHoverEffects contentItem: Rectangle { id: handle - implicitWidth: 4 - implicitHeight: 4 + implicitWidth: 13 + implicitHeight: 13 - color: control.pressed ? control.Material.scrollBarPressedColor : control.Material.scrollBarColor + color: control.pressed ? control.Material.scrollBarPressedColor : + control.hovered ? control.Material.scrollBarHoveredColor : control.Material.scrollBarColor visible: control.size < 1.0 opacity: 0.0 + } - states: State { - name: "active" - when: control.active - PropertyChanges { target: handle; opacity: 0.75 } - } + background: Rectangle { + implicitWidth: 16 + implicitHeight: 16 + color: "#0e000000" + opacity: 0.0 + } + + states: State { + name: "active" + when: control.active + } - transitions: Transition { + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 1.0 } + }, + Transition { from: "active" SequentialAnimation { - PauseAnimation { duration: 450 } - NumberAnimation { target: handle; duration: 200; property: "opacity"; to: 0.0 } + PauseAnimation { duration: 2450 } + NumberAnimation { targets: [contentItem, background]; property: "opacity"; to: 0.0 } } } - } + ] } diff --git a/src/imports/controls/material/ScrollIndicator.qml b/src/imports/controls/material/ScrollIndicator.qml index b5f25d33..1e0fd8ff 100644 --- a/src/imports/controls/material/ScrollIndicator.qml +++ b/src/imports/controls/material/ScrollIndicator.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.ScrollIndicator { id: control diff --git a/src/imports/controls/material/Slider.qml b/src/imports/controls/material/Slider.qml index 15c8edb2..dd6063bb 100644 --- a/src/imports/controls/material/Slider.qml +++ b/src/imports/controls/material/Slider.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.Slider { id: control @@ -49,12 +49,15 @@ T.Slider { padding: 6 + hoverEnabled: Qt.styleHints.useHoverEffects + handle: SliderHandle { x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) value: control.value handleHasFocus: control.visualFocus handlePressed: control.pressed + handleHovered: control.hovered } background: Rectangle { diff --git a/src/imports/controls/material/SliderHandle.qml b/src/imports/controls/material/SliderHandle.qml index 49f833d0..1c02cf16 100644 --- a/src/imports/controls/material/SliderHandle.qml +++ b/src/imports/controls/material/SliderHandle.qml @@ -35,7 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 Item { id: root @@ -45,6 +46,7 @@ Item { property real value: 0 property bool handleHasFocus: false property bool handlePressed: false + property bool handleHovered: false readonly property int initialSize: 13 readonly property bool horizontal: control.orientation === Qt.Horizontal readonly property var control: parent @@ -65,10 +67,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 || root.handleHovered + color: control.Material.rippleColor } } diff --git a/src/imports/controls/material/SpinBox.qml b/src/imports/controls/material/SpinBox.qml index 3325f172..74811c16 100644 --- a/src/imports/controls/material/SpinBox.qml +++ b/src/imports/controls/material/SpinBox.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.SpinBox { id: control @@ -58,6 +58,8 @@ T.SpinBox { leftPadding: (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) rightPadding: (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + hoverEnabled: Qt.styleHints.useHoverEffects + validator: IntValidator { locale: control.locale.name bottom: Math.min(control.from, control.to) @@ -104,17 +106,23 @@ T.SpinBox { inputMethodHints: Qt.ImhFormattedNumbersOnly } - up.indicator: PaddedRectangle { + up.indicator: Item { x: control.mirrored ? 0 : parent.width - width implicitWidth: 48 implicitHeight: 48 height: parent.height width: height - padding: control.spacing - radius: 2 - color: Qt.tint(Qt.tint(control.Material.buttonColor, - control.activeFocus ? control.Material.buttonHoverColor : "transparent"), - control.up.pressed ? control.Material.buttonPressColor: "transparent") + + Ripple { + clipRadius: 2 + x: control.spacing + y: control.spacing + width: parent.width - 2 * control.spacing + height: parent.height - 2 * control.spacing + pressed: control.up.pressed + active: control.up.pressed || control.up.hovered || control.visualFocus + color: control.Material.rippleColor + } Rectangle { x: (parent.width - width) / 2 @@ -132,17 +140,23 @@ T.SpinBox { } } - down.indicator: PaddedRectangle { + down.indicator: Item { x: control.mirrored ? parent.width - width : 0 implicitWidth: 48 implicitHeight: 48 height: parent.height width: height - padding: control.spacing - radius: 2 - color: Qt.tint(Qt.tint(control.Material.buttonColor, - control.activeFocus ? control.Material.buttonHoverColor : "transparent"), - control.down.pressed ? control.Material.buttonPressColor : "transparent") + + Ripple { + clipRadius: 2 + x: control.spacing + y: control.spacing + width: parent.width - 2 * control.spacing + height: parent.height - 2 * control.spacing + pressed: control.down.pressed + active: control.down.pressed || control.down.hovered || control.visualFocus + color: control.Material.rippleColor + } Rectangle { x: (parent.width - width) / 2 diff --git a/src/imports/controls/material/StackView.qml b/src/imports/controls/material/StackView.qml index 982a37cb..dcbe0ad0 100644 --- a/src/imports/controls/material/StackView.qml +++ b/src/imports/controls/material/StackView.qml @@ -35,7 +35,7 @@ ****************************************************************************/ import QtQuick 2.4 -import QtQuick.Templates 2.0 as T +import QtQuick.Templates 2.1 as T T.StackView { id: control diff --git a/src/imports/controls/material/SwipeDelegate.qml b/src/imports/controls/material/SwipeDelegate.qml index dec2d12f..bc9b49c2 100644 --- a/src/imports/controls/material/SwipeDelegate.qml +++ b/src/imports/controls/material/SwipeDelegate.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.SwipeDelegate { id: control @@ -54,6 +54,8 @@ T.SwipeDelegate { bottomPadding: 8 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + contentItem: Text { leftPadding: !control.mirrored ? (control.indicator ? control.indicator.width + control.spacing : 0) : 0 rightPadding: control.mirrored ? (control.indicator ? control.indicator.width + control.spacing : 0) : 0 @@ -83,10 +85,21 @@ T.SwipeDelegate { Rectangle { width: parent.width height: parent.height - visible: control.down || control.highlighted || control.visualFocus - color: control.down ? control.Material.buttonPressColor : - control.visualFocus || control.hovered ? control.Material.swipeDelegateHoverColor : - control.Material.listHighlightColor + visible: control.highlighted + color: control.Material.listHighlightColor + } + + Ripple { + width: parent.width + height: parent.height + + clip: visible + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + enabled: control.swipe.position === 0 } Behavior on x { diff --git a/src/imports/controls/material/SwipeView.qml b/src/imports/controls/material/SwipeView.qml index 38c12b6b..0cdd0758 100644 --- a/src/imports/controls/material/SwipeView.qml +++ b/src/imports/controls/material/SwipeView.qml @@ -35,7 +35,7 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T +import QtQuick.Templates 2.1 as T T.SwipeView { id: control @@ -47,6 +47,7 @@ T.SwipeView { contentItem: ListView { model: control.contentModel + interactive: control.interactive currentIndex: control.currentIndex spacing: control.spacing diff --git a/src/imports/controls/material/Switch.qml b/src/imports/controls/material/Switch.qml index ca739e62..32f083f8 100644 --- a/src/imports/controls/material/Switch.qml +++ b/src/imports/controls/material/Switch.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 -import QtQuick.Templates 2.0 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 +import QtQuick.Templates 2.1 as T T.Switch { id: control @@ -52,10 +52,21 @@ T.Switch { padding: 8 spacing: 8 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: SwitchIndicator { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 control: control + + Ripple { + x: parent.handle.x + parent.handle.width / 2 - width / 2 + y: parent.handle.y + parent.handle.height / 2 - height / 2 + width: 28; height: 28 + pressed: control.pressed + active: control.down || control.visualFocus || control.hovered + color: control.checked ? control.Material.highlightedRippleColor : control.Material.rippleColor + } } contentItem: Text { diff --git a/src/imports/controls/material/SwitchDelegate.qml b/src/imports/controls/material/SwitchDelegate.qml index 097f0acd..b88dbe01 100644 --- a/src/imports/controls/material/SwitchDelegate.qml +++ b/src/imports/controls/material/SwitchDelegate.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.SwitchDelegate { id: control @@ -54,6 +54,8 @@ T.SwitchDelegate { bottomPadding: 8 spacing: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + indicator: SwitchIndicator { x: text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 @@ -76,7 +78,18 @@ T.SwitchDelegate { background: Rectangle { implicitHeight: 48 - visible: control.down || control.highlighted - color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor + color: control.highlighted ? control.Material.listHighlightColor : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor + } } } diff --git a/src/imports/controls/material/SwitchIndicator.qml b/src/imports/controls/material/SwitchIndicator.qml index 0d2163b2..114c3956 100644 --- a/src/imports/controls/material/SwitchIndicator.qml +++ b/src/imports/controls/material/SwitchIndicator.qml @@ -35,28 +35,19 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 Item { id: indicator implicitWidth: 38 implicitHeight: 32 - property alias control: ripple.control + property Item control + property alias handle: handle Material.elevation: 1 - Ripple { - 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 - } - Rectangle { width: parent.width height: 14 diff --git a/src/imports/controls/material/TabBar.qml b/src/imports/controls/material/TabBar.qml index 901e3328..5b2c8888 100644 --- a/src/imports/controls/material/TabBar.qml +++ b/src/imports/controls/material/TabBar.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.7 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.TabBar { id: control diff --git a/src/imports/controls/material/TabButton.qml b/src/imports/controls/material/TabButton.qml index 095645b4..9e6e8333 100644 --- a/src/imports/controls/material/TabButton.qml +++ b/src/imports/controls/material/TabButton.qml @@ -35,8 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.TabButton { id: control @@ -49,6 +50,8 @@ T.TabButton { padding: 12 + hoverEnabled: Qt.styleHints.useHoverEffects + contentItem: Text { text: control.text font: control.font @@ -58,7 +61,14 @@ T.TabButton { verticalAlignment: Text.AlignVCenter } - background: Item { + background: Ripple { implicitHeight: 48 + + clip: true + trigger: Ripple.Release + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.Material.rippleColor } } diff --git a/src/imports/controls/material/TextArea.qml b/src/imports/controls/material/TextArea.qml index b37e2311..3a95600e 100644 --- a/src/imports/controls/material/TextArea.qml +++ b/src/imports/controls/material/TextArea.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.TextArea { id: control @@ -51,6 +51,8 @@ T.TextArea { topPadding: 8 bottomPadding: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + color: enabled ? Material.primaryTextColor : Material.hintTextColor selectionColor: Material.accentColor selectedTextColor: Material.primaryHighlightedTextColor diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml index 9c576ca6..a6406afa 100644 --- a/src/imports/controls/material/TextField.qml +++ b/src/imports/controls/material/TextField.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.TextField { id: control @@ -49,6 +49,8 @@ T.TextField { topPadding: 8 bottomPadding: 16 + hoverEnabled: Qt.styleHints.useHoverEffects + color: enabled ? Material.primaryTextColor : Material.hintTextColor selectionColor: Material.accentColor selectedTextColor: Material.primaryHighlightedTextColor diff --git a/src/imports/controls/material/ToolBar.qml b/src/imports/controls/material/ToolBar.qml index 1bcffd82..ce4f64ec 100644 --- a/src/imports/controls/material/ToolBar.qml +++ b/src/imports/controls/material/ToolBar.qml @@ -35,9 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls.Material.impl 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.ToolBar { id: control diff --git a/src/imports/controls/material/ToolButton.qml b/src/imports/controls/material/ToolButton.qml index d8c945a7..df4b23f8 100644 --- a/src/imports/controls/material/ToolButton.qml +++ b/src/imports/controls/material/ToolButton.qml @@ -35,8 +35,9 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 +import QtQuick.Controls.Material.impl 2.1 T.ToolButton { id: control @@ -49,20 +50,33 @@ T.ToolButton { padding: 6 + hoverEnabled: Qt.styleHints.useHoverEffects + contentItem: Text { text: control.text font: control.font - color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + color: !control.enabled ? control.Material.hintTextColor : + control.checked || control.highlighted ? control.Material.accent : control.Material.primaryTextColor elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } - background: Rectangle { + background: Ripple { implicitWidth: 48 implicitHeight: 48 - color: control.down ? control.Material.buttonPressColor : control.Material.buttonHoverColor - visible: control.enabled && (control.down || control.visualFocus || control.checked || control.highlighted) + readonly property bool square: control.contentItem.implicitWidth <= control.contentItem.implicitHeight + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + clip: !square + width: square ? parent.height / 2 : parent.width + height: square ? parent.height / 2 : parent.height + trigger: square ? Ripple.Press : Ripple.Release + pressed: control.pressed + anchor: control + active: control.enabled && (control.down || control.visualFocus || control.hovered) + color: control.Material.rippleColor } } diff --git a/src/imports/controls/material/ToolSeparator.qml b/src/imports/controls/material/ToolSeparator.qml new file mode 100644 index 00000000..f48fffd4 --- /dev/null +++ b/src/imports/controls/material/ToolSeparator.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding) + + leftPadding: vertical ? 12 : 5 + rightPadding: vertical ? 12 : 5 + topPadding: vertical ? 5 : 12 + bottomPadding: vertical ? 5 : 12 + + //! [contentItem] + contentItem: Rectangle { + implicitWidth: vertical ? 1 : 38 + implicitHeight: vertical ? 38 : 1 + color: control.Material.hintTextColor + } + //! [contentItem] +} diff --git a/src/imports/controls/material/ToolTip.qml b/src/imports/controls/material/ToolTip.qml index ab3b05d8..d055bae6 100644 --- a/src/imports/controls/material/ToolTip.qml +++ b/src/imports/controls/material/ToolTip.qml @@ -35,8 +35,8 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.ToolTip { id: control diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml index 7e914319..255d4b5d 100644 --- a/src/imports/controls/material/Tumbler.qml +++ b/src/imports/controls/material/Tumbler.qml @@ -35,9 +35,10 @@ ****************************************************************************/ import QtQuick 2.6 -import QtQuick.Controls 2.0 -import QtQuick.Templates 2.0 as T -import QtQuick.Controls.Material 2.0 +import QtQuick.Controls 2.1 +import QtQuick.Controls.impl 2.1 +import QtQuick.Templates 2.1 as T +import QtQuick.Controls.Material 2.1 T.Tumbler { id: control @@ -54,22 +55,16 @@ T.Tumbler { verticalAlignment: Text.AlignVCenter } - contentItem: PathView { - id: pathView + contentItem: TumblerView { + id: tumblerView model: control.model delegate: control.delegate - clip: true - pathItemCount: control.visibleItemCount + 1 - preferredHighlightBegin: 0.5 - preferredHighlightEnd: 0.5 - dragMargin: width / 2 - path: Path { - startX: pathView.width / 2 - startY: -pathView.delegateHeight / 2 + startX: tumblerView.width / 2 + startY: -tumblerView.delegateHeight / 2 PathLine { - x: pathView.width / 2 - y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + x: tumblerView.width / 2 + y: (control.visibleItemCount + 1) * tumblerView.delegateHeight - tumblerView.delegateHeight / 2 } } diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri index d6247895..437edeee 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 \ @@ -20,6 +22,8 @@ QML_FILES += \ $$PWD/CheckIndicator.qml \ $$PWD/ComboBox.qml \ $$PWD/Dial.qml \ + $$PWD/Dialog.qml \ + $$PWD/DialogButtonBox.qml \ $$PWD/Drawer.qml \ $$PWD/ElevationEffect.qml \ $$PWD/Frame.qml \ @@ -28,6 +32,7 @@ QML_FILES += \ $$PWD/Label.qml \ $$PWD/Menu.qml \ $$PWD/MenuItem.qml \ + $$PWD/MenuSeparator.qml \ $$PWD/Page.qml \ $$PWD/PageIndicator.qml \ $$PWD/Pane.qml \ @@ -37,7 +42,7 @@ QML_FILES += \ $$PWD/RadioDelegate.qml \ $$PWD/RadioIndicator.qml \ $$PWD/RangeSlider.qml \ - $$PWD/Ripple.qml \ + $$PWD/RectangularGlow.qml \ $$PWD/ScrollBar.qml \ $$PWD/ScrollIndicator.qml \ $$PWD/Slider.qml \ @@ -55,5 +60,6 @@ QML_FILES += \ $$PWD/TextField.qml \ $$PWD/ToolBar.qml \ $$PWD/ToolButton.qml \ + $$PWD/ToolSeparator.qml \ $$PWD/ToolTip.qml \ $$PWD/Tumbler.qml diff --git a/src/imports/controls/material/material.pro b/src/imports/controls/material/material.pro index 06499467..363e4861 100644 --- a/src/imports/controls/material/material.pro +++ b/src/imports/controls/material/material.pro @@ -1,6 +1,6 @@ TARGET = qtquickcontrols2materialstyleplugin TARGETPATH = QtQuick/Controls.2/Material -IMPORT_VERSION = 2.0 +IMPORT_VERSION = 2.1 QT += qml quick QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private diff --git a/src/imports/controls/material/qmldir b/src/imports/controls/material/qmldir index 51dafa08..6125e67d 100644 --- a/src/imports/controls/material/qmldir +++ b/src/imports/controls/material/qmldir @@ -2,4 +2,3 @@ module QtQuick.Controls.Material plugin qtquickcontrols2materialstyleplugin classname QtQuickControls2MaterialStylePlugin depends QtQuick.Controls 2.0 -depends QtGraphicalEffects 1.0 diff --git a/src/imports/controls/material/qquickmaterialprogressring.cpp b/src/imports/controls/material/qquickmaterialprogressring.cpp index 8407c7c2..a3564c17 100644 --- a/src/imports/controls/material/qquickmaterialprogressring.cpp +++ b/src/imports/controls/material/qquickmaterialprogressring.cpp @@ -41,8 +41,8 @@ #include <QtCore/qset.h> #include <QtGui/qpainter.h> #include <QtQuick/private/qquickitem_p.h> -#include <QtQuick/qsgsimplerectnode.h> -#include <QtQuick/qsgsimpletexturenode.h> +#include <QtQuick/qsgrectanglenode.h> +#include <QtQuick/qsgimagenode.h> #include <QtQuick/qquickwindow.h> QT_BEGIN_NAMESPACE @@ -79,18 +79,6 @@ private: qreal m_devicePixelRatio; QSGNode *m_containerNode; QQuickWindow *m_window; -}; - -class QQuickMaterialRingTexture : public QSGSimpleTextureNode -{ -public: - QQuickMaterialRingTexture(); - ~QQuickMaterialRingTexture(); - - QColor color() const; - void setColor(QColor color); - -private: QColor m_color; }; @@ -106,14 +94,15 @@ QQuickMaterialProgressRing::~QQuickMaterialProgressRing() QSGNode *QQuickMaterialProgressRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) { - if (!oldNode) - oldNode = new QSGSimpleRectNode(boundingRect(), Qt::transparent); - - static_cast<QSGSimpleRectNode *>(oldNode)->setRect(boundingRect()); + if (!oldNode) { + oldNode = window()->createRectangleNode(); + static_cast<QSGRectangleNode *>(oldNode)->setColor(Qt::transparent); + } + static_cast<QSGRectangleNode *>(oldNode)->setRect(boundingRect()); - QQuickMaterialRingTexture *textureNode = static_cast<QQuickMaterialRingTexture*>(oldNode->firstChild()); + QSGImageNode *textureNode = static_cast<QSGImageNode *>(oldNode->firstChild()); if (!textureNode) { - textureNode = new QQuickMaterialRingTexture; + textureNode = window()->createImageNode(); textureNode->setOwnsTexture(true); oldNode->appendChildNode(textureNode); } @@ -122,7 +111,6 @@ QSGNode *QQuickMaterialProgressRing::updatePaintNode(QSGNode *oldNode, QQuickIte // so just use a blank image. QImage blankImage(width(), height(), QImage::Format_ARGB32_Premultiplied); blankImage.fill(Qt::transparent); - textureNode->setColor(m_color); textureNode->setRect(boundingRect()); textureNode->setTexture(window()->createTextureFromImage(blankImage)); @@ -194,7 +182,7 @@ void QQuickMaterialRingAnimatorJob::updateCurrentTime(int time) if (!m_containerNode) return; - QSGSimpleRectNode *rectNode = static_cast<QSGSimpleRectNode*>(m_containerNode->firstChild()); + QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(m_containerNode->firstChild()); if (!rectNode) return; @@ -209,8 +197,8 @@ void QQuickMaterialRingAnimatorJob::updateCurrentTime(int time) painter.setRenderHint(QPainter::Antialiasing); QPen pen; - QQuickMaterialRingTexture *textureNode = static_cast<QQuickMaterialRingTexture*>(rectNode->firstChild()); - pen.setColor(textureNode->color()); + QSGImageNode *textureNode = static_cast<QSGImageNode *>(rectNode->firstChild()); + pen.setColor(m_color); pen.setWidth(4 * m_devicePixelRatio); painter.setPen(pen); @@ -266,24 +254,7 @@ void QQuickMaterialRingAnimatorJob::nodeWasDestroyed() void QQuickMaterialRingAnimatorJob::afterNodeSync() { m_containerNode = QQuickItemPrivate::get(m_target)->childContainerNode(); -} - -QQuickMaterialRingTexture::QQuickMaterialRingTexture() -{ -} - -QQuickMaterialRingTexture::~QQuickMaterialRingTexture() -{ -} - -QColor QQuickMaterialRingTexture::color() const -{ - return m_color; -} - -void QQuickMaterialRingTexture::setColor(QColor color) -{ - m_color = color; + m_color = static_cast<QQuickMaterialProgressRing *>(m_target.data())->color(); } QT_END_NAMESPACE diff --git a/src/imports/controls/material/qquickmaterialprogressstrip.cpp b/src/imports/controls/material/qquickmaterialprogressstrip.cpp index ce4d676e..542d312f 100644 --- a/src/imports/controls/material/qquickmaterialprogressstrip.cpp +++ b/src/imports/controls/material/qquickmaterialprogressstrip.cpp @@ -38,10 +38,11 @@ #include <QtCore/qmath.h> #include <QtCore/qeasingcurve.h> -#include <QtQuick/qsgsimplerectnode.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickanimatorjob_p.h> #include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuick/qsgrectanglenode.h> +#include <QtQuick/qsgimagenode.h> QT_BEGIN_NAMESPACE @@ -81,7 +82,7 @@ void QQuickMaterialProgressStripAnimatorJob::updateCurrentTime(int time) if (!m_node) return; - QSGSimpleRectNode *geometryNode = static_cast<QSGSimpleRectNode *>(m_node->firstChild()); + QSGRectangleNode *geometryNode = static_cast<QSGRectangleNode *>(m_node->firstChild()); Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType); if (!geometryNode) return; @@ -128,7 +129,7 @@ void QQuickMaterialProgressStripAnimatorJob::moveNode(QSGTransformNode *transfor matrix.translate(x, 0); transformNode->setMatrix(matrix); - QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(transformNode->firstChild()); + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild()); Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); QRectF r = geometry; @@ -211,9 +212,11 @@ QSGNode *QQuickMaterialProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePa bounds.setHeight(implicitHeight()); bounds.moveTop((height() - bounds.height()) / 2.0); - if (!oldNode) - oldNode = new QSGSimpleRectNode(bounds, Qt::transparent); - static_cast<QSGSimpleRectNode *>(oldNode)->setRect(bounds); + 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(); @@ -225,14 +228,14 @@ QSGNode *QQuickMaterialProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePa transformNode = new QSGTransformNode; oldNode->appendChildNode(transformNode); - QSGRectangleNode *rectNode = d->sceneGraphContext()->createRectangleNode(); + QSGInternalRectangleNode *rectNode = d->sceneGraphContext()->createInternalRectangleNode(); rectNode->setAntialiasing(true); transformNode->appendChildNode(rectNode); } Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); static_cast<QSGTransformNode *>(transformNode)->setMatrix(QMatrix4x4()); - QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(transformNode->firstChild()); + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(transformNode->firstChild()); Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); rectNode->setRect(rect); diff --git a/src/imports/controls/material/qquickmaterialripple.cpp b/src/imports/controls/material/qquickmaterialripple.cpp new file mode 100644 index 00000000..645b0289 --- /dev/null +++ b/src/imports/controls/material/qquickmaterialripple.cpp @@ -0,0 +1,451 @@ +/**************************************************************************** +** +** 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 <QtCore/qmath.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickanimator_p.h> +#include <QtQuick/private/qquickrectangle_p.h> +#include <QtQuick/private/qquickanimatorjob_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p_p.h> + +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) + 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<qreal>(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<QSGInternalRectangleNode *>(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_enterDelay(0), m_trigger(Press), m_clipRadius(0.0), m_anchor(nullptr), 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 (!isEnabled()) + return; + + if (pressed) { + if (m_trigger == Press) + prepareWave(); + else + exitWave(); + } else { + if (m_trigger == Release) + enterWave(); + else + exitWave(); + } +} + +QQuickMaterialRipple::Trigger QQuickMaterialRipple::trigger() const +{ + return m_trigger; +} + +void QQuickMaterialRipple::setTrigger(Trigger trigger) +{ + m_trigger = trigger; +} + +QPointF QQuickMaterialRipple::anchorPoint() const +{ + const QRectF bounds = boundingRect(); + const QPointF center = bounds.center(); + if (!m_anchor) + return center; + + QPointF anchorPoint = bounds.center(); + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(m_anchor)) + anchorPoint = QQuickAbstractButtonPrivate::get(button)->pressPoint; + anchorPoint = mapFromItem(m_anchor, anchorPoint); + + // 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, anchorPoint).length() < r) + return anchorPoint; + + // 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(anchorPoint.y() - center.y(), anchorPoint.x() - center.x()); + return QPointF(center.x() + r * qCos(p), center.y() + r * qSin(p)); +} + +QQuickItem *QQuickMaterialRipple::anchor() const +{ + return m_anchor; +} + +void QQuickMaterialRipple::setAnchor(QQuickItem *item) +{ + m_anchor = item; +} + +void QQuickMaterialRipple::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + + if (change == ItemChildRemovedChange) { + QQuickMaterialRippleAnimator *animator = data.item->findChild<QQuickMaterialRippleAnimator *>(); + 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<QSGTransformNode *>(oldNode); + if (!transformNode) + transformNode = new QSGTransformNode; + + QSGInternalRectangleNode *rectNode = static_cast<QSGInternalRectangleNode *>(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::timerEvent(QTimerEvent *event) +{ + QQuickItem::timerEvent(event); + + if (event->timerId() == m_enterDelay) + enterWave(); +} + +void QQuickMaterialRipple::prepareWave() +{ + if (m_enterDelay <= 0) + m_enterDelay = startTimer(RIPPLE_ENTER_DELAY); +} + +void QQuickMaterialRipple::enterWave() +{ + if (m_enterDelay > 0) { + killTimer(m_enterDelay); + m_enterDelay = 0; + } + + 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(anchorPoint(), boundingRect(), wave); + animator->setDuration(qRound(1000.0 * qSqrt(sz / 2.0 / WAVE_TOUCH_DOWN_ACCELERATION))); + animator->setTargetItem(wave); + animator->setTo(sz); + animator->start(); + m_rippleAnimators += animator; +} + +void QQuickMaterialRipple::exitWave() +{ + if (m_enterDelay > 0) { + killTimer(m_enterDelay); + m_enterDelay = 0; + } + + 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..a1cfed94 --- /dev/null +++ b/src/imports/controls/material/qquickmaterialripple_p.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 <QtQuick/qquickitem.h> + +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(QQuickItem *anchor READ anchor WRITE setAnchor FINAL) + Q_PROPERTY(Trigger trigger READ trigger WRITE setTrigger 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); + + enum Trigger { Press, Release }; + Q_ENUM (Trigger) + + Trigger trigger() const; + void setTrigger(Trigger trigger); + + QPointF anchorPoint() const; + + QQuickItem *anchor() const; + void setAnchor(QQuickItem *anchor); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + void timerEvent(QTimerEvent *event) override; + + void prepareWave(); + void enterWave(); + void exitWave(); + +private: + bool m_active; + bool m_pressed; + int m_enterDelay; + Trigger m_trigger; + qreal m_clipRadius; + QColor m_color; + QQuickItem *m_anchor; + QQuickOpacityAnimator *m_opacityAnimator; + QVector<QQuickMaterialRippleAnimator *> m_rippleAnimators; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickMaterialRipple) + +#endif // QQUICKMATERIALRIPPLE_P_H diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index 9361e535..76332c51 100644 --- a/src/imports/controls/material/qquickmaterialstyle.cpp +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -404,37 +404,24 @@ static const QRgb raisedButtonColorLight = 0xFFD6D7D7; static const QRgb raisedButtonColorDark = 0x3FCCCCCC; static const QRgb raisedButtonDisabledColorLight = dividerColorLight; static const QRgb raisedButtonDisabledColorDark = dividerColorDark; -static const QRgb flatButtonPressColorLight = 0x66999999; -static const QRgb flatButtonPressColorDark = 0x3FCCCCCC; -static const QRgb flatButtonFocusColorLight = 0x33CCCCCC; -static const QRgb flatButtonFocusColorDark = 0x26CCCCCC; -static const QRgb swipeDelegateColorLight = 0xFFD6D7D7; -static const QRgb swipeDelegateColorDark = 0xFF525252; -static const QRgb swipeDelegateHoverColorLight = 0xFFDFDFDF; -static const QRgb swipeDelegateHoverColorDark = 0xFF5D5D5D; -static const QRgb swipeDelegatePressColorLight = 0xFFCFCFCF; -static const QRgb swipeDelegatePressColorDark = 0xFF484848; -static const QRgb swipeDelegateDisabledColorLight = 0xFFEFEFEF; -static const QRgb swipeDelegateDisabledColorDark = 0xFF7C7C7C; static const QRgb frameColorLight = hintTextColorLight; static const QRgb frameColorDark = hintTextColorDark; static const QRgb switchUncheckedTrackColorLight = 0x42000000; static const QRgb switchUncheckedTrackColorDark = 0x4CFFFFFF; static const QRgb switchDisabledTrackColorLight = 0x1E000000; static const QRgb switchDisabledTrackColorDark = 0x19FFFFFF; -static const QRgb checkBoxUncheckedRippleColorLight = 0x10000000; -static const QRgb checkBoxUncheckedRippleColorDark = 0x20FFFFFF; +static const QRgb rippleColorLight = 0x10000000; +static const QRgb rippleColorDark = 0x20FFFFFF; static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC; static const QRgb spinBoxDisabledIconColorDark = 0xFF666666; -static QColor alphaBlend(const QColor &bg, const QColor &fg) +extern bool qt_is_dark_system_theme(); + +static QQuickMaterialStyle::Theme effectiveTheme(QQuickMaterialStyle::Theme theme) { - QColor result; - result.setRedF(fg.redF() * fg.alphaF() + bg.redF() * (1.0 - fg.alphaF())); - result.setGreenF(fg.greenF() * fg.alphaF() + bg.greenF() * (1.0 - fg.alphaF())); - result.setBlueF(fg.blueF() * fg.alphaF() + bg.blueF() * (1.0 - fg.alphaF())); - result.setAlphaF(bg.alphaF() + fg.alphaF() * (1.0 - bg.alphaF())); - return result; + if (theme == QQuickMaterialStyle::System) + theme = qt_is_dark_system_theme() ? QQuickMaterialStyle::Dark : QQuickMaterialStyle::Light; + return theme; } QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyleAttached(parent), @@ -471,6 +458,9 @@ QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const void QQuickMaterialStyle::setTheme(Theme theme) { + if (theme == System) + theme = qt_is_dark_system_theme() ? Dark : Light; + m_explicitTheme = true; if (m_theme == theme) return; @@ -858,10 +848,9 @@ QColor QQuickMaterialStyle::dividerColor() const return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark); } -QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool pressed, bool hover) const +QColor QQuickMaterialStyle::buttonColor(bool highlighted) const { - Shade shade = pressed ? (m_theme == Light ? Shade700 : Shade100) - : themeShade(); + Shade shade = themeShade(); QColor color = Qt::transparent; @@ -872,45 +861,14 @@ QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool pressed, bool hov } else if (elevation() > 0) { color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight : raisedButtonColorDark); - - if (pressed) { - color = this->shade(color, shade); - } - } - - if (color == Qt::transparent) { - if (pressed) { - return QColor::fromRgba(m_theme == Light ? flatButtonPressColorLight - : flatButtonPressColorDark); - } else if (hover) { - return QColor::fromRgba(m_theme == Light ? flatButtonFocusColorLight - : flatButtonFocusColorDark); - } else { - return color; - } } - if (pressed || hover) { - // Add overlaying black shadow 12% opacity - return alphaBlend(color, QColor::fromRgba(0x1F000000)); - } else { - return color; - } + return color; } QColor QQuickMaterialStyle::buttonColor() const { - return buttonColor(false, false, false); -} - -QColor QQuickMaterialStyle::buttonHoverColor() const -{ - return buttonColor(false, false, true); -} - -QColor QQuickMaterialStyle::buttonPressColor() const -{ - return buttonColor(false, true, false); + return buttonColor(false); } QColor QQuickMaterialStyle::buttonDisabledColor() const @@ -925,37 +883,7 @@ QColor QQuickMaterialStyle::buttonDisabledColor() const QColor QQuickMaterialStyle::highlightedButtonColor() const { - return buttonColor(true, false, false); -} - -QColor QQuickMaterialStyle::highlightedButtonHoverColor() const -{ - return buttonColor(true, false, true); -} - -QColor QQuickMaterialStyle::highlightedButtonPressColor() const -{ - return buttonColor(true, true, false); -} - -QColor QQuickMaterialStyle::swipeDelegateColor() const -{ - return QColor::fromRgba(m_theme == Light ? swipeDelegateColorLight : swipeDelegateColorDark); -} - -QColor QQuickMaterialStyle::swipeDelegateHoverColor() const -{ - return QColor::fromRgba(m_theme == Light ? swipeDelegateHoverColorLight : swipeDelegateHoverColorDark); -} - -QColor QQuickMaterialStyle::swipeDelegatePressColor() const -{ - return QColor::fromRgba(m_theme == Light ? swipeDelegatePressColorLight : swipeDelegatePressColorDark); -} - -QColor QQuickMaterialStyle::swipeDelegateDisabledColor() const -{ - return QColor::fromRgba(m_theme == Light ? swipeDelegateDisabledColorLight : swipeDelegateDisabledColorDark); + return buttonColor(true); } QColor QQuickMaterialStyle::frameColor() const @@ -963,12 +891,12 @@ QColor QQuickMaterialStyle::frameColor() const return QColor::fromRgba(m_theme == Light ? frameColorLight : frameColorDark); } -QColor QQuickMaterialStyle::checkBoxUncheckedRippleColor() const +QColor QQuickMaterialStyle::rippleColor() const { - return QColor::fromRgba(m_theme == Light ? checkBoxUncheckedRippleColorLight : checkBoxUncheckedRippleColorDark); + return QColor::fromRgba(m_theme == Light ? rippleColorLight : rippleColorDark); } -QColor QQuickMaterialStyle::checkBoxCheckedRippleColor() const +QColor QQuickMaterialStyle::highlightedRippleColor() const { QColor pressColor = accentColor(); pressColor.setAlpha(m_theme == Light ? 30 : 50); @@ -1012,6 +940,11 @@ QColor QQuickMaterialStyle::scrollBarColor() const return QColor::fromRgba(m_theme == Light ? 0x40000000 : 0x40FFFFFF); } +QColor QQuickMaterialStyle::scrollBarHoveredColor() const +{ + return QColor::fromRgba(m_theme == Light ? 0x60000000 : 0x60FFFFFF); +} + QColor QQuickMaterialStyle::scrollBarPressedColor() const { return QColor::fromRgba(m_theme == Light ? 0x80000000 : 0x80FFFFFF); @@ -1024,7 +957,9 @@ QColor QQuickMaterialStyle::drawerBackgroundColor() const QColor QQuickMaterialStyle::dialogColor() const { - return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark); + if (!m_hasBackground) + return QColor::fromRgba(m_theme == Light ? dialogColorLight : dialogColorDark); + return backgroundColor(); } QColor QQuickMaterialStyle::backgroundDimColor() const @@ -1217,7 +1152,7 @@ void QQuickMaterialStyle::init() QByteArray themeValue = resolveSetting("QT_QUICK_CONTROLS_MATERIAL_THEME", settings, QStringLiteral("Theme")); Theme themeEnum = toEnumValue<Theme>(themeValue, &ok); if (ok) - globalTheme = m_theme = themeEnum; + globalTheme = m_theme = effectiveTheme(themeEnum); else if (!themeValue.isEmpty()) qWarning().nospace().noquote() << "Material: unknown theme value: " << themeValue; diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h index 044d30d9..78ba88da 100644 --- a/src/imports/controls/material/qquickmaterialstyle_p.h +++ b/src/imports/controls/material/qquickmaterialstyle_p.h @@ -77,19 +77,11 @@ class QQuickMaterialStyle : public QQuickStyleAttached Q_PROPERTY(QColor dropShadowColor READ dropShadowColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor buttonHoverColor READ buttonHoverColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor buttonPressColor READ buttonPressColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor highlightedButtonHoverColor READ highlightedButtonHoverColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor highlightedButtonPressColor READ highlightedButtonPressColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor swipeDelegateColor READ swipeDelegateColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor swipeDelegateHoverColor READ swipeDelegateHoverColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor swipeDelegatePressColor READ swipeDelegatePressColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor swipeDelegateDisabledColor READ swipeDelegateDisabledColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor frameColor READ frameColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor checkBoxUncheckedRippleColor READ checkBoxUncheckedRippleColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor checkBoxCheckedRippleColor READ checkBoxCheckedRippleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor rippleColor READ rippleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor highlightedRippleColor READ highlightedRippleColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY paletteChanged FINAL) @@ -97,6 +89,7 @@ class QQuickMaterialStyle : public QQuickStyleAttached Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor drawerBackgroundColor READ drawerBackgroundColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dialogColor READ dialogColor NOTIFY paletteChanged FINAL) @@ -109,7 +102,8 @@ class QQuickMaterialStyle : public QQuickStyleAttached public: enum Theme { Light, - Dark + Dark, + System }; enum Color { @@ -204,20 +198,12 @@ public: QColor dropShadowColor() const; QColor dividerColor() const; QColor buttonColor() const; - QColor buttonHoverColor() const; - QColor buttonPressColor() const; QColor buttonDisabledColor() const; QColor highlightedButtonColor() const; - QColor highlightedButtonHoverColor() const; - QColor highlightedButtonPressColor() const; QColor highlightedButtonDisabledColor() const; - QColor swipeDelegateColor() const; - QColor swipeDelegateHoverColor() const; - QColor swipeDelegatePressColor() const; - QColor swipeDelegateDisabledColor() const; QColor frameColor() const; - QColor checkBoxUncheckedRippleColor() const; - QColor checkBoxCheckedRippleColor() const; + QColor rippleColor() const; + QColor highlightedRippleColor() const; QColor switchUncheckedTrackColor() const; QColor switchCheckedTrackColor() const; QColor switchUncheckedHandleColor() const; @@ -225,6 +211,7 @@ public: QColor switchDisabledTrackColor() const; QColor switchDisabledHandleColor() const; QColor scrollBarColor() const; + QColor scrollBarHoveredColor() const; QColor scrollBarPressedColor() const; QColor drawerBackgroundColor() const; QColor dialogColor() const; @@ -256,7 +243,7 @@ private: QColor backgroundColor(Shade shade) const; QColor accentColor(Shade shade) const; - QColor buttonColor(bool highlighted, bool pressed, bool hover) const; + QColor buttonColor(bool highlighted) const; Shade themeShade() const; // These reflect whether a color value was explicitly set on the specific diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp index ac11e95b..27d2c5a6 100644 --- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp +++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp @@ -40,9 +40,11 @@ #include "qquickmaterialtheme_p.h" #include "qquickmaterialprogressring_p.h" #include "qquickmaterialprogressstrip_p.h" +#include "qquickmaterialripple_p.h" #include <QtQuickControls2/private/qquickstyleselector_p.h> #include <QtQuickControls2/private/qquickpaddedrectangle_p.h> +#include <QtQuickControls2/private/qquickcolorimageprovider_p.h> static inline void initResources() { @@ -77,22 +79,27 @@ QtQuickControls2MaterialStylePlugin::QtQuickControls2MaterialStylePlugin(QObject void QtQuickControls2MaterialStylePlugin::registerTypes(const char *uri) { qmlRegisterUncreatableType<QQuickMaterialStyle>(uri, 2, 0, "Material", tr("Material is an attached property")); + qmlRegisterRevision<QQuickMaterialStyle, 1>(uri, 2, 1); } void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri) { QQuickStylePlugin::initializeEngine(engine, uri); + engine->addImageProvider(name(), new QQuickColorImageProvider(QStringLiteral(":/qt-project.org/imports/QtQuick/Controls.2/Material/images"))); + 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<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"); - qmlRegisterType(typeUrl(QStringLiteral("Ripple.qml")), import, 2, 0, "Ripple"); + qmlRegisterType(typeUrl(QStringLiteral("RectangularGlow.qml")), import, 2, 0, "RectangularGlow"); qmlRegisterType(typeUrl(QStringLiteral("SliderHandle.qml")), import, 2, 0, "SliderHandle"); qmlRegisterType(typeUrl(QStringLiteral("SwitchIndicator.qml")), import, 2, 0, "SwitchIndicator"); } diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc index 47257ce4..e2cc90fa 100644 --- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc +++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.qrc @@ -8,5 +8,8 @@ <file>images/drop-indicator@2x.png</file> <file>images/drop-indicator@3x.png</file> <file>images/drop-indicator@4x.png</file> + <file>shaders/RectangularGlow.frag</file> + <file>shaders/+glslcore/RectangularGlow.frag</file> + <file>shaders/+hlsl/RectangularGlow.frag</file> </qresource> </RCC> diff --git a/src/imports/controls/material/shaders/+glslcore/RectangularGlow.frag b/src/imports/controls/material/shaders/+glslcore/RectangularGlow.frag new file mode 100644 index 00000000..432d86b5 --- /dev/null +++ b/src/imports/controls/material/shaders/+glslcore/RectangularGlow.frag @@ -0,0 +1,25 @@ +#version 150 + +uniform float qt_Opacity; +uniform float relativeSizeX; +uniform float relativeSizeY; +uniform float spread; +uniform vec4 color; + +in vec2 qt_TexCoord0; +out vec4 fragColor; + +float linearstep(float e0, float e1, float x) +{ + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() +{ + float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + fragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/imports/controls/material/shaders/+hlsl/RectangularGlow.frag b/src/imports/controls/material/shaders/+hlsl/RectangularGlow.frag new file mode 100644 index 00000000..69d9f852 --- /dev/null +++ b/src/imports/controls/material/shaders/+hlsl/RectangularGlow.frag @@ -0,0 +1,21 @@ +cbuffer ConstantBuffer : register(b0) +{ + float4x4 qt_Matrix; + float qt_Opacity; + float relativeSizeX; + float relativeSizeY; + float spread; + float4 color; +} + +float linearstep(float e0, float e1, float x) { return clamp((x - e0) / (e1 - e0), 0.0, 1.0); } + +float4 main(float4 position : SV_POSITION, float2 coord : TEXCOORD0) : SV_TARGET +{ + float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - coord.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - coord.y)); + + float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + return color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} diff --git a/src/imports/controls/material/shaders/RectangularGlow.frag b/src/imports/controls/material/shaders/RectangularGlow.frag new file mode 100644 index 00000000..40bab580 --- /dev/null +++ b/src/imports/controls/material/shaders/RectangularGlow.frag @@ -0,0 +1,19 @@ +uniform highp float qt_Opacity; +uniform mediump float relativeSizeX; +uniform mediump float relativeSizeY; +uniform mediump float spread; +uniform lowp vec4 color; +varying highp vec2 qt_TexCoord0; + +highp float linearstep(highp float e0, highp float e1, highp float x) { + return clamp((x - e0) / (e1 - e0), 0.0, 1.0); +} + +void main() { + lowp float alpha = + smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) * + smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y)); + + highp float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha); + gl_FragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier; +} |