// An enum setting, bound to a schema key by name. // // ChoiceRow { setting: "vrrPolicy" } // // The options are the schema's, so a row can never offer a value the store // would reject. Rendered as a segmented control rather than a dropdown: every // choice here has two or three options, and showing them all is both faster to // use and self-documenting. import QtQuick import qs.config import qs.services SettingRow { id: root required property string setting readonly property var spec: PreferenceSchema.spec(root.setting) readonly property var options: root.spec && root.spec.options ? root.spec.options : [] readonly property var current: DesktopPreferences.get(root.setting) label: root.spec ? root.spec.label : root.setting detail: root.spec ? root.spec.detail : "" controlWidth: Math.max(120, root.options.length * 92) readonly property var currentOption: root.options.find(option => option.value === root.current) ?? null // Left and Right move one segment along and commit, which is what the // segments already do under a click -- the arrows are just the other way to // reach the same neighbour. It never wraps: running off the end of a // segmented control silently landing on the far end is how a keyboard user // sets something they did not mean to. function stepChoice(delta: int): void { if (root.options.length === 0) return; const at = root.options.findIndex(option => option.value === root.current); const from = at < 0 ? 0 : at; const next = Math.max(0, Math.min(root.options.length - 1, from + delta)); if (next === at) return; SystemSettings.commitPreference(root.setting, root.options[next].value); } Rectangle { id: group anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter implicitWidth: segments.implicitWidth + 4 implicitHeight: 30 radius: 9 color: Theme.alpha(Theme.fg, 0.07) border.width: 0 activeFocusOnTab: true Accessible.role: Accessible.ComboBox Accessible.name: root.label Accessible.description: { const chosen = root.currentOption ? String(root.currentOption.label ?? "") : "nothing selected"; return root.detail === "" ? chosen : `${root.detail} — ${chosen}`; } Accessible.focusable: true Accessible.focused: group.activeFocus Keys.onLeftPressed: root.stepChoice(-1) Keys.onUpPressed: root.stepChoice(-1) Keys.onRightPressed: root.stepChoice(1) Keys.onDownPressed: root.stepChoice(1) // Focus ring only -- the strip keeps its borderless plate at rest. Rectangle { anchors.fill: parent anchors.margins: -3 radius: 11 color: "transparent" visible: group.activeFocus border.width: 2 border.color: Theme.accentSecondary } Row { id: segments anchors.centerIn: parent spacing: 0 Repeater { model: root.options Rectangle { id: segment required property var modelData readonly property bool selected: root.current === segment.modelData.value implicitWidth: Math.max(70, caption.implicitWidth + 24) implicitHeight: 26 radius: 7 border.width: 0 color: "transparent" // Named individually so the reader says which option it is // on, not just that a choice exists. Not a Tab stop: the // strip is one stop and the arrows walk it. Accessible.role: Accessible.RadioButton Accessible.name: String(segment.modelData.label ?? "") Accessible.checked: segment.selected // The selected segment is the only place the prism appears // in a row: blue leads into orchid, never orchid alone. Rectangle { anchors.fill: parent radius: parent.radius visible: segment.selected border.width: 0 gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0; color: Theme.alpha(Theme.accent, 0.30) } GradientStop { position: 1.0; color: Theme.alpha(Theme.accentSecondary, 0.30) } } } Rectangle { anchors.fill: parent radius: parent.radius border.width: 0 visible: !segment.selected && hover.hovered color: Theme.alpha(Theme.fg, 0.06) } Text { id: caption anchors.centerIn: parent text: segment.modelData.label color: segment.selected ? Theme.fg : Theme.fgDim font.family: Theme.fontFamily font.pixelSize: Theme.fontSize font.weight: segment.selected ? Font.DemiBold : Font.Normal } HoverHandler { id: hover } TapHandler { onTapped: SystemSettings.commitPreference(root.setting, segment.modelData.value) } } } } } }