nosignal-shell/components/controls/SplitButton.qml
28allday 83c6b62c13 feat(nosignal): finish Nerd Font icon remap — core surfaces
Convert remaining reachable surfaces to NsIcon (launcher, utilities, windowinfo,
sidebar, dashboard, notification toast, shared controls IconTextButton/Menu/
SplitButton/ToggleButton/CollapsibleSection/CustomSpinBox, CoverArt). Handles
the `sourceComponent: MaterialIcon {` form and icon-via-alias controls.

- IconTextButton: alias -> plain `icon` property + bound NsIcon (cross-file alias
  to a custom property was rejected).
- Reverted IconButton `font:` (the controls-wide font->fontStyle sweep wrongly
  hit ButtonBase, which uses font not fontStyle).
- Glyphs map: +31 names (dashboard/utilities/launcher leftovers) — no "?" glyphs.

Old collapsed bar + old lock sub-components left as-is (unused, never render).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 12:59:28 +01:00

151 lines
4.6 KiB
QML

import QtQuick
import QtQuick.Layouts
import Caelestia.Config
import qs.components
import qs.services
Row {
id: root
enum Type {
Filled,
Tonal
}
property real horizontalPadding: Tokens.padding.medium
property real verticalPadding: Tokens.padding.small
property int type: SplitButton.Filled
property bool disabled
property bool menuOnTop
property string fallbackIcon
property string fallbackText
property real minLeftWidth
property alias menuItems: menu.items
property alias active: menu.active
property alias expanded: menu.expanded
readonly property alias menu: menu
readonly property alias iconLabel: iconLabel
readonly property alias label: label
readonly property alias stateLayer: stateLayer
readonly property alias textRow: textRow
readonly property alias expandBtn: expandBtn
property color colour: type == SplitButton.Filled ? Colours.palette.m3primary : Colours.palette.m3secondaryContainer
property color textColour: type == SplitButton.Filled ? Colours.palette.m3onPrimary : Colours.palette.m3onSecondaryContainer
property color disabledColour: Qt.alpha(Colours.palette.m3onSurface, 0.1)
property color disabledTextColour: Qt.alpha(Colours.palette.m3onSurface, 0.38)
spacing: Math.floor(Tokens.spacing.extraSmall)
StyledRect {
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topRightRadius: Tokens.rounding.medium / 2
bottomRightRadius: Tokens.rounding.medium / 2
color: root.disabled ? root.disabledColour : root.colour
implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2)
implicitHeight: expandBtn.implicitHeight
StateLayer {
id: stateLayer
topRightRadius: parent.topRightRadius
bottomRightRadius: parent.bottomRightRadius
color: root.textColour
disabled: root.disabled
onClicked: root.active?.clicked()
}
RowLayout {
id: textRow
anchors.centerIn: parent
anchors.horizontalCenterOffset: Math.floor(root.verticalPadding / 4)
spacing: Tokens.spacing.small
NsIcon {
id: iconLabel
Layout.alignment: Qt.AlignVCenter
animate: true
icon: root.active?.activeIcon ?? root.fallbackIcon
color: root.disabled ? root.disabledTextColour : root.textColour
fill: 1
}
StyledText {
id: label
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: implicitWidth
animate: true
text: root.active?.activeText ?? root.fallbackText
color: root.disabled ? root.disabledTextColour : root.textColour
clip: true
Behavior on Layout.preferredWidth {
Anim {
type: Anim.Emphasized
}
}
}
}
}
StyledRect {
id: expandBtn
property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Tokens.rounding.scale) : Tokens.rounding.medium / 2
radius: implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
topLeftRadius: rad
bottomLeftRadius: rad
color: root.disabled ? root.disabledColour : root.colour
implicitWidth: implicitHeight
implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2
StateLayer {
id: expandStateLayer
rect.topLeftRadius: parent.topLeftRadius
rect.bottomLeftRadius: parent.bottomLeftRadius
color: root.textColour
disabled: root.disabled
onClicked: root.expanded = !root.expanded
}
NsIcon {
id: expandIcon
anchors.centerIn: parent
anchors.horizontalCenterOffset: root.expanded ? 0 : -Math.floor(root.verticalPadding / 4)
icon: "expand_more"
color: root.disabled ? root.disabledTextColour : root.textColour
rotation: root.expanded ? 180 : 0
Behavior on anchors.horizontalCenterOffset {
Anim {}
}
Behavior on rotation {
Anim {}
}
}
Behavior on rad {
Anim {}
}
}
Menu {
id: menu
attachTo: expandBtn
attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom
thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top
marginY: Tokens.spacing.small * (root.menuOnTop ? -1 : 1)
}
}