Give Sound the whole story, and keep the buttons inside the card
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
// One chip per channel the selected output actually has.
|
||||
//
|
||||
// "Test" used to play a single front-centre sample, which answers "is this the
|
||||
// right device" and nothing else. A surround receiver wired to the wrong socket
|
||||
// passes that test. Each chip plays its own channel's sample, so the answer to
|
||||
// "is the rear left speaker actually rear left" is one click rather than a
|
||||
// guess -- and the chip lights while its sample is playing, so a silent speaker
|
||||
// is visibly a silent speaker rather than a click that did nothing.
|
||||
|
||||
import QtQuick
|
||||
import qs.config
|
||||
import qs.services
|
||||
import qs.widgets
|
||||
|
||||
Flow {
|
||||
id: root
|
||||
|
||||
property var node: null
|
||||
|
||||
// [{ name, label }], ordered, from the node's own channel map.
|
||||
readonly property var channels: root.node ? SoundTest.channelsFor(root.node) : []
|
||||
|
||||
width: parent ? parent.width : 620
|
||||
spacing: 10
|
||||
|
||||
// Chips share the width evenly while they fit and wrap when they do not, so
|
||||
// stereo gets two wide chips and 7.1 gets rows of whatever fits.
|
||||
readonly property int columns: Math.max(1,
|
||||
Math.min(root.channels.length, Math.floor(root.width / 150)))
|
||||
readonly property real chipWidth: root.columns > 0
|
||||
? (root.width - root.spacing * (root.columns - 1)) / root.columns
|
||||
: root.width
|
||||
|
||||
Repeater {
|
||||
model: root.channels
|
||||
|
||||
Rectangle {
|
||||
id: chip
|
||||
|
||||
required property var modelData
|
||||
|
||||
readonly property string channelName: String(chip.modelData.name ?? "")
|
||||
readonly property bool playing: SoundTest.playingChannel === chip.channelName
|
||||
|
||||
width: root.chipWidth
|
||||
implicitHeight: 44
|
||||
radius: Theme.cardRadius
|
||||
color: chip.playing
|
||||
? Theme.alpha(Theme.accent, 0.20)
|
||||
: Theme.alpha(Theme.fg, chipHover.hovered ? 0.08 : 0.04)
|
||||
border.width: 1
|
||||
border.color: chip.playing
|
||||
? Theme.alpha(Theme.accent, 0.60)
|
||||
: Theme.alpha(Theme.fg, 0.09)
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: "Play " + String(chip.modelData.label ?? "")
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: 8
|
||||
|
||||
ThemedIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
size: 16
|
||||
icon: "audio-volume-high-symbolic"
|
||||
iconFallback: "audio-speakers-symbolic"
|
||||
tint: chip.playing ? Theme.fg : Theme.fgDim
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: String(chip.modelData.label ?? "")
|
||||
color: chip.playing ? Theme.fg : Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: chipHover
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: SoundTest.playChannel(root.node, chip.channelName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user