nosignal-shell/components/controls/ButtonBase.qml
2026-05-02 21:26:56 +10:00

93 lines
2.5 KiB
QML

//@ pragma Internal
import QtQuick
import Caelestia.Config
import qs.components
import qs.services
StyledRect {
id: root
enum ButtonType {
Filled,
Tonal,
Text
}
property bool checked
property alias disabled: stateLayer.disabled
property bool isToggle
property bool isRound
property bool radiusMorph
property alias shapeMorph: stateLayer.shapeMorph
property bool fillWidth // For ButtonRow
property font font
property int type: ButtonBase.Filled
property real padding
property real horizontalPadding: padding
property real verticalPadding: padding
readonly property alias pressed: stateLayer.pressed
readonly property alias hovered: stateLayer.containsMouse
readonly property alias stateLayer: stateLayer
readonly property alias radiusAnim: radiusAnim
required property color activeColour
required property color inactiveColour
required property color activeOnColour
required property color inactiveOnColour
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
property color disabledOnColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
property bool internalChecked
property real shapeMorphExpansion: shapeMorph && pressed ? 1.16 : 1
readonly property color onColour: disabled ? disabledOnColour : internalChecked ? activeOnColour : inactiveOnColour
signal clicked
onCheckedChanged: internalChecked = checked
radius: {
if (radiusMorph && pressed)
return Tokens.rounding.small;
if (internalChecked)
return Tokens.rounding.medium;
if (isRound)
return implicitHeight / 2 * Math.min(1, Tokens.rounding.scale);
return Tokens.rounding.large;
}
color: type === ButtonBase.Text ? "transparent" : disabled ? disabledColour : internalChecked ? activeColour : inactiveColour
// Make size required so we don't forget to set it
required implicitWidth
required implicitHeight
StateLayer {
id: stateLayer
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
disabled: root.disabled
onClicked: {
if (root.isToggle)
root.internalChecked = !root.internalChecked;
root.clicked();
}
}
Behavior on radius {
Anim {
id: radiusAnim
type: Anim.DefaultEffects
}
}
Behavior on shapeMorphExpansion {
Anim {
type: Anim.FastSpatial
}
}
}