diff options
Diffstat (limited to 'desktop/Settings.qml')
| -rw-r--r-- | desktop/Settings.qml | 43 |
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); |
