summaryrefslogtreecommitdiff
path: root/launcher/components
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-08-19 20:46:39 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-08-19 21:50:03 +0800
commit68e1a276192872c57931e9e43911a479d4619c4a (patch)
tree3cb7f752edc931971a429ead938eb1aa7e0af299 /launcher/components
parenta607f21ebaf6f7752626c1f568f90b36ec40c2c8 (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.qml181
-rw-r--r--launcher/components/Calc.qml81
-rw-r--r--launcher/components/Clip.qml199
-rw-r--r--launcher/components/Emoji.qml176
-rw-r--r--launcher/components/Finder.qml0
-rw-r--r--launcher/components/Flight.qml0
-rw-r--r--launcher/components/IComponent.qml93
-rw-r--r--launcher/components/IInnerComponent.qml34
-rw-r--r--launcher/components/SelectionState.qml49
-rw-r--r--launcher/components/Spell.qml235
-rw-r--r--launcher/components/Time.qml0
-rw-r--r--launcher/components/Translate.qml0
-rw-r--r--launcher/components/Weather.qml0
-rw-r--r--launcher/components/Web.qml0
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