diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-08-19 20:46:39 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-08-19 21:50:03 +0800 |
| commit | 68e1a276192872c57931e9e43911a479d4619c4a (patch) | |
| tree | 3cb7f752edc931971a429ead938eb1aa7e0af299 /launcher/components | |
| parent | a607f21ebaf6f7752626c1f568f90b36ec40c2c8 (diff) | |
chore(launcher -> popups): reorganize to allow futher expansion on popups
refactor(launcher): ILauncher is now a derivative of IPopup
Diffstat (limited to 'launcher/components')
| -rw-r--r-- | launcher/components/App.qml | 181 | ||||
| -rw-r--r-- | launcher/components/Calc.qml | 81 | ||||
| -rw-r--r-- | launcher/components/Clip.qml | 199 | ||||
| -rw-r--r-- | launcher/components/Emoji.qml | 176 | ||||
| -rw-r--r-- | launcher/components/Finder.qml | 0 | ||||
| -rw-r--r-- | launcher/components/Flight.qml | 0 | ||||
| -rw-r--r-- | launcher/components/IComponent.qml | 93 | ||||
| -rw-r--r-- | launcher/components/IInnerComponent.qml | 34 | ||||
| -rw-r--r-- | launcher/components/SelectionState.qml | 49 | ||||
| -rw-r--r-- | launcher/components/Spell.qml | 235 | ||||
| -rw-r--r-- | launcher/components/Time.qml | 0 | ||||
| -rw-r--r-- | launcher/components/Translate.qml | 0 | ||||
| -rw-r--r-- | launcher/components/Weather.qml | 0 | ||||
| -rw-r--r-- | launcher/components/Web.qml | 0 |
14 files changed, 0 insertions, 1048 deletions
diff --git a/launcher/components/App.qml b/launcher/components/App.qml deleted file mode 100644 index 0bb5fd9..0000000 --- a/launcher/components/App.qml +++ /dev/null @@ -1,181 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.services -import qs.config - -IComponent { - id: root - - property list<DesktopEntry> entries: active ? AppSearch.query(inputCleaned) : [] - property int selectedIndex: -1 - property bool mouseTriggered: false - - name: "Applications" - - implicitHeight: valid ? layout.height : 0 - - preview: Component { - IconImage { - source: Quickshell.iconPath(answer, "image-missing") - implicitWidth: General.appIconSize - implicitHeight: General.appIconSize - } - } - - property string predictiveCompletion: valid ? entries[selectedIndex].name.slice(input.length) : "" - - process: function () { - const isValid = entries.length > 0; - const selected = isValid ? entries[selectedIndex] : ""; - return { - valid: isValid, - priority: isValid, - answer: selected?.icon || "" - }; - } - - exec: function () { - SelectionState.selected.modelData.execute(); - } - - up: function () { - if (selectedIndex <= 0) - return true; - mouseTriggered = false; - selectedIndex--; - } - down: function () { - if (selectedIndex + 1 > listView.count - 1) - return true; - mouseTriggered = false; - selectedIndex++; - } - - home: function () { - if (listView.count === 0) - return true; - mouseTriggered = false; - selectedIndex = -1; - selectedIndex = 0; - } - end: function () { - if (listView.count === 0) - return true; - mouseTriggered = false; - selectedIndex = listView.count; - selectedIndex = listView.count - 1; - } - - pgup: function () { - if (listView.count === 0) - return true; - mouseTriggered = false; - const pageSize = Math.floor(listView.height / (General.appIconSize + Launcher.innerMargin * 2)); - if (selectedIndex - pageSize < 0) { - selectedIndex = 0; - } else { - selectedIndex -= pageSize; - } - } - - pgdn: function () { - if (listView.count === 0) - return true; - mouseTriggered = false; - const pageSize = Math.floor(listView.height / (General.appIconSize + Launcher.innerMargin * 2)); - if (selectedIndex + pageSize >= listView.count) { - selectedIndex = listView.count - 1; - } else { - selectedIndex += pageSize; - } - } - - onEntriesChanged: { - if (selectedIndex !== -1) { - syncSelectionState(); - return; - } - selectedIndex = 0; - listView.contentY = 0; - syncSelectionState(); - } - - onSelectedIndexChanged: { - syncSelectionState(); - if (selectedIndex < 0 || selectedIndex >= listView.count || mouseTriggered) - return; - Qt.callLater(() => { - listView.positionViewAtIndex(selectedIndex, ListView.Contain); - }); - } - - syncSelectionState: function () { - Qt.callLater(() => state.selected = listView.itemAtIndex(selectedIndex)); - } - - IInnerComponent { - id: layout - fromParent: false - width: parent.width - height: Math.min(listView.contentHeight + titleBar.height, Launcher.widgetHeight * 1.5) - - ListView { - id: listView - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - model: entries - spacing: 0 - - delegate: Item { - required property DesktopEntry modelData - required property int index - width: item.implicitWidth + Launcher.innerMargin * 4 - height: item.height + Launcher.innerMargin * 4 - - RowLayout { - id: item - scale: index === selectedIndex ? 1.01 : 0.99 - anchors.left: parent.left - anchors.top: parent.top - anchors.margins: Launcher.innerMargin * 2 - spacing: Launcher.innerMargin * 2 - - IconImage { - source: Quickshell.iconPath(modelData.icon, "image-missing") - implicitWidth: General.appIconSize - implicitHeight: General.appIconSize - } - IText { - text: modelData.name - renderType: Text.QtRendering - color: index === selectedIndex ? Colors.foreground1 : Colors.foreground2 - } - - Behavior on scale { - ISpringAnimation {} - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onPositionChanged: { - root.mouseTriggered = true; - root.selectedIndex = index; - } - onExited: { - root.mouseTriggered = true; - } - onPressed: { - root._exec(); - } - } - } - } - } -} diff --git a/launcher/components/Calc.qml b/launcher/components/Calc.qml deleted file mode 100644 index c6cdbc1..0000000 --- a/launcher/components/Calc.qml +++ /dev/null @@ -1,81 +0,0 @@ -import Quickshell -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.services -import qs.config - -IComponent { - property int cursorPosition: SelectionState.cursorPosition - - name: "Calculator" - preview: Component { - Icon { - text: "" - } - } - - process: function () { - const isValid = /^(?=.*\d)(?=.*[+\-*\/\^])[0-9+\-*\/\^().\s]+$/.test(input); - const answer = isValid ? String(eval(input.replace(/\^/g, '**').replace(/([\d)])\(/g, '$1*(').replace(/\)([\d])/g, ')*$1'))) : null; - return { - valid: isValid, - priority: isValid, - answer: answer, - predictiveCompletion: isValid ? ' = ' + answer : '' - }; - } - exec: function () { - Clip.copy(answer); - } - - IInnerComponent { - RowLayout { - spacing: 0 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: parent.height - - Item { - Layout.fillWidth: true - IText { - anchors.centerIn: parent - elide: cursorPosition > input.length / 2 ? Text.ElideLeft : Text.ElideRight - width: Math.min(implicitWidth, parent.width - Launcher.innerMargin * 2) - clip: true - renderType: Text.CurveRendering - visible: valid - text: input.replace(/ /g, "").replace(/\+/g, " + ").replace(/-/g, " - ").replace(/\*/g, " × ").replace(/\//g, " ÷ ").replace(/%/g, " % ").replace(/\(/g, " ( ").replace(/\)/g, " ) ") - font { - pixelSize: Launcher.widgetFontSize - bold: true - } - } - } - - IText { - visible: valid - text: "→" - font.pixelSize: Launcher.widgetFontSize - font.bold: true - } - - Item { - Layout.fillWidth: true - IText { - animate: true - anchors.centerIn: parent - width: Math.min(implicitWidth, parent.width - Launcher.innerMargin * 2) - renderType: Text.CurveRendering - visible: valid - text: valid ? answer : '' - font { - pixelSize: Launcher.widgetFontSize - bold: true - } - } - } - } - } -} diff --git a/launcher/components/Clip.qml b/launcher/components/Clip.qml deleted file mode 100644 index bc8d65f..0000000 --- a/launcher/components/Clip.qml +++ /dev/null @@ -1,199 +0,0 @@ -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.services -import qs.config - -IComponent { - id: root - - property var clipHist: active ? Clip.query(inputCleaned) : [] - property int selectedIndex: -1 - property bool mouseTriggered: false - - name: "Clipboard" - - prefix: "clip" - - implicitHeight: valid ? layout.height : 0 - - process: function () { - const isValid = clipHist.length > 0; - return { - valid: isValid, - priority: isValid - }; - } - - exec: function () { - Clip.decodeAndCopy(clipHist[selectedIndex].raw); - } - - up: function () { - if (selectedIndex <= 0) - return true; - mouseTriggered = false; - selectedIndex--; - } - down: function () { - if (selectedIndex + 1 > listView.count - 1) - return true; - mouseTriggered = false; - selectedIndex++; - } - - onClipHistChanged: { - if (selectedIndex !== -1) { - syncSelectionState(); - return; - } - mouseTriggered = false; - selectedIndex = 0; - listView.positionViewAtBeginning(); - syncSelectionState(); - } - - onSelectedIndexChanged: { - if (!mouseTriggered && selectedIndex >= 0 && selectedIndex < listView.count) { - Qt.callLater(() => { - listView.positionViewAtIndex(selectedIndex, ListView.Contain); - }); - } - syncSelectionState(); - } - - syncSelectionState: function () { - Qt.callLater(() => state.selected = listView.itemAtIndex(selectedIndex)); - } - - IInnerComponent { - id: layout - fromParent: false - width: parent.width - height: Math.min(listView.contentHeight + titleBar.height, Launcher.widgetHeight * 1.5) - - RowLayout { - Layout.fillWidth: true - Layout.fillHeight: true - - ListView { - id: listView - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - model: clipHist - spacing: 0 - - delegate: Item { - required property var modelData - required property int index - width: Math.min(item.implicitWidth + Launcher.innerMargin * 4, listView.width) - height: item.height + Launcher.innerMargin * 4 - - Row { - id: item - anchors.left: parent.left - anchors.top: parent.top - anchors.margins: Launcher.innerMargin * 2 - spacing: Launcher.innerMargin * 2 - clip: true - - IconImage { - scale: index === root.selectedIndex ? 1.01 : 0.9 - source: modelData?.appIcon - implicitSize: parent.height - - Behavior on scale { - ISpringAnimation {} - } - } - - Column { - Loader { - sourceComponent: modelData?.type === "image" ? img : text - readonly property Component text: IText { - text: modelData?.data || "" - color: index === root.selectedIndex ? Colors.foreground1 : Colors.foreground2 - font.pixelSize: Launcher.widgetFontSize - } - readonly property Component img: Image { - source: modelData?.data || "" - } - } - Row { - spacing: Launcher.innerMargin - property string sinceWhen: TimeDate.sinceWhen(modelData?.timestamp) || "" - IText { - text: modelData.type - color: index === root.selectedIndex ? Colors.foreground2 : Colors.foreground3 - font.pixelSize: Launcher.widgetFontSize / 1.35 - } - IText { - visible: parent.sinceWhen - text: '·' - color: index === root.selectedIndex ? Colors.foreground2 : Colors.foreground3 - font.pixelSize: Launcher.widgetFontSize / 1.35 - } - IText { - text: parent.sinceWhen || "" - color: index === root.selectedIndex ? Colors.foreground2 : Colors.foreground3 - font.pixelSize: Launcher.widgetFontSize / 1.35 - } - } - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onPositionChanged: { - root.mouseTriggered = true; - root.selectedIndex = index; - } - onExited: { - root.mouseTriggered = true; - } - onPressed: { - root._exec(); - } - } - } - } - - Flickable { - id: preview - clip: true - Layout.fillWidth: true - Layout.fillHeight: true - - contentWidth: loader.item.width - contentHeight: loader.item.height - flickableDirection: Flickable.VerticalFlick - boundsBehavior: Flickable.StopAtBounds - - Loader { - id: loader - sourceComponent: clipHist[selectedIndex]?.type === "image" ? img : text - property Component text: TextEdit { - id: textEdit - readOnly: true - width: preview.width - color: Colors.foreground1 - selectionColor: Colors.background3 - text: clipHist[selectedIndex]?.decoded || "" - } - property Component img: Image { - id: image - width: preview.width - height: preview.height - source: clipHist[selectedIndex]?.image || "" - fillMode: Image.PreserveAspectFit - } - } - } - } - } -} diff --git a/launcher/components/Emoji.qml b/launcher/components/Emoji.qml deleted file mode 100644 index d1343e6..0000000 --- a/launcher/components/Emoji.qml +++ /dev/null @@ -1,176 +0,0 @@ -import Quickshell -import Quickshell.Io -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.services -import qs.config - -IComponent { - id: root - - property var emojis: active ? Emoji.query(input) : [] - property int selectedIndex: -1 - - name: "Emoji" - prefix: name.toLowerCase() + " " - - onEmojisChanged: { - Qt.callLater(() => { - if (selectedIndex !== -1) { - syncSelectionState(); - return; - } - selectedIndex = emojis.length > 0 ? 0 : -1; - syncSelectionState(); - if (loader.item && loader.item.flickable) - loader.item.flickable.contentY = 0; - }); - } - - onSelectedIndexChanged: { - if (!loader.view || !loader.item || !loader.item.flickable) - return; - if (selectedIndex < 0 || selectedIndex >= loader.view.count) - return; - Qt.callLater(() => { - syncSelectionState(); - loader.view.currentIndex = selectedIndex; - loader.view.positionViewAtIndex(selectedIndex, GridView.Contain); - }); - } - - process: function () { - const isValid = selectedIndex >= 0 && emojis.length > 0; - const select = isValid ? emojis[selectedIndex] : null; - return { - valid: isValid, - priority: isValid, - answer: isValid ? select.emoji : "" - }; - } - - home: function () { - if (!loader.view.count) - return true; - selectedIndex = 0; - } - end: function () { - if (!loader.view.count) - return true; - selectedIndex = loader.view.count - 1; - } - prev: function () { - if (selectedIndex <= 0) - return true; - selectedIndex--; - } - next: function () { - if (selectedIndex + 1 >= emojis.length) - return true; - selectedIndex++; - } - up: function () { - const cols = loader.view ? Math.max(1, Math.floor(loader.view.width / loader.view.cellWidth)) : 1; - if (selectedIndex - cols < 0) - return true; - selectedIndex -= cols; - } - down: function () { - const cols = loader.view ? Math.max(1, Math.floor(loader.view.width / loader.view.cellWidth)) : 1; - if (selectedIndex + cols >= emojis.length) - return true; - selectedIndex += cols; - } - - exec: function () { - if (selectedIndex >= 0 && emojis.length > 0) - Emoji.copy(emojis[selectedIndex].emoji); - } - - syncSelectionState: function () { - Qt.callLater(() => state.selected = loader.view.itemAtIndex(selectedIndex)); - } - - IInnerComponent { - id: innerLoader - - Loader { - id: loader - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: parent.height - sourceComponent: show - property var view: null - - readonly property Component show: Component { - Item { - property alias flickable: grid - - GridView { - id: grid - anchors.fill: parent - clip: true - boundsBehavior: Flickable.StopAtBounds - cacheBuffer: cellHeight * 2 - model: emojis - interactive: true - flow: GridView.FlowLeftToRight - snapMode: GridView.NoSnap - - cellWidth: Math.min(width / Math.max(1, Math.floor(width / (Launcher.widgetFontSize * 5))), width / 3) - cellHeight: Launcher.widgetFontSize * 2.2 + Launcher.innerMargin * 2 - - delegate: Item { - required property var modelData - required property int index - width: grid.cellWidth - height: grid.cellHeight - scale: index === selectedIndex ? 1.03 : 0.97 - - IRect { - anchors.fill: parent - color: Qt.rgba(Colors.background2.r, Colors.background2.g, Colors.background2.b, Launcher.widgetBgTransparency) - radius: Launcher.widgetRadius - - Column { - id: chipContent - anchors.centerIn: parent - spacing: 2 - - Icon { - anchors.horizontalCenter: parent.horizontalCenter - text: modelData.emoji - font.pixelSize: Launcher.widgetFontSize * 1.2 - } - IText { - anchors.horizontalCenter: parent.horizontalCenter - text: modelData.name - font.pixelSize: Launcher.widgetFontSize * 0.7 - color: index === selectedIndex ? Colors.foreground1 : Colors.foreground2 - elide: Text.ElideRight - width: parent.parent.width - Launcher.innerMargin * 2 - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onPositionChanged: root.selectedIndex = index - onPressed: root._exec() - } - } - - Behavior on scale { - ISpringAnimation {} - } - } - - Component.onCompleted: loader.view = grid - } - } - } - } - } -} diff --git a/launcher/components/Finder.qml b/launcher/components/Finder.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Finder.qml +++ /dev/null diff --git a/launcher/components/Flight.qml b/launcher/components/Flight.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Flight.qml +++ /dev/null diff --git a/launcher/components/IComponent.qml b/launcher/components/IComponent.qml deleted file mode 100644 index 4f47b88..0000000 --- a/launcher/components/IComponent.qml +++ /dev/null @@ -1,93 +0,0 @@ -import Quickshell -import QtQuick - -import qs.components -import qs.config - -IRect { - id: root - // virtual properties - property bool standalone: false - property var state: SelectionState - property string name // Component/File name - readonly property string _input: state.input - readonly property string input: !standalone ? _input.slice(prefix.length) : _input - readonly property string inputCleaned: input.toLowerCase().trim() - property string prefix - property bool active: !standalone ? input && _input.startsWith(prefix) : true - property bool valid: !standalone ? processed?.valid || false : true - property bool priority: !standalone ? valid && processed?.priority || false : true // please set priority to false if it's invalid - property string answer: processed?.answer || "" - property Component preview: Component { - IText { - animate: true - text: answer - } - } - property string predictiveCompletion: processed?.predictiveCompletion || "" // would technically work with just from answer, but stuff like calc's answer wouldnt have anything to do with the input - property var processed: active ? process() : {} // cached process, thought qml would do that automatically :/ - property var process: () => ({ - valid: valid, - priority: priority, - answer: answer, - preview: preview, - predictiveCompletion: predictiveCompletion - })// use the current IRect if valid is set - property var syncSelectionState: () => {} - // actions - property var up: () => ({ - top: false - }) - property var down: () => ({ - bottom: false - }) - property var prev: () => {} - property var next: () => {} - property var exec: () => {} - property var home: () => {} - property var end: () => {} - property var pgup: () => {} - property var pgdn: () => {} - - signal close - - function _exec() { - exec(); - close(); - } - - opacity: valid ? 1 : 0 - y: valid ? 0 : -Launcher.widgetHeight - - implicitWidth: valid ? Launcher.widgetWidth : 0 - implicitHeight: valid ? Launcher.widgetHeight : 0 - - // implicitWidth: Launcher.widgetWidth - // implicitHeight: Launcher.widgetHeight - - radius: Launcher.widgetRadius - color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Launcher.widgetBgTransparency) // TODO when prioritized, highlight - - onPriorityChanged: { - // sync with state.priorities - Qt.callLater(() => { - if (!standalone) - state.priorities = [...[...state.priorities, root].reduce((s, x) => (s[(s.has(x) && 'delete') || 'add'](x), s), new Set())]; - else - state.priorities = [root]; - }); - } - - Behavior on y { - NumberAnimation { - duration: General.animationDuration / 4 - easing.type: Easing.InOutQuad - } - } - - Component.onCompleted: { - Qt.callLater(() => { - syncSelectionState(); - }); - } -} diff --git a/launcher/components/IInnerComponent.qml b/launcher/components/IInnerComponent.qml deleted file mode 100644 index 7bbc9f0..0000000 --- a/launcher/components/IInnerComponent.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.config - -ColumnLayout { - property bool fromParent: true - property alias titleBar: titleBar - anchors.fill: fromParent ? parent : undefined - spacing: 0 - IRect { - id: titleBar - Layout.fillWidth: true - Layout.fillHeight: false - visible: Launcher.showWidgetTitle && valid - height: childrenRect.height - width: parent.width - topLeftRadius: Launcher.widgetRadius - topRightRadius: Launcher.widgetRadius - color: Qt.rgba(Colors.background3.r, Colors.background3.g, Colors.background3.b, Launcher.widgetTitleBgTransparency) - - IText { - anchors { - top: parent.top - left: parent.left - leftMargin: Launcher.innerMargin - } - visible: valid - font.pixelSize: Launcher.widgetFontSize - text: name - } - } -} diff --git a/launcher/components/SelectionState.qml b/launcher/components/SelectionState.qml deleted file mode 100644 index 1ab577a..0000000 --- a/launcher/components/SelectionState.qml +++ /dev/null @@ -1,49 +0,0 @@ -pragma Singleton -import Quickshell -import QtQuick - -Singleton { - id: root - - PersistentProperties { - id: persist - reloadableId: "launcherSelectionState" - - property string input: "" - property int cursorPosition: 0 - property int selectedPriority: 0 - property int previousSelectedPriority: 0 - } - - property Item selected: null - property alias input: persist.input - property alias cursorPosition: persist.cursorPosition - property var priorities: [] - property alias selectedPriority: persist.selectedPriority - property alias previousSelectedPriority: persist.previousSelectedPriority - property var widgets: [] - - onSelectedPriorityChanged: { - if (selectedPriority > previousSelectedPriority) { - priorities[selectedPriority].home(); - priorities[selectedPriority].syncSelectionState(); - } else { - priorities[selectedPriority].end(); - priorities[selectedPriority].syncSelectionState(); - } - - previousSelectedPriority = selectedPriority; - } - // order them based on widgets(which came from order from config) - onPrioritiesChanged: { - for (let i = priorities.length - 1; i >= 0; i--) - if (!priorities[i] || priorities[i].priority !== true) - priorities.splice(i, 1); - - priorities.sort((a, b) => (widgets.indexOf(a) - widgets.indexOf(b)) || 0); - - priorities.forEach((item, index) => {}); - - priorities[selectedPriority]?.syncSelectionState(); - } -} diff --git a/launcher/components/Spell.qml b/launcher/components/Spell.qml deleted file mode 100644 index fe01c3f..0000000 --- a/launcher/components/Spell.qml +++ /dev/null @@ -1,235 +0,0 @@ -import Quickshell -import Quickshell.Io -import QtQuick -import QtQuick.Layouts - -import qs.components -import qs.services -import qs.config - -IComponent { - id: root - - property list<string> aspell - property int selectedIndex: -1 - - name: "Spell" - prefix: name.toLowerCase() + ' ' - - onValidChanged: { - if (valid) - return; - - aspell = []; - proc.running = false; - selectedIndex = -1; - return; - } - - onAspellChanged: { - if (selectedIndex !== -1) { - syncSelectionState(); - return; - } - selectedIndex = aspell.length > 0 ? 0 : -1; - // selectedIndexChanged dont get called somehow - syncSelectionState(); - if (loader.item && loader.item.flickable) { - loader.item.flickable.contentY = 0; - } - } - - onSelectedIndexChanged: { - if (!loader.view || !loader.item || !loader.item.flickable) - return; - if (selectedIndex < 0 || selectedIndex >= loader.view.count) - return; - Qt.callLater(() => { - syncSelectionState(); - loader.view.currentIndex = selectedIndex; - loader.view.positionViewAtIndex(selectedIndex, GridView.Contain); - }); - } - - process: function () { - Qt.callLater(() => { - proc.running = true; - }); - - const isValid = selectedIndex >= 0 && aspell.length > 0; - const selected = isValid ? aspell[selectedIndex] : ""; - const answer = selected === "*" ? input : selected; - - return { - valid: isValid, - priority: isValid, - answer: answer || "", - predictiveCompletion: answer?.slice(input.length) || "" - }; - } - - home: function () { - if (loader.view.count === 0) - return true; - selectedIndex = -1; - selectedIndex = 0; - } - end: function () { - if (loader.view.count === 0) - return true; - selectedIndex = loader.view.count; - selectedIndex = loader.view.count - 1; - } - - prev: function () { - if (selectedIndex <= 0) - return true; - selectedIndex--; - } - - next: function () { - if (selectedIndex + 1 >= aspell.length) - return true; - selectedIndex++; - } - - up: function () { - const cols = loader.view ? Math.max(1, Math.floor(loader.view.width / loader.view.cellWidth)) : 1; - if (selectedIndex - cols < 0) - return true; - selectedIndex -= cols; - } - - down: function () { - const cols = loader.view ? Math.max(1, Math.floor(loader.view.width / loader.view.cellWidth)) : 1; - if (selectedIndex + cols >= aspell.length) - return true; - selectedIndex += cols; - } - - exec: function () { - if (selectedIndex >= 0) - if (aspell[selectedIndex] !== "*") - Clip.copy(aspell[selectedIndex]); - else - Clip.copy(input); - } - - syncSelectionState: function () { - Qt.callLater(() => state.selected = loader.view.itemAtIndex(selectedIndex)); - } - - IInnerComponent { - id: innerLoader - Loader { - id: loader - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: parent.height - sourceComponent: aspell[0] === "*" ? correct : show - property var view: null - - readonly property Component show: Component { - Item { - property alias flickable: grid - - GridView { - id: grid - anchors.fill: parent - clip: true - boundsBehavior: Flickable.StopAtBounds - cacheBuffer: 0 - model: aspell - interactive: true - flow: GridView.FlowLeftToRight - snapMode: GridView.NoSnap - - cellWidth: Math.min(width / Math.max(1, Math.floor(width / (Launcher.widgetFontSize * 4))), width / 2) - cellHeight: Launcher.widgetFontSize * 1.4 + Launcher.innerMargin * 2 - - delegate: Item { - required property var modelData - required property int index - - width: grid.cellWidth - height: grid.cellHeight - scale: index === selectedIndex ? 1.03 : 0.97 - - IRect { - anchors.fill: parent - color: Qt.rgba(Colors.background2.r, Colors.background2.g, Colors.background2.b, Launcher.widgetBgTransparency) - radius: Launcher.widgetRadius - - IText { - id: chipContent - anchors.centerIn: parent - text: modelData - font.pixelSize: Launcher.widgetFontSize - elide: Text.ElideRight - color: index === selectedIndex ? Colors.foreground1 : Colors.foreground2 - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onPositionChanged: { - root.selectedIndex = index; - } - onPressed: { - root._exec(); - } - } - } - - Behavior on scale { - ISpringAnimation {} - } - } - - Component.onCompleted: { - loader.view = grid; - } - } - } - } - - readonly property Component correct: Component { - IRect { - Layout.fillWidth: true - color: Qt.rgba(Colors.background1.r, Colors.background1.g, Colors.background1.b, Launcher.widgetBgTransparency / 4) - radius: Launcher.widgetRadius - IText { - anchors.centerIn: parent - text: "Correct" - font.pixelSize: Launcher.widgetFontSize - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - } - - Process { - id: proc - command: ["sh", "-c", "echo " + input + " | aspell -a"] - property bool found: false - stdout: SplitParser { - onRead: data => { - if (data.startsWith("&")) { - proc.found = true; - aspell = data.split(/\W+/).filter(input => /^[A-Za-z]+$/.test(input)).slice(1); - } else if (data.startsWith("*")) { - proc.found = true; - aspell = ["*"]; - } - } - } - onStarted: { - found = false; - } - onExited: { - if (!found) - aspell = []; - } - } -} diff --git a/launcher/components/Time.qml b/launcher/components/Time.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Time.qml +++ /dev/null diff --git a/launcher/components/Translate.qml b/launcher/components/Translate.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Translate.qml +++ /dev/null diff --git a/launcher/components/Weather.qml b/launcher/components/Weather.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Weather.qml +++ /dev/null diff --git a/launcher/components/Web.qml b/launcher/components/Web.qml deleted file mode 100644 index e69de29..0000000 --- a/launcher/components/Web.qml +++ /dev/null |
