From 956e706f74468f29ea5fba5c122ea0a8e675c9de Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Sat, 21 Jun 2025 00:55:03 +1000 Subject: feat: launcher calculator Requires libqalculate --- modules/launcher/Actions.qml | 11 +++ modules/launcher/AppList.qml | 17 +++++ modules/launcher/CalcItem.qml | 162 ++++++++++++++++++++++++++++++++++++++++++ modules/launcher/Content.qml | 5 +- 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 modules/launcher/CalcItem.qml diff --git a/modules/launcher/Actions.qml b/modules/launcher/Actions.qml index da6f726..bca8930 100644 --- a/modules/launcher/Actions.qml +++ b/modules/launcher/Actions.qml @@ -10,7 +10,18 @@ import QtQuick Singleton { id: root + property string qalcResult + readonly property list list: [ + Action { + name: qsTr("Calculator") + desc: qsTr("Do simple math equations (powered by Qalc)") + icon: "calculate" + + function onClicked(list: AppList): void { + root.autocomplete(list, "calc"); + } + }, Action { name: qsTr("Scheme") desc: qsTr("Change the current colour scheme") diff --git a/modules/launcher/AppList.qml b/modules/launcher/AppList.qml index c06893a..bbcb27f 100644 --- a/modules/launcher/AppList.qml +++ b/modules/launcher/AppList.qml @@ -14,11 +14,14 @@ ListView { required property PersistentProperties visibilities property bool isAction: search.text.startsWith(Config.launcher.actionPrefix) + property bool isCalc: search.text.startsWith(`${Config.launcher.actionPrefix}calc `) property bool isScheme: search.text.startsWith(`${Config.launcher.actionPrefix}scheme `) property bool isVariant: search.text.startsWith(`${Config.launcher.actionPrefix}variant `) function getModelValues() { let text = search.text; + if (isCalc) + return [0]; if (isScheme) return Schemes.fuzzyQuery(text); if (isVariant) @@ -49,6 +52,8 @@ ListView { } delegate: { + if (isCalc) + return calcItem; if (isScheme) return schemeItem; if (isVariant) @@ -123,6 +128,14 @@ ListView { } } + Component { + id: calcItem + + CalcItem { + list: root + } + } + Component { id: schemeItem @@ -143,6 +156,10 @@ ListView { ChangeAnim {} } + Behavior on isCalc { + ChangeAnim {} + } + Behavior on isScheme { ChangeAnim {} } diff --git a/modules/launcher/CalcItem.qml b/modules/launcher/CalcItem.qml new file mode 100644 index 0000000..4d87f94 --- /dev/null +++ b/modules/launcher/CalcItem.qml @@ -0,0 +1,162 @@ +import "root:/widgets" +import "root:/services" +import "root:/config" +import Quickshell +import Quickshell.Io +import QtQuick +import QtQuick.Layouts + +Item { + id: root + + required property var list + readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length) + + function onClicked(): void { + Quickshell.execDetached(["sh", "-c", `qalc -t -m 100 '${root.math}' | wl-copy`]); + root.list.visibilities.launcher = false; + } + + implicitHeight: Config.launcher.sizes.itemHeight + + anchors.left: parent?.left + anchors.right: parent?.right + + onMathChanged: { + if (math) { + qalcProc.command = ["qalc", "-m", "100", math]; + qalcProc.running = true; + } + } + + StateLayer { + radius: Appearance.rounding.full + + function onClicked(): void { + root.onClicked(); + } + } + + Binding { + id: binding + + when: root.math.length > 0 + target: metrics + property: "text" + } + + Process { + id: qalcProc + + stdout: StdioCollector { + onStreamFinished: binding.value = text.trim() + } + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.larger + + spacing: Appearance.spacing.normal + + MaterialIcon { + text: "function" + font.pointSize: Appearance.font.size.extraLarge + Layout.alignment: Qt.AlignVCenter + } + + StyledText { + id: result + + color: { + if (metrics.text.includes("error: ")) + return Colours.palette.m3error; + if (!root.math) + return Colours.palette.m3onSurfaceVariant; + return Colours.palette.m3onSurface; + } + + text: metrics.elidedText + font.pointSize: Appearance.font.size.normal + + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + + TextMetrics { + id: metrics + + text: qsTr("Type an expression to calculate") + font.family: result.font.family + font.pointSize: result.font.pointSize + elide: Text.ElideRight + elideWidth: result.width + } + } + + StyledRect { + color: Colours.palette.m3tertiary + radius: Appearance.rounding.normal + clip: true + + implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Appearance.padding.normal * 2 + implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Appearance.padding.small * 2 + + Layout.alignment: Qt.AlignVCenter + + StateLayer { + id: stateLayer + + color: Colours.palette.m3onTertiary + + function onClicked(): void { + Quickshell.execDetached(["app2unit", "--", "foot", "fish", "-C", `exec qalc -i '${root.math}'`]); + root.list.visibilities.launcher = false; + } + } + + StyledText { + id: label + + anchors.verticalCenter: parent.verticalCenter + anchors.right: icon.left + anchors.rightMargin: Appearance.spacing.small + + text: qsTr("Open in calculator") + color: Colours.palette.m3onTertiary + font.pointSize: Appearance.font.size.normal + + opacity: stateLayer.containsMouse ? 1 : 0 + + Behavior on opacity { + NumberAnimation { + duration: Appearance.anim.durations.normal + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.standard + } + } + } + + MaterialIcon { + id: icon + + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: Appearance.padding.normal + + text: "exit_to_app" + color: Colours.palette.m3onTertiary + font.pointSize: Appearance.font.size.large + } + + Behavior on implicitWidth { + NumberAnimation { + duration: Appearance.anim.durations.normal + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.emphasized + } + } + } + } +} diff --git a/modules/launcher/Content.qml b/modules/launcher/Content.qml index 26496a6..486b67a 100644 --- a/modules/launcher/Content.qml +++ b/modules/launcher/Content.qml @@ -86,7 +86,10 @@ Item { Wallpapers.setWallpaper(currentItem.modelData.path); root.visibilities.launcher = false; } else if (text.startsWith(Config.launcher.actionPrefix)) { - currentItem.modelData.onClicked(list.currentList); + if (text.startsWith(`${Config.launcher.actionPrefix}calc `)) + currentItem.onClicked(); + else + currentItem.modelData.onClicked(list.currentList); } else { Apps.launch(currentItem.modelData); root.visibilities.launcher = false; -- cgit v1.2.3-freya