Files
Panama/config/dot/quickshell/modules/settings/OptionPickerRow.qml
T

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