aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <[email protected]>2022-11-17 15:35:18 +0800
committerMitch Curtis <[email protected]>2022-12-12 13:38:14 +0800
commit81b12a5f73bfd61c9e7ca912a3e3f7ab57ff45cd (patch)
treee035f40e04b778ce9dc99dc63c504d096d11b271
parent7e38a9e6efc72cc42af16d9cef6f94703b06474b (diff)
Update Material Switch to Material 3
Fixes: QTBUG-108555 Change-Id: I6c17812c9cf0dab71ac212ab7cb28cad646f9dfc Reviewed-by: Mitch Curtis <[email protected]>
-rw-r--r--src/quickcontrols/material/Switch.qml8
-rw-r--r--src/quickcontrols/material/impl/SwitchIndicator.qml92
-rw-r--r--src/quickcontrols/material/qquickmaterialstyle.cpp96
-rw-r--r--src/quickcontrols/material/qquickmaterialstyle_p.h20
-rw-r--r--tests/manual/quickcontrols/material/CMakeLists.txt1
-rw-r--r--tests/manual/quickcontrols/material/material.qml2
-rw-r--r--tests/manual/quickcontrols/material/pages/SwitchPage.qml75
7 files changed, 256 insertions, 38 deletions
diff --git a/src/quickcontrols/material/Switch.qml b/src/quickcontrols/material/Switch.qml
index db3fedfdc3..d27621a74f 100644
--- a/src/quickcontrols/material/Switch.qml
+++ b/src/quickcontrols/material/Switch.qml
@@ -18,6 +18,14 @@ T.Switch {
padding: 8
spacing: 8
+ icon.width: 16
+ icon.height: 16
+ icon.color: checked
+ ? (Material.theme === Material.Light
+ ? enabled ? Qt.darker(Material.switchCheckedTrackColor, 1.8) : Material.switchDisabledCheckedIconColor
+ : enabled ? Material.primaryTextColor : Material.switchDisabledCheckedIconColor)
+ : enabled ? Material.switchUncheckedTrackColor : Material.switchDisabledUncheckedIconColor
+
indicator: SwitchIndicator {
x: control.text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2
y: control.topPadding + (control.availableHeight - height) / 2
diff --git a/src/quickcontrols/material/impl/SwitchIndicator.qml b/src/quickcontrols/material/impl/SwitchIndicator.qml
index e439bc31b7..2d48302e01 100644
--- a/src/quickcontrols/material/impl/SwitchIndicator.qml
+++ b/src/quickcontrols/material/impl/SwitchIndicator.qml
@@ -3,37 +3,71 @@
import QtQuick
import QtQuick.Templates as T
+import QtQuick.Controls.impl
import QtQuick.Controls.Material
import QtQuick.Controls.Material.impl
-Item {
+Rectangle {
id: indicator
- implicitWidth: 38
- implicitHeight: 32
+ width: 52
+ height: 32
+ radius: height / 2
+ y: parent.height / 2 - height / 2
+ color: control.enabled
+ ? (control.checked
+ ? control.Material.switchCheckedTrackColor : control.Material.switchUncheckedTrackColor)
+ : (control.checked
+ ? control.Material.switchDisabledCheckedTrackColor
+ : control.Material.switchDisabledUncheckedTrackColor)
+ border.width: 2
+ border.color: control.enabled
+ ? (control.checked ? control.Material.switchCheckedTrackColor : control.Material.switchUncheckedHandleColor)
+ : (control.checked ? control.Material.switchDisabledCheckedTrackColor : control.Material.switchDisabledUncheckedTrackBorderColor)
property T.AbstractButton control
property alias handle: handle
- Material.elevation: 1
-
- Rectangle {
- width: parent.width
- height: 14
- radius: height / 2
- y: parent.height / 2 - height / 2
- color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedTrackColor : indicator.control.Material.switchUncheckedTrackColor)
- : indicator.control.Material.switchDisabledTrackColor
+ Behavior on color {
+ ColorAnimation {
+ duration: 200
+ }
+ }
+ Behavior on border.color {
+ ColorAnimation {
+ duration: 200
+ }
}
Rectangle {
id: handle
- x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2)))
+ x: Math.max(offset, Math.min(parent.width - offset - width,
+ indicator.control.visualPosition * parent.width - (width / 2)))
y: (parent.height - height) / 2
- width: 20
- height: 20
+ // We use scale to allow us to enlarge the circle from the center,
+ // as using width/height will cause it to jump due to the position x/y bindings.
+ // However, a large enough scale on certain displays will show the triangles
+ // that make up the circle, so instead we make sure that the circle is always
+ // its largest size so that more triangles are used, and downscale instead.
+ width: normalSize * largestScale
+ height: normalSize * largestScale
radius: width / 2
- color: indicator.control.enabled ? (indicator.control.checked ? indicator.control.Material.switchCheckedHandleColor : indicator.control.Material.switchUncheckedHandleColor)
- : indicator.control.Material.switchDisabledHandleColor
+ color: indicator.control.enabled
+ ? (indicator.control.checked
+ ? indicator.control.Material.switchCheckedHandleColor
+ : indicator.control.hovered
+ ? indicator.control.Material.switchUncheckedHoveredHandleColor : indicator.control.Material.switchUncheckedHandleColor)
+ : (indicator.control.checked
+ ? indicator.control.Material.switchDisabledCheckedHandleColor
+ : indicator.control.Material.switchDisabledUncheckedHandleColor)
+ scale: indicator.control.down ? 1 : (indicator.control.checked ? checkedSize / largestSize : normalSize / largestSize)
+
+ readonly property int offset: 2
+ readonly property real normalSize: !hasIcon ? 16 : checkedSize
+ readonly property real checkedSize: 24
+ readonly property real largestSize: 28
+ readonly property real largestScale: largestSize / normalSize
+ readonly property bool hasIcon: indicator.control.icon.name.length > 0
+ || indicator.control.icon.source.toString().length > 0
Behavior on x {
enabled: !indicator.control.pressed
@@ -41,9 +75,27 @@ Item {
duration: 300
}
}
- layer.enabled: indicator.Material.elevation > 0
- layer.effect: ElevationEffect {
- elevation: indicator.Material.elevation
+
+ Behavior on scale {
+ NumberAnimation {
+ duration: 100
+ }
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 200
+ }
+ }
+
+ IconImage {
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ name: indicator.control.icon.name
+ source: indicator.control.icon.source
+ sourceSize: Qt.size(indicator.control.icon.width, indicator.control.icon.height)
+ color: indicator.control.icon.color
+ visible: handle.hasIcon
}
}
}
diff --git a/src/quickcontrols/material/qquickmaterialstyle.cpp b/src/quickcontrols/material/qquickmaterialstyle.cpp
index 35ccc59e1f..40304d4d7c 100644
--- a/src/quickcontrols/material/qquickmaterialstyle.cpp
+++ b/src/quickcontrols/material/qquickmaterialstyle.cpp
@@ -380,16 +380,48 @@ static const QRgb raisedButtonDisabledColorLight = dividerColorLight;
static const QRgb raisedButtonDisabledColorDark = dividerColorDark;
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 rippleColorLight = 0x10000000;
static const QRgb rippleColorDark = 0x20FFFFFF;
static const QRgb spinBoxDisabledIconColorLight = 0xFFCCCCCC;
static const QRgb spinBoxDisabledIconColorDark = 0xFF666666;
static const QRgb sliderDisabledColorLight = 0xFF9E9E9E;
static const QRgb sliderDisabledColorDark = 0xFF616161;
+/*
+ https://m3.material.io/components/switch/specs#57a434cd-5fcc-4d79-9bff-12b2a9768789
+
+ light / dark
+ surface: #FFFBFE/#1C1B1F
+ on-surface: #1C1B1F/#E6E1E5
+ surface-variant: #E7E0EC/#49454F
+
+ 12% = 1E
+ 38% = 61
+
+ handle
+
+ unchecked checked
+ disabled #1C1B1F/#E6E1E5 @ 38% (#611C1B1F/#61E6E1E5) #FFFBFE/#1C1B1F @ 100%
+
+ track
+
+ unchecked checked
+ disabled #E7E0EC/#49454F @ 12% (#1EE7E0EC/#1E49454F) #1C1B1F/#E6E1E5 @ 12% (#1E1C1B1F/#1EE6E1E5)
+
+ track outline
+
+ unchecked checked
+ disabled #1C1B1F/#E6E1E5 @ 12% (#1E1C1B1F/#1EE6E1E5) same as track
+*/
+static const QRgb switchUncheckedTrackColorLight = 0xFFE7E0EC;
+static const QRgb switchUncheckedTrackColorDark = 0x49454F;
+static const QRgb switchDisabledUncheckedTrackColorLight = 0x1EE7E0EC;
+static const QRgb switchDisabledUncheckedTrackColorDark = 0x1E49454F;
+static const QRgb switchDisabledUncheckedTrackBorderColorLight = 0x1E1C1B1F;
+static const QRgb switchDisabledUncheckedTrackBorderColorDark = 0x1EE6E1E5;
+static const QRgb switchDisabledCheckedTrackColorLight = 0x1E1C1B1F;
+static const QRgb switchDisabledCheckedTrackColorDark = 0x1EE6E1E5;
+static const QRgb switchDisabledUncheckedIconColorLight = 0x611C1B1F;
+static const QRgb switchDisabledUncheckedIconColorDark = 0x61E6E1E5;
static QQuickMaterialStyle::Theme effectiveTheme(QQuickMaterialStyle::Theme theme)
{
@@ -952,29 +984,67 @@ QColor QQuickMaterialStyle::switchUncheckedTrackColor() const
QColor QQuickMaterialStyle::switchCheckedTrackColor() const
{
- QColor trackColor(accentColor());
- trackColor.setAlphaF(0.5);
- return trackColor;
+ return accentColor(m_theme == Light ? themeShade() : Shade100);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedTrackColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedTrackColorLight : switchDisabledUncheckedTrackColorDark);
+}
+
+QColor QQuickMaterialStyle::switchDisabledCheckedTrackColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledCheckedTrackColorLight : switchDisabledCheckedTrackColorDark);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedTrackBorderColor() const
+{
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedTrackBorderColorLight : switchDisabledUncheckedTrackBorderColorDark);
}
QColor QQuickMaterialStyle::switchUncheckedHandleColor() const
{
- return m_theme == Light ? color(Grey, Shade50) : color(Grey, Shade400);
+ return m_theme == Light ? color(Grey, Shade600) : color(Grey, Shade400);
+}
+
+QColor QQuickMaterialStyle::switchUncheckedHoveredHandleColor() const
+{
+ const QColor color = switchUncheckedHandleColor();
+ return m_theme == Light ? color.darker(140) : color.lighter(120);
}
QColor QQuickMaterialStyle::switchCheckedHandleColor() const
{
- return m_theme == Light ? accentColor() : shade(accentColor(), Shade200);
+ return m_theme == Light ? QColor::fromRgb(0xFFFFFF) : accentColor(Shade800);
+}
+
+QColor QQuickMaterialStyle::switchDisabledUncheckedHandleColor() const
+{
+ if (m_theme == Light)
+ return QColor::fromRgba(0x611C1B1F);
+
+ QColor darkHandleColor = color(Grey, Shade800);
+ darkHandleColor.setAlphaF(0.38f);
+ return darkHandleColor;
+}
+
+QColor QQuickMaterialStyle::switchDisabledCheckedHandleColor() const
+{
+ return QColor::fromRgb(m_theme == Light ? 0xFFFBFE : 0x1C1B1F);
}
-QColor QQuickMaterialStyle::switchDisabledTrackColor() const
+QColor QQuickMaterialStyle::switchDisabledCheckedIconColor() const
{
- return QColor::fromRgba(m_theme == Light ? switchDisabledTrackColorLight : switchDisabledTrackColorDark);
+ return QColor::fromRgba(m_theme == Light ? 0x611C1B1F : 0x61E6E1E5);
}
-QColor QQuickMaterialStyle::switchDisabledHandleColor() const
+QColor QQuickMaterialStyle::switchDisabledUncheckedIconColor() const
{
- return m_theme == Light ? color(Grey, Shade400) : color(Grey, Shade800);
+ return QColor::fromRgba(m_theme == Light
+ ? switchDisabledUncheckedIconColorLight : switchDisabledUncheckedIconColorDark);
}
QColor QQuickMaterialStyle::scrollBarColor() const
diff --git a/src/quickcontrols/material/qquickmaterialstyle_p.h b/src/quickcontrols/material/qquickmaterialstyle_p.h
index 56e541ce07..e133e35b59 100644
--- a/src/quickcontrols/material/qquickmaterialstyle_p.h
+++ b/src/quickcontrols/material/qquickmaterialstyle_p.h
@@ -51,9 +51,15 @@ class QQuickMaterialStyle : public QQuickAttachedPropertyPropagator
Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY themeOrAccentChanged FINAL)
Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchUncheckedHoveredHandleColor READ switchUncheckedHoveredHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledUncheckedTrackColor READ switchDisabledUncheckedTrackColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledCheckedTrackColor READ switchDisabledCheckedTrackColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledUncheckedTrackBorderColor READ switchDisabledUncheckedTrackBorderColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor switchCheckedHandleColor READ switchCheckedHandleColor NOTIFY themeOrAccentChanged FINAL)
- Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY themeChanged FINAL)
- Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledUncheckedHandleColor READ switchDisabledUncheckedHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledCheckedHandleColor READ switchDisabledCheckedHandleColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledCheckedIconColor READ switchDisabledCheckedIconColor NOTIFY themeChanged FINAL)
+ Q_PROPERTY(QColor switchDisabledUncheckedIconColor READ switchDisabledUncheckedIconColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor scrollBarHoveredColor READ scrollBarHoveredColor NOTIFY themeChanged FINAL)
Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY themeChanged FINAL)
@@ -215,10 +221,16 @@ public:
QColor highlightedRippleColor() const;
QColor switchUncheckedTrackColor() const;
QColor switchCheckedTrackColor() const;
+ QColor switchDisabledUncheckedTrackColor() const;
+ QColor switchDisabledCheckedTrackColor() const;
+ QColor switchDisabledUncheckedTrackBorderColor() const;
QColor switchUncheckedHandleColor() const;
+ QColor switchUncheckedHoveredHandleColor() const;
QColor switchCheckedHandleColor() const;
- QColor switchDisabledTrackColor() const;
- QColor switchDisabledHandleColor() const;
+ QColor switchDisabledUncheckedHandleColor() const;
+ QColor switchDisabledCheckedHandleColor() const;
+ QColor switchDisabledCheckedIconColor() const;
+ QColor switchDisabledUncheckedIconColor() const;
QColor scrollBarColor() const;
QColor scrollBarHoveredColor() const;
QColor scrollBarPressedColor() const;
diff --git a/tests/manual/quickcontrols/material/CMakeLists.txt b/tests/manual/quickcontrols/material/CMakeLists.txt
index 1cd3a98d0f..004d3e8708 100644
--- a/tests/manual/quickcontrols/material/CMakeLists.txt
+++ b/tests/manual/quickcontrols/material/CMakeLists.txt
@@ -23,6 +23,7 @@ set(qmake_immediate_resource_files
"pages/ButtonPage.qml"
"pages/DelayButtonPage.qml"
"pages/RoundButtonPage.qml"
+ "pages/SwitchPage.qml"
"qmldir"
)
diff --git a/tests/manual/quickcontrols/material/material.qml b/tests/manual/quickcontrols/material/material.qml
index 720ff0a5ec..78efaf72e3 100644
--- a/tests/manual/quickcontrols/material/material.qml
+++ b/tests/manual/quickcontrols/material/material.qml
@@ -97,7 +97,7 @@ ApplicationWindow {
focus: true
currentIndex: settings.currentControlIndex
anchors.fill: parent
- model: ["Button", "DelayButton", "RoundButton"]
+ model: ["Button", "DelayButton", "RoundButton", "Switch"]
delegate: ItemDelegate {
width: listView.width
text: modelData
diff --git a/tests/manual/quickcontrols/material/pages/SwitchPage.qml b/tests/manual/quickcontrols/material/pages/SwitchPage.qml
new file mode 100644
index 0000000000..5335fa6290
--- /dev/null
+++ b/tests/manual/quickcontrols/material/pages/SwitchPage.qml
@@ -0,0 +1,75 @@
+// 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: Constants.pageTopPadding
+
+ ColumnLayout {
+ width: parent.width
+
+ RowLayout {
+ spacing: 40
+
+ Switch {
+ text: "Switch"
+ }
+
+ Switch {
+ text: "Checked Switch"
+ checked: true
+ }
+
+ Switch {
+ text: "Disabled Switch"
+ enabled: false
+ }
+
+ Switch {
+ text: "Checked disabled Switch"
+ checked: true
+ enabled: false
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+
+ RowLayout {
+ spacing: 40
+
+ Switch {
+ text: "Switch"
+ icon.source: Constants.iconSource
+ }
+
+ Switch {
+ text: "Checked Switch"
+ icon.source: Constants.iconSource
+ checked: true
+ }
+
+ Switch {
+ text: "Disabled Switch"
+ icon.source: Constants.iconSource
+ enabled: false
+ }
+
+ Switch {
+ text: "Checked disabled Switch"
+ icon.source: Constants.iconSource
+ checked: true
+ enabled: false
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+}