aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/Settings.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/Settings.qml')
-rw-r--r--desktop/Settings.qml43
1 files changed, 33 insertions, 10 deletions
diff --git a/desktop/Settings.qml b/desktop/Settings.qml
index 52ca549..9882193 100644
--- a/desktop/Settings.qml
+++ b/desktop/Settings.qml
@@ -32,22 +32,40 @@ Scope {
}
property string query: ""
- // The pages the search keeps, as {mod, hit}: hit is the keyword that
- // matched when the label did not, shown under the entry.
+ // What the search keeps, as {mod, hit, key}. A page matched by its label
+ // or a keyword has key "" and opens at the top; hit is the keyword when
+ // the label did not match. Then each row inside a page that matches, from
+ // the module's searchItems, with key naming that row.
+ readonly property int perPage: 8
readonly property var found: {
const q = root.query.trim().toLowerCase();
const out = [];
for (const m of root.pages) {
- if (q === "" || m.label.toLowerCase().includes(q) || m.name.includes(q)) {
- out.push({ mod: m, hit: "" });
- continue;
+ if (q === "" || m.label.toLowerCase().includes(q) || m.name.includes(q))
+ out.push({ mod: m, hit: "", key: "" });
+ else {
+ const k = Array.from(m.keywords).find(w => w.toLowerCase().includes(q));
+ if (k !== undefined) out.push({ mod: m, hit: k, key: "" });
}
- const k = Array.from(m.keywords).find(w => w.toLowerCase().includes(q));
- if (k !== undefined) out.push({ mod: m, hit: k });
+ if (q === "") continue;
+ // ponytail: the first perPage rows per page; a narrower query finds the rest.
+ for (const it of m.searchItems.filter(it => it.text.toLowerCase().includes(q)).slice(0, root.perPage))
+ out.push({ mod: m, hit: it.text, key: it.key });
}
return out;
}
+ // The page is shown first so the Loader holds it, then asked to reveal.
+ signal reveal(string key)
+ function go(entry) {
+ root.page = entry.mod.name;
+ if (entry.key) root.reveal(entry.key);
+ }
+
+ // The search index is the modules' own copy of their rows, reread on
+ // every open so it matches what the pages will show.
+ onOpenChanged: if (root.open) for (const m of root.pages) m.refresh()
+
// Null is the landing page.
readonly property QtObject current: root.pages.find(m => m.name === root.page) ?? null
@@ -96,7 +114,7 @@ Scope {
font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
text: root.query
onTextEdited: root.query = text
- onAccepted: if (root.found.length) root.page = root.found[0].mod.name
+ onAccepted: if (root.found.length) root.go(root.found[0])
Keys.onEscapePressed: event => {
if (root.query !== "") root.query = "";
else event.accepted = false;
@@ -121,7 +139,7 @@ Scope {
delegate: Rectangle {
id: entry
required property var modelData
- readonly property bool selected: root.current === modelData.mod
+ readonly property bool selected: root.current === modelData.mod && modelData.key === ""
width: side.width
height: modelData.hit ? 46 : 36
radius: 8
@@ -159,7 +177,7 @@ Scope {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
- onClicked: root.page = entry.modelData.mod.name
+ onClicked: root.go(entry.modelData)
}
}
}
@@ -225,6 +243,11 @@ Scope {
// The Page's back arrow steps out to the landing page,
// dismiss closes the window, and go() moves to another
// settings page by name.
+ Connections {
+ target: root
+ function onReveal(key) { if (pageLoader.item?.reveal) pageLoader.item.reveal(key); }
+ }
+
onLoaded: {
if (item && item.back) item.back.connect(root.back);
if (item && item.dismiss) item.dismiss.connect(root.close);