165 lines
5.7 KiB
QML
165 lines
5.7 KiB
QML
// The connected displays, as chips under the arrangement canvas.
|
|
//
|
|
// This replaces the "Connected display" picker card. Selecting a display is not
|
|
// a setting -- it decides which display everything below the canvas is talking
|
|
// about -- so it reads as a row of tabs rather than as a preference with a
|
|
// value. Clicking a tile on the canvas does the same thing; this is the same
|
|
// choice for anyone who would rather read names than shapes.
|
|
//
|
|
// Hidden for a single display, because a chooser offering one option is not a
|
|
// choice.
|
|
|
|
import QtQuick
|
|
import qs.config
|
|
|
|
Flow {
|
|
id: root
|
|
|
|
// [{ value, label, detail, primary }]
|
|
property var options: []
|
|
property string current: ""
|
|
property bool enabled: true
|
|
|
|
signal picked(string value)
|
|
|
|
visible: root.options.length > 1
|
|
width: parent ? parent.width : 620
|
|
height: root.visible ? implicitHeight : 0
|
|
spacing: 10
|
|
|
|
// Chips share the width evenly while they fit; below that they wrap into
|
|
// rows of whatever does fit, so a dock with four outputs is still legible
|
|
// in a half-screen window.
|
|
readonly property int columns: Math.max(1,
|
|
Math.min(root.options.length, Math.floor(root.width / 210)))
|
|
readonly property real chipWidth: root.columns > 0
|
|
? (root.width - root.spacing * (root.columns - 1)) / root.columns
|
|
: root.width
|
|
|
|
Repeater {
|
|
model: root.options
|
|
|
|
Rectangle {
|
|
id: chip
|
|
|
|
required property var modelData
|
|
required property int index
|
|
|
|
readonly property bool selected: String(chip.modelData.value) === root.current
|
|
|
|
width: root.chipWidth
|
|
implicitHeight: 52
|
|
radius: Theme.cardRadius
|
|
opacity: root.enabled ? 1 : 0.5
|
|
color: chip.selected
|
|
? Theme.alpha(Theme.accent, 0.1)
|
|
: Theme.alpha(Theme.bgPanel, chipHover.hovered && root.enabled ? 0.9 : 0.72)
|
|
border.width: chip.selected || chip.activeFocus ? 2 : 1
|
|
border.color: chip.activeFocus
|
|
? Theme.accentSecondary
|
|
: (chip.selected ? Theme.alpha(Theme.accent, 0.55) : Theme.alpha(Theme.fg, 0.07))
|
|
activeFocusOnTab: root.enabled
|
|
|
|
Accessible.role: Accessible.Button
|
|
Accessible.name: "Select " + String(chip.modelData.label ?? "")
|
|
Accessible.focusable: true
|
|
Accessible.focused: chip.activeFocus
|
|
|
|
function choose(): void {
|
|
if (root.enabled)
|
|
root.picked(String(chip.modelData.value));
|
|
}
|
|
|
|
Keys.onReturnPressed: chip.choose()
|
|
Keys.onSpacePressed: chip.choose()
|
|
|
|
// A screen, small. The second display gets the other end of the
|
|
// palette so the two chips are told apart at a glance rather than
|
|
// by reading them.
|
|
Rectangle {
|
|
id: thumbnail
|
|
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 13
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: 34
|
|
height: 24
|
|
radius: 5
|
|
border.width: 1
|
|
border.color: Theme.alpha(Theme.fg, 0.25)
|
|
|
|
gradient: Gradient {
|
|
orientation: Gradient.Horizontal
|
|
GradientStop {
|
|
position: 0.0
|
|
color: Theme.alpha(chip.index % 2 === 0 ? Theme.accent : Theme.teal, 0.5)
|
|
}
|
|
GradientStop {
|
|
position: 1.0
|
|
color: Theme.alpha(chip.index % 2 === 0 ? Theme.accentSecondary : Theme.cyan, 0.4)
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
anchors.left: thumbnail.right
|
|
anchors.leftMargin: 11
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 12
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 1
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: 5
|
|
|
|
Text {
|
|
width: Math.max(0, parent.width - (star.visible ? star.width + 5 : 0))
|
|
text: String(chip.modelData.label ?? "")
|
|
color: Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
font.weight: Font.DemiBold
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Text {
|
|
id: star
|
|
visible: chip.modelData.primary === true
|
|
width: visible ? implicitWidth : 0
|
|
text: "★"
|
|
color: Theme.warn
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
}
|
|
}
|
|
|
|
Text {
|
|
width: parent.width
|
|
visible: text !== ""
|
|
text: String(chip.modelData.detail ?? "")
|
|
color: Theme.fgDim
|
|
font.family: Theme.fontFamily
|
|
font.features: Theme.tabularFigures
|
|
font.pixelSize: Math.max(9, Theme.fontSizeSmall - 1)
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
|
|
HoverHandler {
|
|
id: chipHover
|
|
enabled: root.enabled
|
|
cursorShape: Qt.PointingHandCursor
|
|
}
|
|
|
|
TapHandler {
|
|
enabled: root.enabled && !chip.selected
|
|
onTapped: {
|
|
chip.choose();
|
|
chip.forceActiveFocus();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|