feat: use button base component
This commit is contained in:
parent
5c1158018b
commit
17281a66a5
7 changed files with 38 additions and 154 deletions
|
|
@ -3,75 +3,37 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias icon: label.text
|
property alias icon: label.text
|
||||||
property bool checked
|
readonly property alias label: label
|
||||||
property bool toggle
|
|
||||||
property real padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
|
|
||||||
property alias font: label.fontStyle
|
|
||||||
property int type: IconButton.Filled
|
|
||||||
property bool disabled
|
|
||||||
property bool isRound
|
|
||||||
|
|
||||||
readonly property alias pressed: stateLayer.pressed
|
padding: type === IconButton.Text ? Tokens.padding.extraSmall / 2 : Tokens.padding.small
|
||||||
readonly property alias hovered: stateLayer.containsMouse
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
activeColour: type === IconButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
property alias label: label
|
inactiveColour: {
|
||||||
property alias radiusAnim: radiusAnim
|
if (!isToggle && type === IconButton.Filled)
|
||||||
|
|
||||||
property bool internalChecked
|
|
||||||
property color activeColour: type === IconButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
|
||||||
property color inactiveColour: {
|
|
||||||
if (!toggle && type === IconButton.Filled)
|
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === IconButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
return type === IconButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
||||||
}
|
}
|
||||||
property color activeOnColour: type === IconButton.Filled ? Colours.palette.m3onPrimary : type === IconButton.Tonal ? Colours.palette.m3onSecondary : Colours.palette.m3primary
|
activeOnColour: type === IconButton.Filled ? Colours.palette.m3onPrimary : type === IconButton.Tonal ? Colours.palette.m3onSecondary : Colours.palette.m3primary
|
||||||
property color inactiveOnColour: {
|
inactiveOnColour: {
|
||||||
if (!toggle && type === IconButton.Filled)
|
if (!isToggle && type === IconButton.Filled)
|
||||||
return Colours.palette.m3onPrimary;
|
return Colours.palette.m3onPrimary;
|
||||||
return type === IconButton.Tonal ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurfaceVariant;
|
return type === IconButton.Tonal ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurfaceVariant;
|
||||||
}
|
}
|
||||||
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
|
|
||||||
property color disabledOnColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
|
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
onCheckedChanged: internalChecked = checked
|
|
||||||
|
|
||||||
radius: stateLayer.pressed ? Tokens.rounding.small : internalChecked ? Tokens.rounding.medium : isRound ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.large
|
|
||||||
color: type === IconButton.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour
|
|
||||||
|
|
||||||
implicitWidth: implicitHeight
|
implicitWidth: implicitHeight
|
||||||
implicitHeight: label.implicitHeight + padding * 2
|
implicitHeight: label.implicitHeight + padding * 2
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
|
||||||
disabled: root.disabled
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: root.disabled ? root.disabledOnColour : root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
fill: !root.toggle || root.internalChecked ? 1 : 0
|
fontStyle: root.font
|
||||||
|
fill: !root.isToggle || root.internalChecked ? 1 : 0
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
Anim {
|
Anim {
|
||||||
|
|
@ -79,12 +41,4 @@ StyledRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {
|
|
||||||
id: radiusAnim
|
|
||||||
|
|
||||||
type: Anim.DefaultEffects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,55 +4,23 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias icon: iconLabel.text
|
property alias icon: iconLabel.text
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property bool checked
|
|
||||||
property bool toggle
|
|
||||||
property real horizontalPadding: Tokens.padding.medium
|
|
||||||
property real verticalPadding: Tokens.padding.small
|
|
||||||
property alias font: label.font
|
|
||||||
property int type: IconTextButton.Filled
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
readonly property alias iconLabel: iconLabel
|
||||||
property alias iconLabel: iconLabel
|
readonly property alias label: label
|
||||||
property alias label: label
|
|
||||||
|
|
||||||
property bool internalChecked
|
activeColour: type === IconTextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
property color activeColour: type === IconTextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
inactiveColour: type === IconTextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer
|
||||||
property color inactiveColour: type === IconTextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer
|
activeOnColour: type === IconTextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary
|
||||||
property color activeOnColour: type === IconTextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary
|
inactiveOnColour: type === IconTextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
||||||
property color inactiveOnColour: type === IconTextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
|
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
onCheckedChanged: internalChecked = checked
|
|
||||||
|
|
||||||
radius: internalChecked ? Tokens.rounding.medium : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
|
||||||
color: type === IconTextButton.Text ? "transparent" : internalChecked ? activeColour : inactiveColour
|
|
||||||
|
|
||||||
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
implicitWidth: row.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: row.implicitHeight + verticalPadding * 2
|
implicitHeight: row.implicitHeight + verticalPadding * 2
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: row
|
id: row
|
||||||
|
|
||||||
|
|
@ -64,7 +32,7 @@ StyledRect {
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.topMargin: Math.round(fontInfo.pointSize * 0.0575)
|
Layout.topMargin: Math.round(fontInfo.pointSize * 0.0575)
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
fill: root.internalChecked ? 1 : 0
|
fill: root.internalChecked ? 1 : 0
|
||||||
|
|
||||||
Behavior on fill {
|
Behavior on fill {
|
||||||
|
|
@ -79,11 +47,7 @@ StyledRect {
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.topMargin: -Math.round(iconLabel.fontInfo.pointSize * 0.0575)
|
Layout.topMargin: -Math.round(iconLabel.fontInfo.pointSize * 0.0575)
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,75 +3,41 @@ import Caelestia.Config
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.services
|
import qs.services
|
||||||
|
|
||||||
StyledRect {
|
ButtonBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum Type {
|
|
||||||
Filled,
|
|
||||||
Tonal,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property bool checked
|
readonly property alias label: label
|
||||||
property bool toggle
|
|
||||||
property real horizontalPadding: Tokens.padding.medium
|
|
||||||
property real verticalPadding: Tokens.padding.small
|
|
||||||
property alias font: label.font
|
|
||||||
property int type: TextButton.Filled
|
|
||||||
|
|
||||||
property alias stateLayer: stateLayer
|
horizontalPadding: Tokens.padding.medium
|
||||||
property alias label: label
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
property bool internalChecked
|
activeColour: type === TextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
||||||
property color activeColour: type === TextButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondary
|
inactiveColour: {
|
||||||
property color inactiveColour: {
|
if (!isToggle && type === TextButton.Filled)
|
||||||
if (!toggle && type === TextButton.Filled)
|
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
return type === TextButton.Filled ? Colours.tPalette.m3surfaceContainer : Colours.palette.m3secondaryContainer;
|
||||||
}
|
}
|
||||||
property color activeOnColour: {
|
activeOnColour: {
|
||||||
if (type === TextButton.Text)
|
if (type === TextButton.Text)
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary;
|
return type === TextButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondary;
|
||||||
}
|
}
|
||||||
property color inactiveOnColour: {
|
inactiveOnColour: {
|
||||||
if (!toggle && type === TextButton.Filled)
|
if (!isToggle && type === TextButton.Filled)
|
||||||
return Colours.palette.m3onPrimary;
|
return Colours.palette.m3onPrimary;
|
||||||
if (type === TextButton.Text)
|
if (type === TextButton.Text)
|
||||||
return Colours.palette.m3primary;
|
return Colours.palette.m3primary;
|
||||||
return type === TextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer;
|
return type === TextButton.Filled ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal clicked
|
|
||||||
|
|
||||||
onCheckedChanged: internalChecked = checked
|
|
||||||
|
|
||||||
radius: internalChecked ? Tokens.rounding.medium : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
|
|
||||||
color: type === TextButton.Text ? "transparent" : internalChecked ? activeColour : inactiveColour
|
|
||||||
|
|
||||||
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
implicitWidth: label.implicitWidth + horizontalPadding * 2
|
||||||
implicitHeight: label.implicitHeight + verticalPadding * 2
|
implicitHeight: label.implicitHeight + verticalPadding * 2
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
|
||||||
onClicked: {
|
|
||||||
if (root.toggle)
|
|
||||||
root.internalChecked = !root.internalChecked;
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: label
|
id: label
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
|
color: root.onColour
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on radius {
|
|
||||||
Anim {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ StyledRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: modelData.label
|
text: modelData.label
|
||||||
checked: _checked
|
checked: _checked
|
||||||
toggle: false
|
isToggle: false
|
||||||
type: TextButton.Tonal
|
type: TextButton.Tonal
|
||||||
|
|
||||||
// Create binding in Component.onCompleted
|
// Create binding in Component.onCompleted
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ Item {
|
||||||
PlayerControl {
|
PlayerControl {
|
||||||
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
icon: Players.active?.isPlaying ? "pause" : "play_arrow"
|
||||||
label.animate: true
|
label.animate: true
|
||||||
toggle: true
|
isToggle: true
|
||||||
padding: Tokens.padding.extraSmall / 2
|
padding: Tokens.padding.extraSmall / 2
|
||||||
checked: Players.active?.isPlaying ?? false
|
checked: Players.active?.isPlaying ?? false
|
||||||
font: Tokens.font.icon.builders.large.scale(1.5).build()
|
font: Tokens.font.icon.builders.large.scale(1.5).build()
|
||||||
|
|
|
||||||
|
|
@ -256,7 +256,7 @@ StyledRect {
|
||||||
IconButton {
|
IconButton {
|
||||||
label.animate: true
|
label.animate: true
|
||||||
icon: Recorder.paused ? "play_arrow" : "pause"
|
icon: Recorder.paused ? "play_arrow" : "pause"
|
||||||
toggle: true
|
isToggle: true
|
||||||
checked: Recorder.paused
|
checked: Recorder.paused
|
||||||
type: IconButton.Tonal
|
type: IconButton.Tonal
|
||||||
font: Tokens.font.icon.large
|
font: Tokens.font.icon.large
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ StyledRect {
|
||||||
delegate: Toggle {
|
delegate: Toggle {
|
||||||
icon: "settings"
|
icon: "settings"
|
||||||
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
||||||
toggle: false
|
isToggle: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.visibilities.utilities = false;
|
root.visibilities.utilities = false;
|
||||||
root.popouts.detach("network");
|
root.popouts.detach("network");
|
||||||
|
|
@ -143,7 +143,7 @@ StyledRect {
|
||||||
icon: "vpn_key"
|
icon: "vpn_key"
|
||||||
checked: VPN.connected && VPN.status.state !== "needs-auth" && VPN.status.state !== "error"
|
checked: VPN.connected && VPN.status.state !== "needs-auth" && VPN.status.state !== "error"
|
||||||
enabled: !VPN.connecting
|
enabled: !VPN.connecting
|
||||||
toggle: VPN.status.state !== "needs-auth" && VPN.status.state !== "error"
|
isToggle: VPN.status.state !== "needs-auth" && VPN.status.state !== "error"
|
||||||
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
||||||
onClicked: VPN.toggle()
|
onClicked: VPN.toggle()
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ StyledRect {
|
||||||
Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Tokens.padding.large : internalChecked ? Tokens.padding.small : 0)
|
Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Tokens.padding.large : internalChecked ? Tokens.padding.small : 0)
|
||||||
radius: stateLayer.pressed ? Tokens.rounding.medium / 2 : internalChecked ? Tokens.rounding.medium : Tokens.rounding.large
|
radius: stateLayer.pressed ? Tokens.rounding.medium / 2 : internalChecked ? Tokens.rounding.medium : Tokens.rounding.large
|
||||||
inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
|
inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
|
||||||
toggle: true
|
isToggle: true
|
||||||
radiusAnim.duration: Tokens.anim.durations.expressiveFastSpatial
|
radiusAnim.duration: Tokens.anim.durations.expressiveFastSpatial
|
||||||
radiusAnim.easing: Tokens.anim.expressiveFastSpatial
|
radiusAnim.easing: Tokens.anim.expressiveFastSpatial
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue