From 8e8ea841dec20b587e425412ff1fd452eeab88a7 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Fri, 2 May 2025 13:46:44 +1000 Subject: feat: launcher base --- config/LauncherConfig.qml | 12 +++ modules/bar/Bar.qml | 18 ++--- modules/launcher/Launcher.qml | 182 ++++++++++++++++++++++++++++++++++++++++++ shell.qml | 2 + widgets/CustomShortcut.qml | 5 ++ 5 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 config/LauncherConfig.qml create mode 100644 modules/launcher/Launcher.qml create mode 100644 widgets/CustomShortcut.qml diff --git a/config/LauncherConfig.qml b/config/LauncherConfig.qml new file mode 100644 index 0000000..1b9efc0 --- /dev/null +++ b/config/LauncherConfig.qml @@ -0,0 +1,12 @@ +pragma Singleton + +import Quickshell +import QtQuick + +Singleton { + readonly property Sizes sizes: Sizes {} + + component Sizes: QtObject { + property int width: 600 + } +} diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml index c739b2a..37d2617 100644 --- a/modules/bar/Bar.qml +++ b/modules/bar/Bar.qml @@ -64,17 +64,15 @@ Variants { active: false opacity: 0 - states: [ - State { - name: "visible" - when: BarConfig.preset.name === loader.presetName - - PropertyChanges { - loader.opacity: 1 - loader.active: true - } + states: State { + name: "visible" + when: BarConfig.preset.name === loader.presetName + + PropertyChanges { + loader.opacity: 1 + loader.active: true } - ] + } transitions: [ Transition { diff --git a/modules/launcher/Launcher.qml b/modules/launcher/Launcher.qml new file mode 100644 index 0000000..8313721 --- /dev/null +++ b/modules/launcher/Launcher.qml @@ -0,0 +1,182 @@ +import "root:/widgets" +import "root:/config" +import Quickshell +import QtQuick +import QtQuick.Shapes +import Qt5Compat.GraphicalEffects + +Scope { + id: root + + property bool bindInterrupted + property bool launcherVisible + + LazyLoader { + id: loader + + loading: true + + StyledWindow { + id: win + + name: "launcher" + + width: content.width + bg.rounding * 2 + height: content.implicitHeight + + anchors.bottom: true + + Shape { + id: bg + + readonly property int rounding: Appearance.rounding.large + readonly property int roundingY: Math.min(rounding, wrapper.height / 2) + readonly property real wrapperHeight: wrapper.height - 1 // Pixel issues :sob: + + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + preferredRendererType: Shape.CurveRenderer + opacity: Appearance.transparency.enabled ? Appearance.transparency.base : 1 + + ShapePath { + strokeWidth: -1 + fillColor: Appearance.colours.m3surface + + startY: bg.wrapperHeight + + PathArc { + relativeX: bg.rounding + relativeY: -bg.roundingY + radiusX: bg.rounding + radiusY: bg.roundingY + direction: PathArc.Counterclockwise + } + PathLine { + relativeX: 0 + y: bg.roundingY + } + PathArc { + relativeX: bg.rounding + relativeY: -bg.roundingY + radiusX: bg.rounding + radiusY: bg.roundingY + } + PathLine { + x: wrapper.width - bg.rounding * 2 + } + PathArc { + relativeX: bg.rounding + relativeY: bg.roundingY + radiusX: bg.rounding + radiusY: bg.roundingY + } + PathLine { + relativeX: 0 + y: bg.wrapperHeight - bg.roundingY + } + PathArc { + relativeX: bg.rounding + relativeY: bg.roundingY + radiusX: bg.rounding + radiusY: bg.roundingY + direction: PathArc.Counterclockwise + } + } + } + + Item { + id: wrapper + + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + + height: 0 + visible: false + + clip: true + + states: State { + name: "visible" + when: root.launcherVisible + + PropertyChanges { + wrapper.height: content.height + wrapper.visible: true + } + } + + transitions: [ + Transition { + from: "" + to: "visible" + + SequentialAnimation { + PropertyAction { + target: wrapper + property: "visible" + } + NumberAnimation { + target: wrapper + property: "height" + duration: Appearance.anim.durations.large + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.emphasizedDecel + } + } + }, + Transition { + from: "visible" + to: "" + + SequentialAnimation { + NumberAnimation { + target: wrapper + property: "height" + duration: Appearance.anim.durations.extraLarge + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.anim.curves.emphasizedDecel + } + PropertyAction { + target: wrapper + property: "visible" + } + } + } + ] + + PaddedRect { + id: content + + width: LauncherConfig.sizes.width + padding: Appearance.padding.large + anchors.horizontalCenter: parent.horizontalCenter + + StyledText { + text: "Launcher" + font.pointSize: 80 + } + } + } + } + } + + CustomShortcut { + name: "launcher" + description: "Toggle launcher" + onPressed: root.bindInterrupted = false + onReleased: { + if (!root.bindInterrupted) + root.launcherVisible = !root.launcherVisible; + root.bindInterrupted = false; + } + } + + CustomShortcut { + name: "launcherInterrupt" + description: "Interrupt launcher keybind" + onPressed: root.bindInterrupted = true + } +} diff --git a/shell.qml b/shell.qml index a1ab585..1131bae 100644 --- a/shell.qml +++ b/shell.qml @@ -1,4 +1,5 @@ import "modules/bar" +import "modules/launcher" import "config" import Quickshell import QtQuick.Controls.Material @@ -10,4 +11,5 @@ ShellRoot { Material.background: Appearance.colours.m3background Bar {} + Launcher {} } diff --git a/widgets/CustomShortcut.qml b/widgets/CustomShortcut.qml new file mode 100644 index 0000000..aa35ed8 --- /dev/null +++ b/widgets/CustomShortcut.qml @@ -0,0 +1,5 @@ +import Quickshell.Hyprland + +GlobalShortcut { + appid: "caelestia" +} -- cgit v1.2.3-freya