aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2022-12-09 02:19:50 +0100
committerLiang Qi <liang.qi@qt.io>2022-12-09 02:19:50 +0100
commitf756c201c56454f4162de05a3c6bc264e8b7a758 (patch)
treeffb3a0a48acbed663c04faf1f25f07cedd0511ce
parent21bf976a411a65a1c945aae994afbcb8590e50e4 (diff)
parent871fe574cf942c0a1ddb936a169553cdb6a93249 (diff)
Merge "Merge remote-tracking branch 'origin/wip/material3' into dev"
-rw-r--r--src/quickcontrols/doc/src/external-pages.qdoc5
-rw-r--r--src/quickcontrols/doc/src/qtquickcontrols-material.qdoc24
-rw-r--r--src/quickcontrols/material/Button.qml45
-rw-r--r--src/quickcontrols/material/DelayButton.qml5
-rw-r--r--src/quickcontrols/material/RoundButton.qml9
-rw-r--r--src/quickcontrols/material/impl/BoxShadow.qml17
-rw-r--r--src/quickcontrols/material/impl/CMakeLists.txt1
-rw-r--r--src/quickcontrols/material/impl/ElevationEffect.qml228
-rw-r--r--src/quickcontrols/material/impl/RoundedElevationEffect.qml35
-rw-r--r--src/quickcontrols/material/impl/qquickmaterialripple.cpp4
-rw-r--r--src/quickcontrols/material/qquickmaterialstyle.cpp73
-rw-r--r--src/quickcontrols/material/qquickmaterialstyle_p.h34
-rw-r--r--tests/auto/quickcontrols/qquickmaterialstyle/data/tst_material.qml13
-rw-r--r--tests/auto/quickcontrols/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp4
-rw-r--r--tests/manual/quickcontrols/material/CMakeLists.txt34
-rw-r--r--tests/manual/quickcontrols/material/Constants.qml11
-rw-r--r--tests/manual/quickcontrols/material/material.cpp32
-rw-r--r--tests/manual/quickcontrols/material/material.qml126
-rw-r--r--tests/manual/quickcontrols/material/pages/ButtonPage.qml125
-rw-r--r--tests/manual/quickcontrols/material/pages/DelayButtonPage.qml73
-rw-r--r--tests/manual/quickcontrols/material/pages/RoundButtonPage.qml93
-rw-r--r--tests/manual/quickcontrols/material/qmldir2
-rw-r--r--tests/manual/quickcontrols/testbench/testbench.qml4
23 files changed, 795 insertions, 202 deletions
diff --git a/src/quickcontrols/doc/src/external-pages.qdoc b/src/quickcontrols/doc/src/external-pages.qdoc
index 591533c2c7..d78f94cc12 100644
--- a/src/quickcontrols/doc/src/external-pages.qdoc
+++ b/src/quickcontrols/doc/src/external-pages.qdoc
@@ -10,3 +10,8 @@
\externalpage https://doc.qt.io/qtcreator/creator-project-creating.html#selecting-project-type
\title Qt Creator: Project Types
*/
+
+/*!
+ \externalpage https://m3.material.io/styles/shape/overview
+ \title Material Style: Shape
+*/
diff --git a/src/quickcontrols/doc/src/qtquickcontrols-material.qdoc b/src/quickcontrols/doc/src/qtquickcontrols-material.qdoc
index 36e3b96a97..7b17b23a59 100644
--- a/src/quickcontrols/doc/src/qtquickcontrols-material.qdoc
+++ b/src/quickcontrols/doc/src/qtquickcontrols-material.qdoc
@@ -19,6 +19,7 @@
\li \l {material-foreground-attached-prop}{\b foreground} : color
\li \l {material-primary-attached-prop}{\b primary} : color
\li \l {material-theme-attached-prop}{\b theme} : enumeration
+ \li \l {material-roundedScale-attached-prop}{\b roundedScale} : enumeration
\endlist
\section1 Attached Methods
@@ -355,6 +356,29 @@
\endstyleproperty
+ \styleproperty {Material.roundedScale} {enumeration} {material-roundedScale-attached-prop}
+ \target material-roundedScale-attached-prop
+ This attached property holds the radius of rounded corners used on the
+ target control. The property can be attached to any window or item, but
+ only some controls support it.
+
+ The default value is control-specific.
+
+ Available scales:
+ \value Material.NotRounded Square corners
+ \value Material.ExtraSmallScale Extra small rounded corners
+ \value Material.SmallScale Small rounded corners
+ \value Material.MediumScale Medium rounded corners
+ \value Material.LargeScale Large rounded corners
+ \value Material.ExtraLargeScale Extra large rounded corners
+ \value Material.FullScale Fully rounded corners
+
+ This property was added in Qt 6.5.
+
+ See also: \l {Material Style: Shape}.
+
+ \endstyleproperty
+
\section1 Attached Method Documentation
\stylemethod2 {color} {color} {enumeration} {predefined} {enumeration} {shade} {material-color-attached-method}
diff --git a/src/quickcontrols/material/Button.qml b/src/quickcontrols/material/Button.qml
index f2828b1eeb..e2bbb58687 100644
--- a/src/quickcontrols/material/Button.qml
+++ b/src/quickcontrols/material/Button.qml
@@ -17,19 +17,22 @@ T.Button {
topInset: 6
bottomInset: 6
- padding: 12
- horizontalPadding: padding - 4
- spacing: 6
+ verticalPadding: 14
+ // https://m3.material.io/components/buttons/specs#256326ad-f934-40e7-b05f-0bcb41aa4382
+ leftPadding: !flat ? (!hasIcon ? 24 : 16) : 12
+ rightPadding: !flat ? 24 : (!hasIcon ? 12 : 16)
+ spacing: 8
icon.width: 24
icon.height: 24
icon.color: !enabled ? Material.hintTextColor :
- flat && highlighted ? Material.accentColor :
+ (control.flat && control.highlighted) || (control.checked && !control.highlighted) ? Material.accentColor :
highlighted ? Material.primaryHighlightedTextColor : Material.foreground
- Material.elevation: flat ? control.down || (enabled && control.hovered) ? 2 : 0
- : control.down ? 8 : 2
- Material.background: flat ? "transparent" : undefined
+ readonly property bool hasIcon: icon.name.length > 0 || icon.source.toString().length > 0
+
+ Material.elevation: control.down ? 8 : 2
+ Material.roundedScale: Material.FullScale
contentItem: IconLabel {
spacing: control.spacing
@@ -40,7 +43,7 @@ T.Button {
text: control.text
font: control.font
color: !control.enabled ? control.Material.hintTextColor :
- control.flat && control.highlighted ? control.Material.accentColor :
+ (control.flat && control.highlighted) || (control.checked && !control.highlighted) ? control.Material.accentColor :
control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground
}
@@ -48,32 +51,22 @@ T.Button {
implicitWidth: 64
implicitHeight: control.Material.buttonHeight
- radius: 2
- color: !control.enabled ? control.Material.buttonDisabledColor :
- control.highlighted ? (control.checked ? control.Material.highlightedCheckedButtonColor :
- 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
- }
+ radius: control.Material.roundedScale === Material.FullScale ? height / 2 : control.Material.roundedScale
+ color: control.Material.buttonColor(control.Material.theme, control.Material.background,
+ control.Material.accent, control.enabled, control.flat, control.highlighted, control.checked)
// 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 {
+ layer.enabled: control.enabled && color.a > 0 && !control.flat
+ layer.effect: RoundedElevationEffect {
elevation: control.Material.elevation
+ roundedScale: control.background.radius
}
Ripple {
- clipRadius: 2
+ clip: true
+ clipRadius: parent.radius
width: parent.width
height: parent.height
pressed: control.pressed
diff --git a/src/quickcontrols/material/DelayButton.qml b/src/quickcontrols/material/DelayButton.qml
index f050d57a39..b18550541c 100644
--- a/src/quickcontrols/material/DelayButton.qml
+++ b/src/quickcontrols/material/DelayButton.qml
@@ -43,7 +43,8 @@ T.DelayButton {
implicitHeight: control.Material.buttonHeight
radius: 2
- color: !control.enabled ? control.Material.buttonDisabledColor : control.Material.buttonColor
+ color: control.Material.buttonColor(control.Material.theme, control.Material.background,
+ control.Material.accent, control.enabled, false /*flat*/, false /*highlighted*/, false /*checked*/)
PaddedRectangle {
y: parent.height - 4
@@ -65,7 +66,7 @@ T.DelayButton {
}
}
- layer.enabled: control.enabled && control.Material.buttonColor.a > 0
+ layer.enabled: control.enabled && color.a > 0 && !control.flat
layer.effect: ElevationEffect {
elevation: control.Material.elevation
}
diff --git a/src/quickcontrols/material/RoundButton.qml b/src/quickcontrols/material/RoundButton.qml
index 3484fb9460..4e3db36fca 100644
--- a/src/quickcontrols/material/RoundButton.qml
+++ b/src/quickcontrols/material/RoundButton.qml
@@ -28,8 +28,7 @@ T.RoundButton {
flat && highlighted ? Material.accentColor :
highlighted ? Material.primaryHighlightedTextColor : Material.foreground
- Material.elevation: flat ? control.down || control.hovered ? 2 : 0
- : control.down ? 12 : 6
+ Material.elevation: control.down ? 8 : 2
Material.background: flat ? "transparent" : undefined
contentItem: IconLabel {
@@ -51,8 +50,8 @@ T.RoundButton {
implicitHeight: control.Material.buttonHeight
radius: control.radius
- color: !control.enabled ? control.Material.buttonDisabledColor
- : control.checked || control.highlighted ? control.Material.highlightedButtonColor : control.Material.buttonColor
+ color: control.Material.buttonColor(control.Material.theme, control.Material.background,
+ control.Material.accent, control.enabled, control.flat, control.highlighted, false /*checked*/)
Rectangle {
width: parent.width
@@ -73,7 +72,7 @@ T.RoundButton {
// The layer is disabled when the button color is transparent so that 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.enabled: control.enabled && color.a > 0 && !control.flat
layer.effect: ElevationEffect {
elevation: control.Material.elevation
}
diff --git a/src/quickcontrols/material/impl/BoxShadow.qml b/src/quickcontrols/material/impl/BoxShadow.qml
index f77412d554..d702389cdf 100644
--- a/src/quickcontrols/material/impl/BoxShadow.qml
+++ b/src/quickcontrols/material/impl/BoxShadow.qml
@@ -16,6 +16,12 @@ RectangularGlow {
property int blurRadius
property int spreadRadius
+ // The strength of the shadow. We have this because RectangularGlow spreads
+ // out the shadow thinly, whereas lower elevation levels in Material 3
+ // are less spread out and stronger. This is only used for items with fully-rounded
+ // corners, like buttons.
+ property real strength
+
// The source item the shadow is being applied to, used for correctly
// calculating the corner radious
property Item source
@@ -23,6 +29,10 @@ RectangularGlow {
property bool fullWidth
property bool fullHeight
+ // qmllint disable unqualified
+ // Intentionally duck-typed (QTBUG-94807)
+ readonly property real sourceRadius: source && source.radius || 0
+
x: (parent.width - width)/2 + offsetX
y: (parent.height - height)/2 + offsetY
@@ -32,8 +42,7 @@ RectangularGlow {
width: implicitWidth + 2 * spreadRadius + (fullWidth ? 2 * cornerRadius : 0)
height: implicitHeight + 2 * spreadRadius + (fullHeight ? 2 * cornerRadius : 0)
glowRadius: blurRadius/2
- spread: 0.05
- // qmllint disable unqualified
- // Intentionally duck-typed (QTBUG-94807)
- cornerRadius: blurRadius + (source && source.radius || 0)
+ spread: strength
+
+ cornerRadius: blurRadius + sourceRadius
}
diff --git a/src/quickcontrols/material/impl/CMakeLists.txt b/src/quickcontrols/material/impl/CMakeLists.txt
index 8b8e2311b4..ebf3e1cbf3 100644
--- a/src/quickcontrols/material/impl/CMakeLists.txt
+++ b/src/quickcontrols/material/impl/CMakeLists.txt
@@ -12,6 +12,7 @@ set(qml_files
"ElevationEffect.qml"
"RadioIndicator.qml"
"RectangularGlow.qml"
+ "RoundedElevationEffect.qml"
"SliderHandle.qml"
"SwitchIndicator.qml"
)
diff --git a/src/quickcontrols/material/impl/ElevationEffect.qml b/src/quickcontrols/material/impl/ElevationEffect.qml
index 6690567617..29ec742f4a 100644
--- a/src/quickcontrols/material/impl/ElevationEffect.qml
+++ b/src/quickcontrols/material/impl/ElevationEffect.qml
@@ -75,106 +75,113 @@ Item {
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}]
+ property var _shadows: _defaultShadows
+
+ readonly property var _defaultShadows: [
+ { // 0
+ angularValues: [
+ {offset: 0, blur: 0, spread: 0},
+ {offset: 0, blur: 0, spread: 0},
+ {offset: 0, blur: 0, spread: 0}
+ ],
+ strength: 0.05
+ },
+ { // 1
+ angularValues: [
+ {offset: 1, blur: 3, spread: 0},
+ {offset: 1, blur: 1, spread: 0},
+ {offset: 2, blur: 1, spread: -1}
+ ],
+ strength: 0.05
+ },
+ { // 2
+ angularValues: [
+ {offset: 1, blur: 5, spread: 0},
+ {offset: 2, blur: 2, spread: 0},
+ {offset: 3, blur: 1, spread: -2}
+ ],
+ strength: 0.05
+ },
+ { // 3
+ angularValues: [
+ {offset: 1, blur: 8, spread: 0},
+ {offset: 3, blur: 4, spread: 0},
+ {offset: 3, blur: 3, spread: -2}
+ ],
+ strength: 0.05
+ },
+ { // 4
+ angularValues: [
+ {offset: 2, blur: 4, spread: -1},
+ {offset: 4, blur: 5, spread: 0},
+ {offset: 1, blur: 10, spread: 0}
+ ],
+ strength: 0.05
+ },
+ { // 5
+ angularValues: [
+ {offset: 3, blur: 5, spread: -1},
+ {offset: 5, blur: 8, spread: 0},
+ {offset: 1, blur: 14, spread: 0}
+ ],
+ strength: 0.05
+ },
+ { // 6
+ angularValues: [
+ {offset: 3, blur: 5, spread: -1},
+ {offset: 6, blur: 10, spread: 0},
+ {offset: 1, blur: 18, spread: 0}
+ ],
+ strength: 0.05
+ },
+ { // 7
+ angularValues: [
+ {offset: 4, blur: 5, spread: -2},
+ {offset: 7, blur: 10, spread: 1},
+ {offset: 2, blur: 16, spread: 1}
+ ],
+ strength: 0.05
+ },
+ { // 8
+ angularValues: [
+ {offset: 5, blur: 5, spread: -3},
+ {offset: 8, blur: 10, spread: 1},
+ {offset: 3, blur: 14, spread: 2}
+ ],
+ strength: 0.05
+ },
+ { // 9
+ angularValues: [
+ {offset: 5, blur: 6, spread: -3},
+ {offset: 9, blur: 12, spread: 1},
+ {offset: 3, blur: 16, spread: 2}
+ ],
+ strength: 0.05
+ },
+ { // 10
+ angularValues: [
+ {offset: 6, blur: 6, spread: -3},
+ {offset: 10, blur: 14, spread: 1},
+ {offset: 4, blur: 18, spread: 3}
+ ],
+ strength: 0.05
+ },
+ { // 11
+ angularValues: [
+ {offset: 6, blur: 7, spread: -4},
+ {offset: 11, blur: 15, spread: 1},
+ {offset: 4, blur: 20, spread: 3}
+ ],
+ strength: 0.05
+ },
+ { // 12
+ angularValues: [
+ {offset: 7, blur: 8, spread: -4},
+ {offset: 12, blur: 17, spread: 2},
+ {offset: 5, blur: 22, spread: 4}
+ ],
+ strength: 0.05
+ }
]
/*
@@ -202,9 +209,10 @@ Item {
// the size of the parent, so we don't need to worry about the extra padding
// in the parent Item
BoxShadow {
- offsetY: effect._shadow[0].offset
- blurRadius: effect._shadow[0].blur
- spreadRadius: effect._shadow[0].spread
+ offsetY: effect._shadow.angularValues[0].offset
+ blurRadius: effect._shadow.angularValues[0].blur
+ spreadRadius: effect._shadow.angularValues[0].spread
+ strength: effect._shadow.strength
color: Qt.rgba(0,0,0, 0.2)
fullWidth: effect.fullWidth
@@ -213,9 +221,10 @@ Item {
}
BoxShadow {
- offsetY: effect._shadow[1].offset
- blurRadius: effect._shadow[1].blur
- spreadRadius: effect._shadow[1].spread
+ offsetY: effect._shadow.angularValues[1].offset
+ blurRadius: effect._shadow.angularValues[1].blur
+ spreadRadius: effect._shadow.angularValues[1].spread
+ strength: effect._shadow.strength
color: Qt.rgba(0,0,0, 0.14)
fullWidth: effect.fullWidth
@@ -224,9 +233,10 @@ Item {
}
BoxShadow {
- offsetY: effect._shadow[2].offset
- blurRadius: effect._shadow[2].blur
- spreadRadius: effect._shadow[2].spread
+ offsetY: effect._shadow.angularValues[2].offset
+ blurRadius: effect._shadow.angularValues[2].blur
+ spreadRadius: effect._shadow.angularValues[2].spread
+ strength: effect._shadow.strength
color: Qt.rgba(0,0,0, 0.12)
fullWidth: effect.fullWidth
diff --git a/src/quickcontrols/material/impl/RoundedElevationEffect.qml b/src/quickcontrols/material/impl/RoundedElevationEffect.qml
new file mode 100644
index 0000000000..c197823dc6
--- /dev/null
+++ b/src/quickcontrols/material/impl/RoundedElevationEffect.qml
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick.Controls.Material
+import QtQuick.Controls.Material.impl
+
+ElevationEffect {
+ required property int roundedScale
+
+ _shadows: roundedScale === Material.NotRounded ? _defaultShadows : roundedShadows()
+
+ function roundedShadows() {
+ // Make a deep copy.
+ let shadows = [..._defaultShadows]
+ for (let i = 0, strength = 0.95; i < shadows.length; ++i) {
+ // See comment on BoxShadow's strength property for why we do this.
+ shadows[i].strength = strength
+ // We don't want the strength to be too high for the controls with very slightly rounded
+ // corners, as they are quite close to the non-rounded ones in terms of not needing adjustments.
+ // This is still not great for the higher elevations for ExtraSmallScale, but it's as good
+ // as I can get it.
+ strength = Math.max(0.05, strength - (roundedScale > Material.ExtraSmallScale ? 0.1 : 0.3))
+
+ // The values at index 0 are already 0, and we don't want our Math.max(1, ...) code to affect them.
+ if (i > 0) {
+ // The blur values for e.g. buttons with rounded corners are too large, so we reduce them.
+ for (let angularShadowIndex = 0; angularShadowIndex < shadows[i].angularValues.length; ++angularShadowIndex) {
+ shadows[i].angularValues[angularShadowIndex].blur =
+ Math.max(1, Math.floor(shadows[i].angularValues[angularShadowIndex].blur / 4))
+ }
+ }
+ }
+ return shadows
+ }
+}
diff --git a/src/quickcontrols/material/impl/qquickmaterialripple.cpp b/src/quickcontrols/material/impl/qquickmaterialripple.cpp
index 04e171f190..89648182d4 100644
--- a/src/quickcontrols/material/impl/qquickmaterialripple.cpp
+++ b/src/quickcontrols/material/impl/qquickmaterialripple.cpp
@@ -227,7 +227,6 @@ void QQuickMaterialRipple::setClipRadius(qreal radius)
return;
m_clipRadius = radius;
- setClip(!qFuzzyIsNull(radius));
update();
}
@@ -323,8 +322,7 @@ QSGNode *QQuickMaterialRipple::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
QQuickItemPrivate *d = QQuickItemPrivate::get(this);
QQuickDefaultClipNode *clipNode = d->clipNode();
if (clipNode) {
- // TODO: QTBUG-51894
- // clipNode->setRadius(m_clipRadius);
+ clipNode->setRadius(m_clipRadius);
clipNode->setRect(boundingRect());
clipNode->update();
}
diff --git a/src/quickcontrols/material/qquickmaterialstyle.cpp b/src/quickcontrols/material/qquickmaterialstyle.cpp
index dbe7347acc..ce745500a2 100644
--- a/src/quickcontrols/material/qquickmaterialstyle.cpp
+++ b/src/quickcontrols/material/qquickmaterialstyle.cpp
@@ -486,8 +486,6 @@ void QQuickMaterialStyle::themeChange()
emit themeChanged();
emit themeOrAccentChanged();
emit primaryHighlightedTextColor();
- emit buttonColorChanged();
- emit buttonDisabledColorChanged();
emit dialogColorChanged();
emit tooltipColorChanged();
emit toolBarColorChanged();
@@ -619,7 +617,6 @@ void QQuickMaterialStyle::accentChange()
{
emit accentChanged();
emit themeOrAccentChanged();
- emit buttonColorChanged();
}
QVariant QQuickMaterialStyle::foreground() const
@@ -753,7 +750,6 @@ void QQuickMaterialStyle::resetBackground()
void QQuickMaterialStyle::backgroundChange()
{
emit backgroundChanged();
- emit buttonColorChanged();
emit dialogColorChanged();
emit tooltipColorChanged();
emit toolBarColorChanged();
@@ -781,7 +777,25 @@ void QQuickMaterialStyle::resetElevation()
void QQuickMaterialStyle::elevationChange()
{
emit elevationChanged();
- emit buttonDisabledColorChanged();
+}
+
+QQuickMaterialStyle::RoundedScale QQuickMaterialStyle::roundedScale() const
+{
+ return m_roundedScale;
+}
+
+void QQuickMaterialStyle::setRoundedScale(RoundedScale roundedScale)
+{
+ if (m_roundedScale == roundedScale)
+ return;
+
+ m_roundedScale = roundedScale;
+ emit roundedScaleChanged();
+}
+
+void QQuickMaterialStyle::resetRoundedScale()
+{
+ setRoundedScale(RoundedScale::NotRounded);
}
QColor QQuickMaterialStyle::primaryColor() const
@@ -874,9 +888,24 @@ QColor QQuickMaterialStyle::iconDisabledColor() const
return QColor::fromRgba(m_theme == Light ? iconDisabledColorLight : iconDisabledColorDark);
}
-QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool checked) const
+QColor QQuickMaterialStyle::buttonColor(Theme theme, const QVariant &background, const QVariant &accent,
+ bool enabled, bool flat, bool highlighted, bool checked) const
{
+ if (flat)
+ return Qt::transparent;
+
+ if (!enabled) {
+ return QColor::fromRgba(m_theme == Light
+ ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark);
+ }
+
+ // We don't use theme (and other arguments) here even though we pass it in, as it's
+ // simpler to just re-use themeShade. We still need the arguments because they allow
+ // us to be re-called whenever they change.
Shade shade = themeShade();
+ Q_UNUSED(theme);
+ Q_UNUSED(background);
+ Q_UNUSED(accent);
QColor color = Qt::transparent;
@@ -891,7 +920,8 @@ QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool checked) const
// A highlighted + checked button should become darker.
color = accentColor(checked ? Shade100 : shade);
}
- } else if (elevation() > 0) {
+ } else {
+ // Even if the elevation is zero, it should still have a background if it's not flat.
color = QColor::fromRgba(m_theme == Light ? raisedButtonColorLight
: raisedButtonColorDark);
}
@@ -899,31 +929,6 @@ QColor QQuickMaterialStyle::buttonColor(bool highlighted, bool checked) const
return color;
}
-QColor QQuickMaterialStyle::buttonColor() const
-{
- return buttonColor(false);
-}
-
-QColor QQuickMaterialStyle::buttonDisabledColor() const
-{
- if (elevation() > 0) {
- return QColor::fromRgba(m_theme == Light ? raisedButtonDisabledColorLight
- : raisedButtonDisabledColorDark);
- } else {
- return Qt::transparent;
- }
-}
-
-QColor QQuickMaterialStyle::highlightedButtonColor() const
-{
- return buttonColor(true);
-}
-
-QColor QQuickMaterialStyle::highlightedCheckedButtonColor() const
-{
- return buttonColor(true, true);
-}
-
QColor QQuickMaterialStyle::frameColor() const
{
return QColor::fromRgba(m_theme == Light ? frameColorLight : frameColorDark);
@@ -1168,8 +1173,8 @@ int QQuickMaterialStyle::touchTarget() const
int QQuickMaterialStyle::buttonHeight() const
{
- // https://material.io/guidelines/components/buttons.html#buttons-style
- return globalVariant == Dense ? 32 : 36;
+ // https://m3.material.io/components/buttons/specs#256326ad-f934-40e7-b05f-0bcb41aa4382
+ return globalVariant == Dense ? 32 : 40;
}
int QQuickMaterialStyle::delegateHeight() const
diff --git a/src/quickcontrols/material/qquickmaterialstyle_p.h b/src/quickcontrols/material/qquickmaterialstyle_p.h
index 99344a6192..56e541ce07 100644
--- a/src/quickcontrols/material/qquickmaterialstyle_p.h
+++ b/src/quickcontrols/material/qquickmaterialstyle_p.h
@@ -30,6 +30,8 @@ class QQuickMaterialStyle : public QQuickAttachedPropertyPropagator
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(RoundedScale roundedScale READ roundedScale WRITE setRoundedScale RESET resetRoundedScale
+ NOTIFY roundedScaleChanged FINAL)
Q_PROPERTY(QColor primaryColor READ primaryColor NOTIFY primaryChanged FINAL) // TODO: remove?
Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) // TODO: remove?
@@ -43,10 +45,6 @@ class QQuickMaterialStyle : public QQuickAttachedPropertyPropagator
Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor iconColor READ iconColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor iconDisabledColor READ iconDisabledColor NOTIFY themeChanged FINAL)
- Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY buttonColorChanged FINAL)
- Q_PROPERTY(QColor buttonDisabledColor READ buttonDisabledColor NOTIFY buttonDisabledColorChanged FINAL)
- Q_PROPERTY(QColor highlightedButtonColor READ highlightedButtonColor NOTIFY buttonColorChanged FINAL)
- Q_PROPERTY(QColor highlightedCheckedButtonColor READ highlightedCheckedButtonColor NOTIFY buttonColorChanged FINAL REVISION(6, 2))
Q_PROPERTY(QColor frameColor READ frameColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor rippleColor READ rippleColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor highlightedRippleColor READ highlightedRippleColor NOTIFY themeOrAccentChanged FINAL)
@@ -134,10 +132,21 @@ public:
ShadeA700,
};
+ enum class RoundedScale {
+ NotRounded,
+ ExtraSmallScale = 4,
+ SmallScale = 8,
+ MediumScale = 12,
+ LargeScale = 16,
+ ExtraLargeScale = 28,
+ FullScale = 0xFF // For full we use half the height of the item.
+ };
+
Q_ENUM(Theme)
Q_ENUM(Variant)
Q_ENUM(Color)
Q_ENUM(Shade)
+ Q_ENUM(RoundedScale)
explicit QQuickMaterialStyle(QObject *parent = nullptr);
@@ -183,6 +192,10 @@ public:
void resetElevation();
void elevationChange();
+ RoundedScale roundedScale() const;
+ void setRoundedScale(RoundedScale roundedScale);
+ void resetRoundedScale();
+
QColor primaryColor() const;
QColor accentColor() const;
QColor backgroundColor() const;
@@ -195,11 +208,8 @@ public:
QColor dividerColor() const;
QColor iconColor() const;
QColor iconDisabledColor() const;
- QColor buttonColor() const;
- QColor buttonDisabledColor() const;
- QColor highlightedButtonColor() const;
- QColor highlightedCheckedButtonColor() const;
- QColor highlightedButtonDisabledColor() const;
+ Q_INVOKABLE QColor buttonColor(Theme theme, const QVariant &background, const QVariant &accent,
+ bool enabled, bool flat, bool highlighted, bool checked) const;
QColor frameColor() const;
QColor rippleColor() const;
QColor highlightedRippleColor() const;
@@ -249,12 +259,11 @@ Q_SIGNALS:
void themeOrAccentChanged();
void primaryHighlightedTextColorChanged();
- void buttonColorChanged();
- void buttonDisabledColorChanged();
void dialogColorChanged();
void tooltipColorChanged();
void toolBarColorChanged();
void toolTextColorChanged();
+ void roundedScaleChanged();
protected:
void attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) override;
@@ -265,7 +274,7 @@ private:
QColor backgroundColor(Shade shade) const;
QColor accentColor(Shade shade) const;
- QColor buttonColor(bool highlighted, bool checked = false) const;
+
Shade themeShade() const;
// These reflect whether a color value was explicitly set on the specific
@@ -295,6 +304,7 @@ private:
uint m_foreground = 0;
uint m_background = 0;
int m_elevation = 0;
+ RoundedScale m_roundedScale = RoundedScale::NotRounded;
};
QT_END_NAMESPACE
diff --git a/tests/auto/quickcontrols/qquickmaterialstyle/data/tst_material.qml b/tests/auto/quickcontrols/qquickmaterialstyle/data/tst_material.qml
index 34754420d0..fd62a5693b 100644
--- a/tests/auto/quickcontrols/qquickmaterialstyle/data/tst_material.qml
+++ b/tests/auto/quickcontrols/qquickmaterialstyle/data/tst_material.qml
@@ -35,6 +35,7 @@ TestCase {
Material.accent: Material.DeepPurple
Material.background: Material.Green
Material.foreground: Material.Blue
+ Material.roundedScale: Material.SmallScale
}
}
@@ -158,6 +159,8 @@ TestCase {
compare(control.Material.foreground, "#dd000000")
compare(control.Material.background, "#fafafa")
compare(control.Material.theme, Material.Light)
+ // This doesn't propagate but we check its default anyway.
+ compare(control.Material.roundedScale, Material.FullScale)
}
function test_set() {
@@ -168,11 +171,13 @@ TestCase {
control.Material.background = Material.Red
control.Material.foreground = Material.Blue
control.Material.theme = Material.Dark
+ control.Material.roundedScale = Material.SmallScale
compare(control.Material.primary, Material.color(Material.Green))
compare(control.Material.accent, Material.color(Material.Brown, themeshade(control.Material.theme)))
compare(control.Material.background, Material.color(Material.Red, themeshade(control.Material.theme)))
compare(control.Material.foreground, Material.color(Material.Blue))
compare(control.Material.theme, Material.Dark)
+ compare(control.Material.roundedScale, Material.SmallScale)
}
function test_reset() {
@@ -183,16 +188,21 @@ TestCase {
compare(control.Material.background, Material.color(Material.Green, themeshade(control.Material.theme)))
compare(control.Material.foreground, Material.color(Material.Blue))
compare(control.Material.theme, Material.Dark)
+ compare(control.Material.roundedScale, Material.SmallScale)
control.Material.primary = undefined
control.Material.accent = undefined
control.Material.background = undefined
control.Material.foreground = undefined
control.Material.theme = undefined
+ control.Material.roundedScale = undefined
compare(control.Material.primary, testCase.Material.primary)
compare(control.Material.accent, testCase.Material.accent)
compare(control.Material.background, testCase.Material.background)
compare(control.Material.foreground, testCase.Material.foreground)
compare(control.Material.theme, testCase.Material.theme)
+ // Button's default is FullyRounded, but it specifies that default in QML,
+ // which means we have no way of knowing how to reset that in resetRoundedScale().
+ compare(control.Material.roundedScale, Material.NotRounded)
}
function test_inheritance_data() {
@@ -817,9 +827,6 @@ TestCase {
property Component row_foregroundToDividerColor: Item { Material.foreground: Material.dividerColor }
property Component row_foregroundToIconColor: Item { Material.foreground: Material.iconColor }
property Component row_foregroundToIconDisabledColor: Item { Material.foreground: Material.iconDisabledColor }
- property Component row_foregroundToButtonColor: Item { Material.foreground: Material.buttonColor }
- property Component row_foregroundToButtonDisabledColor: Item { Material.foreground: Material.buttonDisabledColor }
- property Component row_foregroundToHighlightedButtonColor: Item { Material.foreground: Material.highlightedButtonColor }
property Component row_foregroundToFrameColor: Item { Material.foreground: Material.frameColor }
property Component row_foregroundToRippleColor: Item { Material.foreground: Material.rippleColor }
property Component row_foregroundToHighlightedRippleColor: Item { Material.foreground: Material.highlightedRippleColor }
diff --git a/tests/auto/quickcontrols/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp b/tests/auto/quickcontrols/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
index 722f846d90..cec4149149 100644
--- a/tests/auto/quickcontrols/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
+++ b/tests/auto/quickcontrols/qquickmaterialstyleconf/tst_qquickmaterialstyleconf.cpp
@@ -58,8 +58,8 @@ void tst_qquickmaterialstyleconf::variants_data()
// Just to ensure that the correct conf is loaded.
QTest::addColumn<QColor>("expectedColor");
- // (36 button height + 12 touchable area)
- QTest::newRow("normal") << QByteArray(":/variant-normal.conf") << 48 << QColor::fromRgb(0x123456);
+ // (40 button height + 12 touchable area)
+ QTest::newRow("normal") << QByteArray(":/variant-normal.conf") << 52 << QColor::fromRgb(0x123456);
// We specified a custom variant (dense), so the button should be small.
// (32 button height + 12 touchable area)
QTest::newRow("dense") << QByteArray(":/variant-dense.conf") << 44 << QColor::fromRgb(0x789abc);
diff --git a/tests/manual/quickcontrols/material/CMakeLists.txt b/tests/manual/quickcontrols/material/CMakeLists.txt
new file mode 100644
index 0000000000..1cd3a98d0f
--- /dev/null
+++ b/tests/manual/quickcontrols/material/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(material LANGUAGES C CXX ASM)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_manual_test(material
+ GUI
+ SOURCES
+ material.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::Qml
+ Qt::QuickControls2
+)
+
+set(qmake_immediate_resource_files
+ "material.qml"
+ "Constants.qml"
+ "pages/ButtonPage.qml"
+ "pages/DelayButtonPage.qml"
+ "pages/RoundButtonPage.qml"
+ "qmldir"
+)
+
+qt_internal_add_resource(material "qmake_immediate"
+ PREFIX
+ "/"
+ FILES
+ ${qmake_immediate_resource_files}
+)
diff --git a/tests/manual/quickcontrols/material/Constants.qml b/tests/manual/quickcontrols/material/Constants.qml
new file mode 100644
index 0000000000..51b9b6ff23
--- /dev/null
+++ b/tests/manual/quickcontrols/material/Constants.qml
@@ -0,0 +1,11 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+pragma Singleton
+
+import QtQml
+
+QtObject {
+ readonly property url iconSource: "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png"
+ readonly property int pageTopPadding: 20
+ readonly property int spacing: 40
+}
diff --git a/tests/manual/quickcontrols/material/material.cpp b/tests/manual/quickcontrols/material/material.cpp
new file mode 100644
index 0000000000..2e257b0902
--- /dev/null
+++ b/tests/manual/quickcontrols/material/material.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QSettings>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication::setApplicationName("material");
+ QGuiApplication::setOrganizationName("QtProject");
+
+ QGuiApplication app(argc, argv);
+
+ const char *variantEnvVar = "QT_QUICK_CONTROLS_MATERIAL_VARIANT";
+ if (!qEnvironmentVariableIsSet(variantEnvVar)) {
+ QSettings settings;
+ const char *variant = "variant";
+ if (settings.contains(variant))
+ qputenv(variantEnvVar, settings.value(variant).toByteArray());
+ }
+
+ QQmlApplicationEngine engine;
+ const QUrl url(QStringLiteral("qrc:/material.qml"));
+ QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
+ &app, [url](QObject *obj, const QUrl &objUrl) {
+ if (!obj && url == objUrl)
+ QCoreApplication::exit(-1);
+ }, Qt::QueuedConnection);
+ engine.load(url);
+
+ return app.exec();
+}
diff --git a/tests/manual/quickcontrols/material/material.qml b/tests/manual/quickcontrols/material/material.qml
new file mode 100644
index 0000000000..720ff0a5ec
--- /dev/null
+++ b/tests/manual/quickcontrols/material/material.qml
@@ -0,0 +1,126 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtCore
+import QtQuick
+import QtQuick.Controls.Material
+import QtQuick.Layouts
+
+ApplicationWindow {
+ id: window
+ title: "Material"
+ width: screen.desktopAvailableWidth * 0.8
+ height: screen.desktopAvailableHeight * 0.8
+ visible: true
+
+ Material.theme: settings.theme
+
+ Settings {
+ id: settings
+
+ property alias windowX: window.x
+ property alias windowY: window.y
+ property alias windowWidth: window.width
+ property alias windowHeight: window.height
+
+ property int theme: darkThemeSwitch.checked ? Material.Dark : Material.Light
+ property string variant: denseSwitch.checked ? "Dense" : "Normal"
+
+ property alias currentControlIndex: listView.currentIndex
+ }
+
+ Shortcut {
+ sequences: ["Esc", "Back"]
+ onActivated: openDrawerAction.trigger()
+ }
+
+ Shortcut {
+ sequence: "Ctrl+Q"
+ onActivated: Qt.quit()
+ }
+
+ Action {
+ id: openDrawerAction
+ text: "Controls"
+ onTriggered: drawer.open()
+ }
+
+ header: ToolBar {
+ RowLayout {
+ spacing: 20
+ anchors.fill: parent
+
+ Material.theme: Material.Dark
+
+ ToolButton {
+ action: openDrawerAction
+ }
+
+ Label {
+ id: titleLabel
+ text: listView.currentItem ? listView.currentItem.text : "Material"
+ font.pixelSize: 20
+ elide: Label.ElideRight
+ horizontalAlignment: Qt.AlignHCenter
+ verticalAlignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Switch {
+ id: darkThemeSwitch
+ text: "Dark"
+ checked: settings.theme === Material.Dark
+ }
+
+ Switch {
+ id: denseSwitch
+ text: "Dense"
+ checked: settings.variant === "Dense"
+
+ ToolTip.text: "Requires restart"
+ ToolTip.visible: hovered
+ }
+ }
+ }
+
+ Drawer {
+ id: drawer
+ width: window.width / 3
+ height: window.height
+ interactive: stackView.depth === 1
+
+ ListView {
+ id: listView
+ focus: true
+ currentIndex: settings.currentControlIndex
+ anchors.fill: parent
+ model: ["Button", "DelayButton", "RoundButton"]
+ delegate: ItemDelegate {
+ width: listView.width
+ text: modelData
+ highlighted: ListView.isCurrentItem
+ onClicked: listView.currentIndex = index
+ }
+
+ ScrollIndicator.vertical: ScrollIndicator { }
+
+ // Need to wait until our count is non-zero before setting a default currentIndex.
+ // This also allows us to use an alias for the settings property.
+ Component.onCompleted: if (currentIndex === -1) currentIndex = 0
+
+ onCurrentIndexChanged: {
+ if (currentIndex >= 0 && currentIndex < count)
+ stackView.replace("qrc:/pages/" + model[currentIndex] + "Page.qml")
+ drawer.close()
+ }
+ }
+ }
+
+ StackView {
+ id: stackView
+ anchors.fill: parent
+ }
+}
diff --git a/tests/manual/quickcontrols/material/pages/ButtonPage.qml b/tests/manual/quickcontrols/material/pages/ButtonPage.qml
new file mode 100644
index 0000000000..3f861e7a70
--- /dev/null
+++ b/tests/manual/quickcontrols/material/pages/ButtonPage.qml
@@ -0,0 +1,125 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls.Material
+import QtQuick.Layouts
+
+import ".."
+
+Page {
+ topPadding: 20
+
+ property var backgroundColor
+
+ header: RowLayout {
+ CheckBox {
+ id: iconCheckBox
+ text: "Icon"
+ }
+
+ CheckBox {
+ id: disabledCheckBox
+ text: "Disabled"
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ component RoundedScaleLayout: ColumnLayout {
+ id: roundedScaleLayout
+ enabled: !disabledCheckBox.checked
+
+ property bool allowFlat
+ property var backgroundColor: undefined
+ property var foregroundColor: undefined
+
+ property int contentLeftMargin
+ property int contentRightMargin
+
+ RowLayout {
+ enabled: roundedScaleLayout.allowFlat
+
+ CheckBox {
+ id: flatCheckBox
+ text: "Flat"
+
+ Layout.leftMargin: roundedScaleLayout.contentLeftMargin
+ }
+ }
+
+ RowLayout {
+ spacing: Constants.spacing
+
+ Repeater {
+ id: roundedScaleRepeater
+ model: ListModel {
+ ListElement { displayName: "NotRounded"; roundedScale: Material.NotRounded }
+ ListElement { displayName: "ExtraSmall"; roundedScale: Material.ExtraSmallScale }
+ ListElement { displayName: "Small"; roundedScale: Material.SmallScale }
+ ListElement { displayName: "Medium"; roundedScale: Material.MediumScale }
+ ListElement { displayName: "Large"; roundedScale: Material.LargeScale }
+ ListElement { displayName: "ExtraLarge"; roundedScale: Material.ExtraLargeScale }
+ ListElement { displayName: "Full"; roundedScale: Material.FullScale }
+ }
+
+ // Workaround for QTBUG-98859.
+ delegate: Component {
+ ColumnLayout {
+ id: scaleLayout
+ spacing: Constants.spacing
+
+ required property int index
+ required property string displayName
+ required property int roundedScale
+
+ Layout.leftMargin: index === 0 ? roundedScaleLayout.contentLeftMargin : 0
+ Layout.rightMargin: index === roundedScaleRepeater.count - 1 ? roundedScaleLayout.contentRightMargin : 0
+ Layout.bottomMargin: Constants.spacing
+
+ Label {
+ text: scaleLayout.displayName
+
+ Layout.alignment: Qt.AlignHCenter
+ }
+
+ Repeater {
+ model: 13
+
+ Button {
+ text: modelData
+ flat: flatCheckBox.checked
+ icon.source: iconCheckBox.checked ? "qrc:/qt-project.org/imports/QtQuick/Controls/Basic/images/check.png" : ""
+
+ Material.background: roundedScaleLayout.backgroundColor
+ Material.foreground: roundedScaleLayout.foregroundColor
+ Material.elevation: modelData
+ Material.roundedScale: scaleLayout.roundedScale
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ScrollView {
+ anchors.fill: parent
+
+ RowLayout {
+ spacing: Constants.spacing
+
+ RoundedScaleLayout {
+ contentLeftMargin: Constants.spacing
+ allowFlat: true
+ }
+
+ RoundedScaleLayout {
+ backgroundColor: Material.Teal
+ foregroundColor: "white"
+ contentRightMargin: Constants.spacing
+ }
+ }
+ }
+}
diff --git a/tests/manual/quickcontrols/material/pages/DelayButtonPage.qml b/tests/manual/quickcontrols/material/pages/DelayButtonPage.qml
new file mode 100644
index 0000000000..ee9c12f446
--- /dev/null
+++ b/tests/manual/quickcontrols/material/pages/DelayButtonPage.qml
@@ -0,0 +1,73 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls.Material
+import QtQuick.Layouts
+
+import ".."
+
+Page {
+ topPadding: 20
+
+ property var backgroundColor
+
+ header: RowLayout {
+ CheckBox {
+ id: disabledCheckBox
+ text: "Disabled"
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ component ElevationLayout: ColumnLayout {
+ id: elevationLayout
+ enabled: !disabledCheckBox.checked
+
+ property var backgroundColor: undefined
+ property var foregroundColor: undefined
+
+ property int contentLeftMargin
+ property int contentRightMargin
+
+ ColumnLayout {
+ spacing: Constants.spacing
+
+ Repeater {
+ model: 13
+
+ DelayButton {
+ text: modelData
+
+ Material.background: elevationLayout.backgroundColor
+ Material.foreground: elevationLayout.foregroundColor
+ Material.elevation: modelData
+
+ Layout.leftMargin: elevationLayout.contentLeftMargin
+ }
+ }
+
+ Layout.bottomMargin: Constants.spacing
+ }
+ }
+
+ ScrollView {
+ anchors.fill: parent
+
+ RowLayout {
+ spacing: Constants.spacing
+
+ ElevationLayout {
+ contentLeftMargin: Constants.spacing
+ }
+
+ ElevationLayout {
+ backgroundColor: Material.Teal
+ foregroundColor: "white"
+ contentRightMargin: Constants.spacing
+ }
+ }
+ }
+}
diff --git a/tests/manual/quickcontrols/material/pages/RoundButtonPage.qml b/tests/manual/quickcontrols/material/pages/RoundButtonPage.qml
new file mode 100644
index 0000000000..1fbcbf2e45
--- /dev/null
+++ b/tests/manual/quickcontrols/material/pages/RoundButtonPage.qml
@@ -0,0 +1,93 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Controls.Material
+import QtQuick.Layouts
+
+import ".."
+
+Page {
+ topPadding: 20
+
+ property var backgroundColor
+
+ header: RowLayout {
+ CheckBox {
+ id: iconCheckBox
+ text: "Icon"
+ }
+
+ CheckBox {
+ id: disabledCheckBox
+ text: "Disabled"
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ component ElevationLayout: ColumnLayout {
+ id: elevationLayout
+ enabled: !disabledCheckBox.checked
+
+ property bool allowFlat
+ property var backgroundColor: undefined
+ property var foregroundColor: undefined
+
+ property int contentLeftMargin
+ property int contentRightMargin
+
+ RowLayout {
+ enabled: elevationLayout.allowFlat
+
+ CheckBox {
+ id: flatCheckBox
+ text: "Flat"
+
+ Layout.leftMargin: elevationLayout.contentLeftMargin
+ }
+ }
+
+ ColumnLayout {
+ spacing: Constants.spacing
+
+ Repeater {
+ model: 13
+
+ RoundButton {
+ text: iconCheckBox.checked ? "" : modelData
+ flat: flatCheckBox.checked
+ icon.source: iconCheckBox.checked ? Constants.iconSource : ""
+
+ Material.background: elevationLayout.backgroundColor
+ Material.foreground: elevationLayout.foregroundColor
+ Material.elevation: modelData
+
+ Layout.leftMargin: elevationLayout.contentLeftMargin
+ }
+ }
+
+ Layout.bottomMargin: Constants.spacing
+ }
+ }
+
+ ScrollView {
+ anchors.fill: parent
+
+ RowLayout {
+ spacing: Constants.spacing
+
+ ElevationLayout {
+ contentLeftMargin: Constants.spacing
+ allowFlat: true
+ }
+
+ ElevationLayout {
+ backgroundColor: Material.Teal
+ foregroundColor: "white"
+ contentRightMargin: Constants.spacing
+ }
+ }
+ }
+}
diff --git a/tests/manual/quickcontrols/material/qmldir b/tests/manual/quickcontrols/material/qmldir
new file mode 100644
index 0000000000..e56896abb6
--- /dev/null
+++ b/tests/manual/quickcontrols/material/qmldir
@@ -0,0 +1,2 @@
+module MaterialHelper
+singleton Constants 1.0 Constants.qml
diff --git a/tests/manual/quickcontrols/testbench/testbench.qml b/tests/manual/quickcontrols/testbench/testbench.qml
index c9185e35d0..c88e16425a 100644
--- a/tests/manual/quickcontrols/testbench/testbench.qml
+++ b/tests/manual/quickcontrols/testbench/testbench.qml
@@ -430,8 +430,8 @@ Ui.ApplicationWindow {
Label {
text: statesAsString.length > 0 ? statesAsString : "normal"
- // 4 is the most states for any element (Button)
- Layout.preferredHeight: (fontMetrics.lineSpacing) * (rootDelegate.maxStateCombinations + 1)
+ // Ensure that each row of the Flow has the same height for the labels.
+ Layout.preferredHeight: fontMetrics.lineSpacing * rootDelegate.maxStateCombinations
}
ControlContainer {