From 564e91496acf7afffdeb276f06ac81328b93682f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Wed, 18 Dec 2024 20:36:52 +0100 Subject: [PATCH] chore(StatusCheckBox/Switch): UI updates & some fixes - fix a bug where the Switch would start animating if it'd been checked on creation - add the same property `leftSide` to StatusSwitch (just like StatusCheckBox), and use `LayoutMirroring` to perform the visual inversion - fixup margins and padding, removing hardcoded values, according to latest Figma designs - make a difference between a disabled and inactive button by using opacity - provide smooth color transitions - add dedicated StoryBook pages --- storybook/pages/StatusCheckBoxPage.qml | 84 +++++++++++++++++++ storybook/pages/StatusSwitchPage.qml | 68 +++++++++++++++ .../src/StatusQ/Controls/StatusCheckBox.qml | 28 ++++--- .../src/StatusQ/Controls/StatusSwitch.qml | 28 ++++--- 4 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 storybook/pages/StatusCheckBoxPage.qml create mode 100644 storybook/pages/StatusSwitchPage.qml diff --git a/storybook/pages/StatusCheckBoxPage.qml b/storybook/pages/StatusCheckBoxPage.qml new file mode 100644 index 0000000000..cc63758275 --- /dev/null +++ b/storybook/pages/StatusCheckBoxPage.qml @@ -0,0 +1,84 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import StatusQ.Controls 0.1 + +import Storybook 1.0 + +SplitView { + id: root + + orientation: Qt.Vertical + Logs { id: logs } + + Item { + SplitView.fillWidth: true + SplitView.fillHeight: true + + Rectangle { + width: switchControl.width + height: switchControl.height + anchors.centerIn: parent + color: "transparent" + border.width: 1 + border.color: "pink" + + StatusCheckBox { + id: switchControl + anchors.centerIn: parent + text: ctrlWithText.checked ? "Check me out" : "" + leftSide: !ctrlInverted.checked + changeCursor: ctrlCursor.checked + checked: true + enabled: ctrlEnabled.checked + tristate: ctrlTristate.checked + size: ctrlSmall.checked ? StatusCheckBox.Size.Small : StatusCheckBox.Size.Regular + onClicked: logs.logEvent("clicked()") + onToggled: logs.logEvent("toggled()") + } + } + } + + LogsAndControlsPanel { + SplitView.minimumHeight: 320 + SplitView.preferredHeight: 320 + + logsView.logText: logs.logText + + ColumnLayout { + Layout.fillWidth: true + + Switch { + id: ctrlEnabled + text: "Enabled" + checked: true + } + Switch { + id: ctrlCursor + text: "Change cursor" + checked: true + } + Switch { + id: ctrlInverted + text: "Inverted" + } + Switch { + id: ctrlSmall + text: "Small size" + } + Switch { + id: ctrlTristate + text: "Tristate" + } + Switch { + id: ctrlWithText + text: "With text" + checked: true + } + } + } +} + +// category: Controls +// status: good diff --git a/storybook/pages/StatusSwitchPage.qml b/storybook/pages/StatusSwitchPage.qml new file mode 100644 index 0000000000..c61661895d --- /dev/null +++ b/storybook/pages/StatusSwitchPage.qml @@ -0,0 +1,68 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import StatusQ.Controls 0.1 + +import Storybook 1.0 + +SplitView { + id: root + + orientation: Qt.Vertical + Logs { id: logs } + + Item { + SplitView.fillWidth: true + SplitView.fillHeight: true + + Rectangle { + width: switchControl.width + height: switchControl.height + anchors.centerIn: parent + color: "transparent" + border.width: 1 + border.color: "pink" + + StatusSwitch { + id: switchControl + anchors.centerIn: parent + text: ctrlWithText.checked ? "Check me out" : "" + leftSide: !ctrlInverted.checked + checked: true + enabled: ctrlEnabled.checked + onClicked: logs.logEvent("clicked()") + onToggled: logs.logEvent("toggled()") + } + } + } + + LogsAndControlsPanel { + SplitView.minimumHeight: 200 + SplitView.preferredHeight: 200 + + logsView.logText: logs.logText + + ColumnLayout { + Layout.fillWidth: true + + Switch { + id: ctrlEnabled + text: "Enabled" + checked: true + } + Switch { + id: ctrlInverted + text: "Inverted" + } + Switch { + id: ctrlWithText + text: "With text" + checked: true + } + } + } +} + +// category: Controls +// status: good diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusCheckBox.qml b/ui/StatusQ/src/StatusQ/Controls/StatusCheckBox.qml index 6cb41126f3..51897d954d 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusCheckBox.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusCheckBox.qml @@ -23,8 +23,11 @@ CheckBox { } property bool leftSide: true + LayoutMirroring.enabled: !leftSide + LayoutMirroring.childrenInherit: true - opacity: enabled ? 1.0 : 0.3 + padding: 4 + opacity: enabled ? 1.0 : Theme.disabledOpacity QtObject { id: d @@ -40,7 +43,7 @@ CheckBox { } font.family: Theme.baseFont.name - font.pixelSize: size === StatusCheckBox.Size.Regular ? 15 : 13 + font.pixelSize: size === StatusCheckBox.Size.Regular ? Theme.primaryTextFontSize : Theme.additionalTextSize indicator: Rectangle { objectName: "indicator" @@ -49,12 +52,11 @@ CheckBox { implicitWidth: size === StatusCheckBox.Size.Regular ? d.indicatorSizeRegular : d.indicatorSizeSmall implicitHeight: implicitWidth - x: !root.leftSide? root.rightPadding : root.leftPadding - y: parent.height / 2 - height / 2 + x: root.text ? (root.mirrored ? root.width - width - root.rightPadding : root.leftPadding) : root.leftPadding + (root.availableWidth - width) / 2 + y: root.topPadding + (root.availableHeight - height) / 2 radius: 2 - color: root.down || checkState !== Qt.Checked - ? Theme.palette.directColor8 - : Theme.palette.primaryColor1 + color: checkState !== Qt.Checked ? Theme.palette.directColor7 : Theme.palette.primaryColor1 + Behavior on color { ColorAnimation { duration: Theme.AnimationDuration.Fast } } StatusIcon { icon: "checkbox" @@ -63,9 +65,11 @@ CheckBox { height: size === StatusCheckBox.Size.Regular ? d.indicatorIconHeightRegular : d.indicatorIconHeightSmall anchors.centerIn: parent - anchors.horizontalCenterOffset: 1 + anchors.horizontalCenterOffset: root.mirrored ? - 1 : 1 color: checkState === Qt.PartiallyChecked ? Theme.palette.directColor9 : Theme.palette.white - visible: root.down || checkState !== Qt.Unchecked + opacity: checkState !== Qt.Unchecked ? 1 : 0 + visible: opacity > 0 + Behavior on opacity { OpacityAnimator { duration: Theme.AnimationDuration.Fast } } } } @@ -76,10 +80,8 @@ CheckBox { wrapMode: Text.WordWrap width: parent.width lineHeight: 1.2 - leftPadding: root.leftSide? (!!root.text ? root.indicator.width + root.spacing - : root.indicator.width) : 0 - rightPadding: !root.leftSide? (!!root.text ? root.indicator.width + root.spacing - : root.indicator.width) : 0 + leftPadding: root.indicator && !root.mirrored ? root.indicator.width + root.spacing : 0 + rightPadding: root.indicator && root.mirrored ? root.indicator.width + root.spacing : 0 visible: !!text } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml b/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml index c616c8d61d..691eedcb0e 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml @@ -4,7 +4,6 @@ import QtGraphicalEffects 1.15 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 -import StatusQ.Components 0.1 Switch { id: root @@ -14,10 +13,14 @@ Switch { font.family: Theme.baseFont.name font.pixelSize: Theme.primaryTextFontSize - background: MouseArea { - cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor - acceptedButtons: Qt.NoButton - } + background: null + + padding: 4 + opacity: enabled ? 1.0 : Theme.disabledOpacity + + property bool leftSide: true + LayoutMirroring.enabled: !leftSide + LayoutMirroring.childrenInherit: true indicator: Item { id: oval @@ -33,8 +36,8 @@ Switch { radius: 14 color: root.checked ? Theme.palette.primaryColor1 - : Theme.palette.directColor8 - opacity: root.enabled ? 1 : 0.2 + : Theme.palette.directColor7 + Behavior on color { ColorAnimation { duration: Theme.AnimationDuration.Fast } } } Rectangle { @@ -68,20 +71,23 @@ Switch { } ] - transitions: Transition { - reversible: true - NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120} + Behavior on x { + enabled: !root.pressed + SmoothedAnimation {} } } } contentItem: StatusBaseText { text: root.text - opacity: enabled ? 1.0 : 0.3 color: root.textColor font: root.font verticalAlignment: Text.AlignVCenter leftPadding: root.mirrored ? 0 : !!root.text ? root.indicator.width + root.spacing : root.indicator.width rightPadding: root.mirrored ? !!root.text ? root.indicator.width + root.spacing : root.indicator.width : 0 } + + HoverHandler { + cursorShape: root.enabled && root.hovered ? Qt.PointingHandCursor : undefined + } }