// 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(); } } } } }