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
This commit is contained in:
Lukáš Tinkl 2024-12-18 20:36:52 +01:00
parent 0592e2338b
commit 564e91496a
No known key found for this signature in database
4 changed files with 184 additions and 24 deletions

View File

@ -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

View File

@ -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

View File

@ -23,8 +23,11 @@ CheckBox {
} }
property bool leftSide: true 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 { QtObject {
id: d id: d
@ -40,7 +43,7 @@ CheckBox {
} }
font.family: Theme.baseFont.name 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 { indicator: Rectangle {
objectName: "indicator" objectName: "indicator"
@ -49,12 +52,11 @@ CheckBox {
implicitWidth: size === StatusCheckBox.Size.Regular implicitWidth: size === StatusCheckBox.Size.Regular
? d.indicatorSizeRegular : d.indicatorSizeSmall ? d.indicatorSizeRegular : d.indicatorSizeSmall
implicitHeight: implicitWidth implicitHeight: implicitWidth
x: !root.leftSide? root.rightPadding : root.leftPadding x: root.text ? (root.mirrored ? root.width - width - root.rightPadding : root.leftPadding) : root.leftPadding + (root.availableWidth - width) / 2
y: parent.height / 2 - height / 2 y: root.topPadding + (root.availableHeight - height) / 2
radius: 2 radius: 2
color: root.down || checkState !== Qt.Checked color: checkState !== Qt.Checked ? Theme.palette.directColor7 : Theme.palette.primaryColor1
? Theme.palette.directColor8 Behavior on color { ColorAnimation { duration: Theme.AnimationDuration.Fast } }
: Theme.palette.primaryColor1
StatusIcon { StatusIcon {
icon: "checkbox" icon: "checkbox"
@ -63,9 +65,11 @@ CheckBox {
height: size === StatusCheckBox.Size.Regular height: size === StatusCheckBox.Size.Regular
? d.indicatorIconHeightRegular : d.indicatorIconHeightSmall ? d.indicatorIconHeightRegular : d.indicatorIconHeightSmall
anchors.centerIn: parent anchors.centerIn: parent
anchors.horizontalCenterOffset: 1 anchors.horizontalCenterOffset: root.mirrored ? - 1 : 1
color: checkState === Qt.PartiallyChecked ? Theme.palette.directColor9 : Theme.palette.white 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 wrapMode: Text.WordWrap
width: parent.width width: parent.width
lineHeight: 1.2 lineHeight: 1.2
leftPadding: root.leftSide? (!!root.text ? root.indicator.width + root.spacing leftPadding: root.indicator && !root.mirrored ? root.indicator.width + root.spacing : 0
: root.indicator.width) : 0 rightPadding: root.indicator && root.mirrored ? root.indicator.width + root.spacing : 0
rightPadding: !root.leftSide? (!!root.text ? root.indicator.width + root.spacing
: root.indicator.width) : 0
visible: !!text visible: !!text
} }

View File

@ -4,7 +4,6 @@ import QtGraphicalEffects 1.15
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
Switch { Switch {
id: root id: root
@ -14,10 +13,14 @@ Switch {
font.family: Theme.baseFont.name font.family: Theme.baseFont.name
font.pixelSize: Theme.primaryTextFontSize font.pixelSize: Theme.primaryTextFontSize
background: MouseArea { background: null
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton padding: 4
} opacity: enabled ? 1.0 : Theme.disabledOpacity
property bool leftSide: true
LayoutMirroring.enabled: !leftSide
LayoutMirroring.childrenInherit: true
indicator: Item { indicator: Item {
id: oval id: oval
@ -33,8 +36,8 @@ Switch {
radius: 14 radius: 14
color: root.checked ? Theme.palette.primaryColor1 color: root.checked ? Theme.palette.primaryColor1
: Theme.palette.directColor8 : Theme.palette.directColor7
opacity: root.enabled ? 1 : 0.2 Behavior on color { ColorAnimation { duration: Theme.AnimationDuration.Fast } }
} }
Rectangle { Rectangle {
@ -68,20 +71,23 @@ Switch {
} }
] ]
transitions: Transition { Behavior on x {
reversible: true enabled: !root.pressed
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120} SmoothedAnimation {}
} }
} }
} }
contentItem: StatusBaseText { contentItem: StatusBaseText {
text: root.text text: root.text
opacity: enabled ? 1.0 : 0.3
color: root.textColor color: root.textColor
font: root.font font: root.font
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
leftPadding: root.mirrored ? 0 : !!root.text ? root.indicator.width + root.spacing : root.indicator.width 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 rightPadding: root.mirrored ? !!root.text ? root.indicator.width + root.spacing : root.indicator.width : 0
} }
HoverHandler {
cursorShape: root.enabled && root.hovered ? Qt.PointingHandCursor : undefined
}
} }