diff options
author | Michael Spencer <sonrisesoftware@gmail.com> | 2016-04-29 10:36:52 -0500 |
---|---|---|
committer | Michael Spencer <sonrisesoftware@gmail.com> | 2016-05-04 19:49:46 +0000 |
commit | 251afe3eaac3367c5c659dddc1e8854f833d5112 (patch) | |
tree | b746a7a99b148f44b9da9f7008cbe814c1193438 /src/imports/controls/material | |
parent | aa6af36630b6aa07c8b67dfd4cbdcfecc8362cb1 (diff) |
Material: Add proper elevation support
- Added an ElevationEffect component based on elevation shadows from Angular Material
- Use it on Button, ToolBar, ComboBox, Drawer, Pane, Popup, Menu, and Switch
- Add an elevation property to the Material attached object
- Update the button colors based on the elevation property
Change-Id: I5152e1a56bdcb1016cc4f945a16ef510e0cdece6
Task-number: QTBUG-51276
Reviewed-by: Nikita Krupenko <krnekit@gmail.com>
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src/imports/controls/material')
22 files changed, 554 insertions, 114 deletions
diff --git a/src/imports/controls/material/BoxShadow.qml b/src/imports/controls/material/BoxShadow.qml new file mode 100644 index 00000000..b70fcee5 --- /dev/null +++ b/src/imports/controls/material/BoxShadow.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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 QtGraphicalEffects 1.0 + +/*! + A implementation of CSS's box-shadow, used by ElevationEffect for a Material Design + elevation shadow effect. + */ +RectangularGlow { + // The 4 properties from CSS box-shadow, plus the inherited color property + property int offsetX + property int offsetY + property int blurRadius + property int spreadRadius + + // The source item the shadow is being applied to, used for correctly + // calculating the corner radious + property Item source + + property bool fullWidth + property bool fullHeight + + x: (parent.width - width)/2 + offsetX + y: (parent.height - height)/2 + offsetY + + implicitWidth: source ? source.width : parent.width + implicitHeight: source ? source.height : parent.height + + width: implicitWidth + 2 * spreadRadius + (fullWidth ? 2 * cornerRadius : 0) + height: implicitHeight + 2 * spreadRadius + (fullHeight ? 2 * cornerRadius : 0) + glowRadius: blurRadius/2 + spread: 0.05 + cornerRadius: blurRadius + (source && source.radius || 0) +} diff --git a/src/imports/controls/material/Button.qml b/src/imports/controls/material/Button.qml index 6ef27a5a..027e4e16 100644 --- a/src/imports/controls/material/Button.qml +++ b/src/imports/controls/material/Button.qml @@ -37,11 +37,21 @@ 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 QtGraphicalEffects 1.0 T.Button { id: control + // TODO: Add a flat property to T.Button, and make this: + // flat ? control.down || control.hovered ? 2 : 0 + // : control.down ? 8 : 2 + // See https://bugreports.qt.io/browse/QTBUG-51054 + // NOTE: Flat buttons should be transparent by default and have no elevation when pressed + // However, on the desktop, flat buttons can be colored and have a 2dp when pressed + // This is called a flat raised button + Material.elevation: control.down ? 8 : 2 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, @@ -66,6 +76,7 @@ T.Button { //! [contentItem] //! [background] + // TODO: Add a proper ripple/ink effect for mouse/touch input and focus state background: Rectangle { implicitWidth: 64 implicitHeight: 48 @@ -75,10 +86,16 @@ T.Button { width: parent.width height: parent.height - 12 radius: 2 - color: !control.enabled ? (control.highlighted ? control.Material.raisedHighlightedButtonDisabledColor : control.Material.raisedButtonDisabledColor) : - (control.down ? (control.highlighted ? control.Material.raisedHighlightedButtonPressColor : control.Material.raisedButtonPressColor) : - (control.visualFocus ? (control.highlighted ? control.Material.raisedHighlightedButtonHoverColor : control.Material.raisedButtonHoverColor) : - (control.highlighted ? control.Material.raisedHighlightedButtonColor : control.Material.raisedButtonColor))) + color: !control.enabled + ? control.Material.buttonDisabledColor + : control.down + ? control.highlighted ? control.Material.highlightedButtonPressColor + : control.Material.buttonPressColor + : control.visualFocus + ? control.highlighted ? control.Material.highlightedButtonHoverColor + : control.Material.buttonHoverColor + : control.highlighted ? control.Material.highlightedButtonColor + : control.Material.buttonColor Behavior on color { ColorAnimation { @@ -86,20 +103,12 @@ T.Button { } } - Rectangle { - width: parent.width - height: parent.height - radius: parent.radius - visible: control.visualFocus - color: control.Material.checkBoxUncheckedRippleColor - } - - layer.enabled: control.enabled - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - samples: control.down ? 15 : 9 - spread: 0.5 + // The layer is disabled when the button color is transparent so you can do + // Material.background: "transparent" and get a proper flat button without needing + // to set Material.elevation as well + layer.enabled: control.enabled && control.Material.buttonColor.a > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation } } //! [background] diff --git a/src/imports/controls/material/CheckDelegate.qml b/src/imports/controls/material/CheckDelegate.qml index fc8b6397..e3143a2b 100644 --- a/src/imports/controls/material/CheckDelegate.qml +++ b/src/imports/controls/material/CheckDelegate.qml @@ -80,7 +80,7 @@ T.CheckDelegate { implicitHeight: 48 visible: control.down || control.highlighted - color: control.down ? control.Material.flatButtonPressColor : control.Material.listHighlightColor + color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor } //! [background] } diff --git a/src/imports/controls/material/ComboBox.qml b/src/imports/controls/material/ComboBox.qml index 99e2f0f2..0dec9bf6 100644 --- a/src/imports/controls/material/ComboBox.qml +++ b/src/imports/controls/material/ComboBox.qml @@ -39,11 +39,14 @@ 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 QtGraphicalEffects 1.0 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, @@ -100,12 +103,9 @@ T.ComboBox { } } - layer.enabled: control.enabled - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - samples: control.pressed ? 15 : 9 - spread: 0.5 + layer.enabled: control.enabled && control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation } Rectangle { @@ -156,11 +156,8 @@ T.ComboBox { color: control.Material.dialogColor layer.enabled: control.enabled - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - samples: 15 - spread: 0.5 + layer.effect: ElevationEffect { + elevation: 8 } } } diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml index b7d7cfc5..a546e041 100644 --- a/src/imports/controls/material/Drawer.qml +++ b/src/imports/controls/material/Drawer.qml @@ -38,6 +38,7 @@ import QtQuick 2.6 import QtGraphicalEffects 1.0 import QtQuick.Templates 2.0 as T import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material.impl 2.0 T.Drawer { id: control @@ -65,12 +66,9 @@ T.Drawer { color: control.Material.dialogColor layer.enabled: control.position > 0 - layer.effect: DropShadow { - horizontalOffset: control.edge === Qt.LeftEdge ? 1 : control.edge === Qt.RightEdge ? -1 : 0 - verticalOffset: control.edge === Qt.TopEdge ? 1 : control.edge === Qt.BottomEdge ? -1 : 0 - color: control.Material.dropShadowColor - samples: 15 - spread: 0.5 + layer.effect: ElevationEffect { + elevation: 16 + fullHeight: true } } //! [background] diff --git a/src/imports/controls/material/ElevationEffect.qml b/src/imports/controls/material/ElevationEffect.qml new file mode 100644 index 00000000..93a32f83 --- /dev/null +++ b/src/imports/controls/material/ElevationEffect.qml @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material.impl 2.0 + +/*! + 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. + + \sa fullHeight + */ + 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. + + \sa fullWidth + */ + property bool fullHeight: false + + /*! + \internal + + The actual source Item the effect is applied to. + */ + readonly property Item sourceItem: source.sourceItem + + /* + * The following shadow values are taken from Angular Material + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2016 Google, Inc. http://angularjs.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * 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 + make up the elevation. + */ + readonly property var _shadows: [ + [{offset: 0, blur: 0, spread: 0}, + {offset: 0, blur: 0, spread: 0}, + {offset: 0, blur: 0, spread: 0}], + + [{offset: 1, blur: 3, spread: 0}, + {offset: 1, blur: 1, spread: 0}, + {offset: 2, blur: 1, spread: -1}], + + [{offset: 1, blur: 5, spread: 0}, + {offset: 2, blur: 2, spread: 0}, + {offset: 3, blur: 1, spread: -2}], + + [{offset: 1, blur: 8, spread: 0}, + {offset: 3, blur: 4, spread: 0}, + {offset: 3, blur: 3, spread: -2}], + + [{offset: 2, blur: 4, spread: -1}, + {offset: 4, blur: 5, spread: 0}, + {offset: 1, blur: 10, spread: 0}], + + [{offset: 3, blur: 5, spread: -1}, + {offset: 5, blur: 8, spread: 0}, + {offset: 1, blur: 14, spread: 0}], + + [{offset: 3, blur: 5, spread: -1}, + {offset: 6, blur: 10, spread: 0}, + {offset: 1, blur: 18, spread: 0}], + + [{offset: 4, blur: 5, spread: -2}, + {offset: 7, blur: 10, spread: 1}, + {offset: 2, blur: 16, spread: 1}], + + [{offset: 5, blur: 5, spread: -3}, + {offset: 8, blur: 10, spread: 1}, + {offset: 3, blur: 14, spread: 2}], + + [{offset: 5, blur: 6, spread: -3}, + {offset: 9, blur: 12, spread: 1}, + {offset: 3, blur: 16, spread: 2}], + + [{offset: 6, blur: 6, spread: -3}, + {offset: 10, blur: 14, spread: 1}, + {offset: 4, blur: 18, spread: 3}], + + [{offset: 6, blur: 7, spread: -4}, + {offset: 11, blur: 15, spread: 1}, + {offset: 4, blur: 20, spread: 3}], + + [{offset: 7, blur: 8, spread: -4}, + {offset: 12, blur: 17, spread: 2}, + {offset: 5, blur: 22, spread: 4}], + + [{offset: 7, blur: 8, spread: -4}, + {offset: 13, blur: 19, spread: 2}, + {offset: 5, blur: 24, spread: 4}], + + [{offset: 7, blur: 9, spread: -4}, + {offset: 14, blur: 21, spread: 2}, + {offset: 5, blur: 26, spread: 4}], + + [{offset: 8, blur: 9, spread: -5}, + {offset: 15, blur: 22, spread: 2}, + {offset: 6, blur: 28, spread: 5}], + + [{offset: 8, blur: 10, spread: -5}, + {offset: 16, blur: 24, spread: 2}, + {offset: 6, blur: 30, spread: 5}], + + [{offset: 8, blur: 11, spread: -5}, + {offset: 17, blur: 26, spread: 2}, + {offset: 6, blur: 32, spread: 5}], + + [{offset: 9, blur: 11, spread: -5}, + {offset: 18, blur: 28, spread: 2}, + {offset: 7, blur: 34, spread: 6}], + + [{offset: 9, blur: 12, spread: -6}, + {offset: 19, blur: 29, spread: 2}, + {offset: 7, blur: 36, spread: 6}], + + [{offset: 10, blur: 13, spread: -6}, + {offset: 20, blur: 31, spread: 3}, + {offset: 8, blur: 38, spread: 7}], + + [{offset: 10, blur: 13, spread: -6}, + {offset: 21, blur: 33, spread: 3}, + {offset: 8, blur: 40, spread: 7}], + + [{offset: 10, blur: 14, spread: -6}, + {offset: 22, blur: 35, spread: 3}, + {offset: 8, blur: 42, spread: 7}], + + [{offset: 11, blur: 14, spread: -7}, + {offset: 23, blur: 36, spread: 3}, + {offset: 9, blur: 44, spread: 8}], + + [{offset: 11, blur: 15, spread: -7}, + {offset: 24, blur: 38, spread: 3}, + {offset: 9, blur: 46, spread: 8}] + ] + + /*! + \internal + + The current shadow based on the elevation. + */ + readonly property var _shadow: _shadows[elevation] + + // Nest the shadows and source view in two items rendered as a layer + // so the shadow is not clipped by the bounds of the source view + Item { + property int margin: -100 + + x: margin + y: margin + width: parent.width - 2 * margin + height: parent.height - 2 * margin + + // By rendering as a layer, the shadow will never show through the source item, + // even when the source item's opacity is less than 1 + layer.enabled: true + + // The box shadows automatically pick up the size of the source Item and not + // the size of the parent, so we don't need to worry about the extra padding + // in the parent Item + BoxShadow { + offsetY: _shadow[0].offset + blurRadius: _shadow[0].blur + spreadRadius: _shadow[0].spread + color: Qt.rgba(0,0,0, 0.2) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + BoxShadow { + offsetY: _shadow[1].offset + blurRadius: _shadow[1].blur + spreadRadius: _shadow[1].spread + color: Qt.rgba(0,0,0, 0.14) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + BoxShadow { + offsetY: _shadow[2].offset + blurRadius: _shadow[2].blur + spreadRadius: _shadow[2].spread + color: Qt.rgba(0,0,0, 0.12) + + fullWidth: effect.fullWidth + fullHeight: effect.fullHeight + source: effect.sourceItem + } + + ShaderEffect { + property alias source: effect.source + + x: (parent.width - width)/2 + y: (parent.height - height)/2 + width: sourceItem.width + height: sourceItem.height + } + } +} diff --git a/src/imports/controls/material/ItemDelegate.qml b/src/imports/controls/material/ItemDelegate.qml index 37181008..19c832cd 100644 --- a/src/imports/controls/material/ItemDelegate.qml +++ b/src/imports/controls/material/ItemDelegate.qml @@ -71,7 +71,7 @@ T.ItemDelegate { implicitHeight: 48 visible: control.down || control.highlighted - color: control.down ? control.Material.flatButtonPressColor : control.Material.listHighlightColor + color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor } //! [background] } diff --git a/src/imports/controls/material/Menu.qml b/src/imports/controls/material/Menu.qml index 5480a7ff..eff94be9 100644 --- a/src/imports/controls/material/Menu.qml +++ b/src/imports/controls/material/Menu.qml @@ -38,11 +38,14 @@ 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 QtGraphicalEffects 1.0 T.Menu { id: control + Material.elevation: 8 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem ? contentItem.implicitWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, @@ -88,12 +91,9 @@ T.Menu { radius: 3 color: control.Material.dialogColor - layer.enabled: true - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - samples: 15 - spread: 0.5 + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation } } //! [background] diff --git a/src/imports/controls/material/MenuItem.qml b/src/imports/controls/material/MenuItem.qml index 6a89a18a..b3b4da9e 100644 --- a/src/imports/controls/material/MenuItem.qml +++ b/src/imports/controls/material/MenuItem.qml @@ -82,7 +82,7 @@ T.MenuItem { background: Rectangle { implicitWidth: 200 visible: control.down || control.highlighted - color: control.down ? control.Material.flatButtonPressColor : control.Material.listHighlightColor + color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor } //! [background] } diff --git a/src/imports/controls/material/Pane.qml b/src/imports/controls/material/Pane.qml index 43f9e34a..434c676c 100644 --- a/src/imports/controls/material/Pane.qml +++ b/src/imports/controls/material/Pane.qml @@ -37,6 +37,7 @@ import QtQuick 2.6 import QtQuick.Templates 2.0 as T import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material.impl 2.0 T.Pane { id: control @@ -56,6 +57,11 @@ T.Pane { //! [background] background: Rectangle { color: control.Material.backgroundColor + + layer.enabled: control.enabled && control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } } //! [background] } diff --git a/src/imports/controls/material/Popup.qml b/src/imports/controls/material/Popup.qml index 08bfaa19..4f1db60e 100644 --- a/src/imports/controls/material/Popup.qml +++ b/src/imports/controls/material/Popup.qml @@ -38,10 +38,13 @@ import QtQuick 2.6 import QtGraphicalEffects 1.0 import QtQuick.Templates 2.0 as T import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material.impl 2.0 T.Popup { id: control + Material.elevation: 24 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth > 0 ? contentWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, @@ -70,12 +73,9 @@ T.Popup { radius: 3 color: control.Material.dialogColor - layer.enabled: true - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - samples: 15 - spread: 0.5 + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation } } } diff --git a/src/imports/controls/material/RadioDelegate.qml b/src/imports/controls/material/RadioDelegate.qml index ba86da03..8a52c108 100644 --- a/src/imports/controls/material/RadioDelegate.qml +++ b/src/imports/controls/material/RadioDelegate.qml @@ -79,7 +79,7 @@ T.RadioDelegate { implicitHeight: 48 visible: control.down || control.highlighted - color: control.down ? control.Material.flatButtonPressColor : control.Material.listHighlightColor + color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor } //! [background] } diff --git a/src/imports/controls/material/SpinBox.qml b/src/imports/controls/material/SpinBox.qml index 828ac9cb..64176b69 100644 --- a/src/imports/controls/material/SpinBox.qml +++ b/src/imports/controls/material/SpinBox.qml @@ -118,9 +118,9 @@ T.SpinBox { width: height padding: control.spacing radius: 3 - color: Qt.tint(Qt.tint(control.Material.raisedButtonColor, - control.activeFocus ? control.Material.raisedButtonHoverColor : "transparent"), - control.up.pressed ? control.Material.raisedButtonPressColor: "transparent") + color: Qt.tint(Qt.tint(control.Material.buttonColor, + control.activeFocus ? control.Material.buttonHoverColor : "transparent"), + control.up.pressed ? control.Material.buttonPressColor: "transparent") Rectangle { x: (parent.width - width) / 2 @@ -148,9 +148,9 @@ T.SpinBox { width: height padding: control.spacing radius: 3 - color: Qt.tint(Qt.tint(control.Material.raisedButtonColor, - control.activeFocus ? control.Material.raisedButtonHoverColor : "transparent"), - control.down.pressed ? control.Material.raisedButtonPressColor : "transparent") + color: Qt.tint(Qt.tint(control.Material.buttonColor, + control.activeFocus ? control.Material.buttonHoverColor : "transparent"), + control.down.pressed ? control.Material.buttonPressColor : "transparent") Rectangle { x: (parent.width - width) / 2 diff --git a/src/imports/controls/material/Switch.qml b/src/imports/controls/material/Switch.qml index 37776100..300ccac2 100644 --- a/src/imports/controls/material/Switch.qml +++ b/src/imports/controls/material/Switch.qml @@ -42,6 +42,8 @@ import QtQuick.Templates 2.0 as T T.Switch { id: control + Material.elevation: 1 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, diff --git a/src/imports/controls/material/SwitchDelegate.qml b/src/imports/controls/material/SwitchDelegate.qml index f49efad2..92f66f91 100644 --- a/src/imports/controls/material/SwitchDelegate.qml +++ b/src/imports/controls/material/SwitchDelegate.qml @@ -42,6 +42,8 @@ import QtQuick.Controls.Material.impl 2.0 T.SwitchDelegate { id: control + Material.elevation: 1 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, @@ -80,7 +82,7 @@ T.SwitchDelegate { implicitHeight: 48 visible: control.down || control.highlighted - color: control.down ? control.Material.flatButtonPressColor : control.Material.listHighlightColor + color: control.down ? control.Material.buttonPressColor : control.Material.listHighlightColor } //! [background] } diff --git a/src/imports/controls/material/SwitchIndicator.qml b/src/imports/controls/material/SwitchIndicator.qml index 93b4c9f6..433a8d79 100644 --- a/src/imports/controls/material/SwitchIndicator.qml +++ b/src/imports/controls/material/SwitchIndicator.qml @@ -80,12 +80,9 @@ Item { duration: 300 } } - - layer.enabled: true - layer.effect: DropShadow { - verticalOffset: 1 - color: control.Material.dropShadowColor - spread: 0.3 + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation } } } diff --git a/src/imports/controls/material/ToolBar.qml b/src/imports/controls/material/ToolBar.qml index b87451a0..1cd67bd0 100644 --- a/src/imports/controls/material/ToolBar.qml +++ b/src/imports/controls/material/ToolBar.qml @@ -37,10 +37,13 @@ import QtQuick 2.6 import QtQuick.Templates 2.0 as T import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Material.impl 2.0 T.ToolBar { id: control + Material.elevation: 4 + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) @@ -55,6 +58,12 @@ T.ToolBar { background: Rectangle { implicitHeight: 48 color: control.Material.primaryColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullWidth: true + } } //! [background] } diff --git a/src/imports/controls/material/ToolButton.qml b/src/imports/controls/material/ToolButton.qml index 22a81c76..59a6110e 100644 --- a/src/imports/controls/material/ToolButton.qml +++ b/src/imports/controls/material/ToolButton.qml @@ -65,7 +65,7 @@ T.ToolButton { implicitWidth: 48 implicitHeight: 48 - color: control.down ? control.Material.flatButtonPressColor : control.Material.flatButtonFocusColor + color: control.down ? control.Material.buttonPressColor : control.Material.flatButtonFocusColor visible: control.enabled && (control.down || control.visualFocus || control.checked || control.highlighted) } //! [background] diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri index c1d6b66b..d6247895 100644 --- a/src/imports/controls/material/material.pri +++ b/src/imports/controls/material/material.pri @@ -12,6 +12,7 @@ SOURCES += \ QML_FILES += \ $$PWD/ApplicationWindow.qml \ + $$PWD/BoxShadow.qml \ $$PWD/BusyIndicator.qml \ $$PWD/Button.qml \ $$PWD/CheckBox.qml \ @@ -20,6 +21,7 @@ QML_FILES += \ $$PWD/ComboBox.qml \ $$PWD/Dial.qml \ $$PWD/Drawer.qml \ + $$PWD/ElevationEffect.qml \ $$PWD/Frame.qml \ $$PWD/GroupBox.qml \ $$PWD/ItemDelegate.qml \ diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp index b63299c1..d993ce13 100644 --- a/src/imports/controls/material/qquickmaterialstyle.cpp +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -392,7 +392,7 @@ static const QRgb hintTextColorDark = 0x4CFFFFFF; static const QRgb dividerColorLight = 0x1E000000; static const QRgb dividerColorDark = 0x1EFFFFFF; static const QRgb raisedButtonColorLight = 0xFFD6D7D7; -static const QRgb raisedButtonPressColorLight = 0xFFCCCDCD; +static const QRgb raisedButtonColorDark = 0xFFD6D7D7; static const QRgb raisedButtonDisabledColorLight = dividerColorLight; static const QRgb raisedButtonDisabledColorDark = dividerColorDark; static const QRgb flatButtonPressColorLight = 0x66999999; @@ -442,7 +442,8 @@ QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyleAttached( m_primary(defaultPrimary), m_accent(defaultAccent), m_foreground(defaultForeground), - m_background(defaultBackground) + m_background(defaultBackground), + m_elevation(0) { init(); } @@ -734,6 +735,25 @@ void QQuickMaterialStyle::resetBackground() inheritBackground(material ? material->m_background : defaultBackground, true, material ? material->m_hasBackground : false); } +int QQuickMaterialStyle::elevation() const +{ + return m_elevation; +} + +void QQuickMaterialStyle::setElevation(int elevation) +{ + if (m_elevation == elevation) + return; + + m_elevation = elevation; + emit elevationChanged(); +} + +void QQuickMaterialStyle::resetElevation() +{ + setElevation(0); +} + QColor QQuickMaterialStyle::primaryColor() const { if (m_customPrimary) @@ -743,24 +763,36 @@ QColor QQuickMaterialStyle::primaryColor() const return colors[m_primary][Shade500]; } -QColor QQuickMaterialStyle::accentColor() const +QColor QQuickMaterialStyle::accentColor(Shade shade) const { if (m_customAccent) - return QColor::fromRgba(m_accent); + return shade == Shade500 ? QColor::fromRgba(m_accent) + : this->shade(QColor::fromRgba(m_accent), shade); if (m_accent > BlueGrey) return QColor(); - return colors[m_accent][m_theme == Light ? Shade500 : Shade200]; + return colors[m_accent][shade]; } -QColor QQuickMaterialStyle::backgroundColor() const +QColor QQuickMaterialStyle::accentColor() const +{ + return accentColor(m_theme == Light ? Shade500 : Shade200); +} + +QColor QQuickMaterialStyle::backgroundColor(Shade shade) const { if (!m_hasBackground) return QColor::fromRgba(m_theme == Light ? backgroundColorLight : backgroundColorDark); if (m_customBackground) - return QColor::fromRgba(m_background); + return shade == Shade500 ? QColor::fromRgba(m_background) + : this->shade(QColor::fromRgba(m_background), shade); if (m_background > BlueGrey) return QColor(); - return colors[m_background][Shade500]; + return colors[m_background][shade]; +} + +QColor QQuickMaterialStyle::backgroundColor() const +{ + return backgroundColor(Shade500); } QColor QQuickMaterialStyle::primaryTextColor() const @@ -808,52 +840,77 @@ QColor QQuickMaterialStyle::dividerColor() const return QColor::fromRgba(m_theme == Light ? dividerColorLight : dividerColorDark); } -QColor QQuickMaterialStyle::raisedButtonColor() const +QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool pressed, bool hover) const { - return QColor::fromRgba(m_theme == Light ? raisedButtonColorLight : flatButtonFocusColorDark); -} + Shade shade = m_theme == Light ? pressed ? Shade700 : Shade500 + : pressed ? Shade100 : Shade200; -QColor QQuickMaterialStyle::raisedButtonHoverColor() const -{ - // The specs don't specify different colors here for the light theme. - return QColor::fromRgba(m_theme == Light ? raisedButtonColorLight : flatButtonPressColorDark); + QColor color = Qt::transparent; + + if (m_hasBackground) { + color = backgroundColor(shade); + } else if (highlighted) { + color = accentColor(shade); + } else if (elevation() > 0) { + color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight + : raisedButtonColorDark); + + if (pressed) { + color = this->shade(color, shade); + } + } + + if (color == Qt::transparent && pressed) { + color = QColor::fromRgba(m_theme == Light ? flatButtonPressColorLight + : flatButtonPressColorDark); + } + + if (pressed || hover) { + // Add overlaying black shadow 12% opacity + return alphaBlend(color, QColor::fromRgba(0x1F000000)); + } else { + return color; + } } -QColor QQuickMaterialStyle::raisedButtonPressColor() const +QColor QQuickMaterialStyle::buttonColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonPressColorLight : flatButtonPressColorDark); + return buttonColor(false, false, false); } -QColor QQuickMaterialStyle::raisedButtonDisabledColor() const +QColor QQuickMaterialStyle::buttonHoverColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark); + return buttonColor(false, false, true); } -QColor QQuickMaterialStyle::raisedHighlightedButtonColor() const +QColor QQuickMaterialStyle::buttonPressColor() const { - return accentColor(); + return buttonColor(false, true, false); } -QColor QQuickMaterialStyle::raisedHighlightedButtonHoverColor() const +QColor QQuickMaterialStyle::buttonDisabledColor() const { - // Add overlaying black shadow 12% opacity - return alphaBlend(accentColor(), QColor::fromRgba(0x1F000000)); + if (elevation() > 0) { + return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight + : raisedButtonDisabledColorDark); + } else { + return Qt::transparent; + } } -QColor QQuickMaterialStyle::raisedHighlightedButtonPressColor() const +QColor QQuickMaterialStyle::highlightedButtonColor() const { - // Add overlaying black shadow 12% opacity - return alphaBlend(shade(accentColor(), m_theme == Light ? Shade700 : Shade100), QColor::fromRgba(0x1F000000)); + return buttonColor(true, false, false); } -QColor QQuickMaterialStyle::raisedHighlightedButtonDisabledColor() const +QColor QQuickMaterialStyle::highlightedButtonHoverColor() const { - return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark); + return buttonColor(true, false, true); } -QColor QQuickMaterialStyle::flatButtonPressColor() const +QColor QQuickMaterialStyle::highlightedButtonPressColor() const { - return QColor::fromRgba(m_theme == Light ? flatButtonPressColorLight : flatButtonPressColorDark); + return buttonColor(true, true, false); } QColor QQuickMaterialStyle::flatButtonFocusColor() const diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h index a8b7ecb8..ce89cc46 100644 --- a/src/imports/controls/material/qquickmaterialstyle_p.h +++ b/src/imports/controls/material/qquickmaterialstyle_p.h @@ -63,6 +63,9 @@ class QQuickMaterialStyle : public QQuickStyleAttached Q_PROPERTY(QVariant accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL) Q_PROPERTY(QVariant foreground READ foreground WRITE setForeground RESET resetForeground NOTIFY foregroundChanged FINAL) Q_PROPERTY(QVariant background READ background WRITE setBackground RESET resetBackground NOTIFY backgroundChanged FINAL) + Q_PROPERTY(int elevation READ elevation WRITE setElevation RESET resetElevation NOTIFY elevationChanged FINAL) + + Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove? Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove? Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundChanged FINAL) @@ -73,15 +76,13 @@ class QQuickMaterialStyle : public QQuickStyleAttached Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dropShadowColor READ dropShadowColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedButtonColor READ raisedButtonColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedButtonHoverColor READ raisedButtonHoverColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedButtonPressColor READ raisedButtonPressColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedButtonDisabledColor READ raisedButtonDisabledColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedHighlightedButtonColor READ raisedHighlightedButtonColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedHighlightedButtonHoverColor READ raisedHighlightedButtonHoverColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedHighlightedButtonPressColor READ raisedHighlightedButtonPressColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor raisedHighlightedButtonDisabledColor READ raisedHighlightedButtonDisabledColor NOTIFY paletteChanged FINAL) - Q_PROPERTY(QColor flatButtonPressColor READ flatButtonPressColor 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 flatButtonFocusColor READ flatButtonFocusColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor swipeDelegateColor READ swipeDelegateColor NOTIFY paletteChanged FINAL) Q_PROPERTY(QColor swipeDelegateHoverColor READ swipeDelegateHoverColor NOTIFY paletteChanged FINAL) @@ -187,6 +188,10 @@ public: void propagateBackground(); void resetBackground(); + int elevation() const; + void setElevation(int elevation); + void resetElevation(); + QColor primaryColor() const; QColor accentColor() const; QColor backgroundColor() const; @@ -197,15 +202,14 @@ public: QColor textSelectionColor() const; QColor dropShadowColor() const; QColor dividerColor() const; - QColor raisedButtonColor() const; - QColor raisedButtonHoverColor() const; - QColor raisedButtonPressColor() const; - QColor raisedButtonDisabledColor() const; - QColor raisedHighlightedButtonColor() const; - QColor raisedHighlightedButtonHoverColor() const; - QColor raisedHighlightedButtonPressColor() const; - QColor raisedHighlightedButtonDisabledColor() const; - QColor flatButtonPressColor() 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 flatButtonFocusColor() const; QColor swipeDelegateColor() const; QColor swipeDelegateHoverColor() const; @@ -237,6 +241,8 @@ Q_SIGNALS: void accentChanged(); void foregroundChanged(); void backgroundChanged(); + void elevationChanged(); + void paletteChanged(); protected: @@ -246,6 +252,10 @@ private: void init(); bool variantToRgba(const QVariant &var, const char *name, QRgb *rgba, bool *custom) const; + QColor backgroundColor(Shade shade) const; + QColor accentColor(Shade shade) const; + QColor buttonColor(bool highlighted, bool pressed, bool hover) const; + bool m_explicitTheme; bool m_explicitPrimary; bool m_explicitAccent; @@ -262,6 +272,7 @@ private: uint m_accent; uint m_foreground; uint m_background; + int m_elevation; }; QT_END_NAMESPACE diff --git a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp index 623d93f9..5ee6e767 100644 --- a/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp +++ b/src/imports/controls/material/qtquickcontrols2materialstyleplugin.cpp @@ -89,7 +89,9 @@ void QtQuickControls2MaterialStylePlugin::initializeEngine(QQmlEngine *engine, c qmlRegisterType<QQuickMaterialProgressStrip>(import, 2, 0, "ProgressStrip"); qmlRegisterType<QQuickMaterialRingAnimator>(import, 2, 0, "RingAnimator"); 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("SliderHandle.qml")), import, 2, 0, "SliderHandle"); qmlRegisterType(typeUrl(QStringLiteral("SwitchIndicator.qml")), import, 2, 0, "SwitchIndicator"); |