Files
qbz/crates/qbz-qt/qml/controls/SettingsButton.qml
T
vicrodh fed0816e9b fix(qt): ambient mode reaches every chrome control
Under the ambient field some controls still painted the opaque theme
token while their neighbours used the half-alpha one: the album track
filter and its select toggle, the Library tab strip's host, the Local
Library icon selects, the header's active nav items and open playlists
button, the queue sidebar's now-playing card and artwork placeholders,
the Listen list's floating actions, and the shared SettingsButton,
IconTextButton, multi-select bar, text area, load-more pill, tree row
selection, sidebar count chips, Purchases tab strip, play-history filter
box and Orbit banner. Each now takes the ambient-aware fill the header
search and QbzTabBar already use (theme.ambientOn ? …A50 : …).

Tooltips, popups and modals stay opaque on purpose: they are read over
content, not chrome.

cc
2026-09-14 00:39:47 -06:00

94 lines
3.4 KiB
QML

// Settings SecondaryButton (IntegrationsSettings.slint:27 /
// AppearanceSettings.slint:83) — min 160px (compact variant 34px square for
// icon buttons), 34px tall, bordered, optional danger red (#e0564f ≈
// theme.danger), busy spinner text.
import QtQuick
import com.blitzfc.qbz
import "../theme"
Rectangle {
// Explicit density opt-in; desktop geometry remains the default.
property bool kioskHost: false
id: root
property string text: ""
property string iconName: ""
// Trailing chevron/glyph AFTER the label (the Slint settings rows that open
// a sub-view: ContentFilteringSettings.slint's Manage affordance). "" = none.
property string trailingIconName: ""
property bool danger: false
property bool busy: false
// The two metrics the MyQBZ modal footers and the Disco builder need. The
// Slint's SecondaryButton is 34px/min-160 in Settings and 38px/hug in a
// modal footer, which is one control with two call-site numbers — not two
// components (TRACK-RULES §5). minWidth: 0 = hug the content.
property int btnHeight: 34
property int minWidth: 160
signal clicked()
QbzTheme { id: theme }
width: Math.max(iconName !== "" && text === "" ? 34 : minWidth, row.implicitWidth + 24)
height: kioskHost ? Math.max(44, btnHeight) : btnHeight
radius: theme.radiusSm
border.width: root.activeFocus ? 2 : 1
border.color: root.activeFocus ? theme.accent
: (danger ? theme.danger : theme.borderSubtle)
color: enabled && btnArea.containsMouse ? theme.surfaceHover : (theme.ambientOn ? theme.surfaceElevatedA50 : theme.surfaceElevated)
opacity: enabled ? 1.0 : 0.4
activeFocusOnTab: enabled
Accessible.role: Accessible.Button
Accessible.name: text
Accessible.onPressAction: if (root.enabled) root.clicked()
Keys.onPressed: function (event) {
if (root.enabled && !event.isAutoRepeat
&& (event.key === Qt.Key_Space
|| event.key === Qt.Key_Return
|| event.key === Qt.Key_Enter)) {
root.clicked()
event.accepted = true
}
}
Row {
id: row
anchors.centerIn: parent
spacing: 8
QbzIcon {
visible: iconName !== ""
name: iconName
width: 15
height: 15
anchors.verticalCenter: parent.verticalCenter
tintName: danger ? "favorite" : "secondary"
}
Text {
visible: text !== ""
text: parent.parent.text
color: parent.parent.danger ? theme.danger : theme.textPrimary
font.pixelSize: root.kioskHost ? theme.fontBody * 1.2 : theme.fontBody
font.weight: theme.weightMedium
verticalAlignment: Text.AlignVCenter
}
QbzIcon {
visible: parent.parent.trailingIconName !== ""
name: parent.parent.trailingIconName
width: 15
height: 15
anchors.verticalCenter: parent.verticalCenter
tintName: parent.parent.danger ? "favorite" : "secondary"
}
}
MouseArea {
id: btnArea
anchors.fill: parent
hoverEnabled: true
cursorShape: parent.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onPressed: if (root.enabled) root.forceActiveFocus()
onClicked: if (root.enabled) root.clicked()
}
}