90 lines
3.3 KiB
QML
90 lines
3.3 KiB
QML
// A choice with more options, or wider labels, than a segmented control can
|
|
// carry: collapsed to its current value, expanding to the list.
|
|
//
|
|
// ChoiceRow puts every option on one line, which works for two or three short
|
|
// ones and falls apart at four with sentences under them -- and on this page
|
|
// two cards sit side by side, so a row has half the width it used to.
|
|
//
|
|
// Schema-bound when you name a key, hand-fed when you do not:
|
|
//
|
|
// OptionPickerRow { setting: "powerButtonAction" }
|
|
//
|
|
// gets its label, explanation, option list and current value from
|
|
// PreferenceSchema and commits the pick for you, exactly as ToggleRow and
|
|
// ChoiceRow do. Leaving `setting` empty keeps the original behavior, which is
|
|
// what the display rows need: some of these choices are not preferences at all
|
|
// but compositor state going through a keep-or-revert transaction, so the
|
|
// caller says what a pick means rather than this writing it.
|
|
|
|
import QtQuick
|
|
import qs.config
|
|
import qs.services
|
|
|
|
PickerRow {
|
|
id: root
|
|
|
|
// Empty means "not a stored preference"; see above.
|
|
property string setting: ""
|
|
|
|
readonly property var spec:
|
|
root.setting === "" ? null : PreferenceSchema.spec(root.setting)
|
|
|
|
// [{ value, label, detail }]
|
|
property var options: root.spec && root.spec.options ? root.spec.options : []
|
|
property var current: root.setting === "" ? null : DesktopPreferences.get(root.setting)
|
|
|
|
label: root.spec ? root.spec.label : ""
|
|
detail: root.spec ? root.spec.detail : ""
|
|
|
|
signal picked(var value)
|
|
|
|
// Connected rather than handled inline: a caller that declares its own
|
|
// `onPicked` replaces a handler written in this file, and a schema-bound
|
|
// row that silently stopped writing would be a bad way to find that out.
|
|
Connections {
|
|
target: root
|
|
function onPicked(value: var): void {
|
|
if (root.setting !== "")
|
|
SystemSettings.commitPreference(root.setting, value);
|
|
}
|
|
}
|
|
|
|
readonly property var currentOption:
|
|
root.options.find(option => option.value === root.current) ?? null
|
|
|
|
value: root.currentOption ? String(root.currentOption.label ?? "") : ""
|
|
|
|
Repeater {
|
|
model: root.options
|
|
|
|
TextRow {
|
|
required property var modelData
|
|
required property int index
|
|
|
|
width: parent.width
|
|
label: String(modelData.label ?? "")
|
|
detail: String(modelData.detail ?? "")
|
|
value: modelData.value === root.current ? "Current" : ""
|
|
controlWidth: 90
|
|
divider: index < root.options.length - 1
|
|
activatable: modelData.value !== root.current
|
|
|
|
// An option in an open list, not a button: the reader should say
|
|
// which one is already chosen. The current option is deliberately
|
|
// not activatable and so not a Tab stop -- picking what is already
|
|
// picked is not a thing to walk to.
|
|
activeFocusOnTab: modelData.value !== root.current
|
|
|
|
Accessible.role: Accessible.RadioButton
|
|
Accessible.name: String(modelData.label ?? "")
|
|
Accessible.description: String(modelData.detail ?? "")
|
|
Accessible.checked: modelData.value === root.current
|
|
|
|
onActivated: {
|
|
root.picked(modelData.value);
|
|
root.collapse();
|
|
}
|
|
}
|
|
}
|
|
}
|