diff --git a/.nvim.lua b/.nvim.lua index 7168375..d5f9ede 100644 --- a/.nvim.lua +++ b/.nvim.lua @@ -1,3 +1,3 @@ -require("lspconfig").qmlls.setup() +vim.lsp.enable("qmlls") require("nvim-treesitter").install({ "qmljs" }) diff --git a/.qmlls.ini b/.qmlls.ini new file mode 120000 index 0000000..4f81584 --- /dev/null +++ b/.qmlls.ini @@ -0,0 +1 @@ +/run/user/1000/quickshell/vfs/feb6ddef68a55c1886b9c19683c71793/.qmlls.ini \ No newline at end of file diff --git a/Bar.qml b/Bar.qml new file mode 100644 index 0000000..79d013e --- /dev/null +++ b/Bar.qml @@ -0,0 +1,50 @@ +import Quickshell +import Quickshell.Hyprland +import QtQuick +import "Components/Color.js" as Colors + +import "Components" +import "Components/Pill" + +Scope { + Variants { + model: Quickshell.screens + + delegate: Component { + PanelWindow { + id: win + required property var modelData + + screen: modelData + + Behavior on implicitHeight { + NumberAnimation { duration: 0; easing.type: Easing.InOutQuad } + } + + property HyprlandMonitor monitor: Hyprland.monitorFor(modelData) + + color: "transparent" + + exclusionMode: ExclusionMode.Normal + + mask: Region { + item: container + } + + anchors { + top: true + left: true + right: true + } + + implicitHeight: 1000 + exclusiveZone: 15 + + Pill { + id: container + monitor: win.monitor + } + } + } + } +} diff --git a/Components/Clock.qml b/Components/Clock.qml new file mode 100644 index 0000000..b14621d --- /dev/null +++ b/Components/Clock.qml @@ -0,0 +1,42 @@ +// Time.qml + +// with this line our type becomes a Singleton +pragma Singleton + +import Quickshell +import Quickshell.Io +import QtQuick + +// your singletons should always have Singleton as the type +Singleton { + id: root + property string time + property string day + + Process { + id: timeProc + command: ["date", "+%T"] + running: true + + stdout: StdioCollector { + onStreamFinished: root.time = this.text + } + } + + Process { + id: dateProc + command: ["date", "+%A %B %d %Y"] + running: true + + stdout: StdioCollector { + onStreamFinished: root.day = this.text + } + } + + Timer { + interval: 500 + running: true + repeat: true + onTriggered: timeProc.running = true, dateProc.running = true + } +} diff --git a/Components/Color.js b/Components/Color.js new file mode 100644 index 0000000..cd957fa --- /dev/null +++ b/Components/Color.js @@ -0,0 +1,26 @@ +let rosewater = "#f5e0dc"; +let flamingo = "#f2cdcd"; +let pink = "#f5c2e7"; +let mauve = "#cba6f7"; +let red = "#f38ba8"; +let maroon = "#eba0ac"; +let peach = "#fab387"; +let yellow = "#f9e2af"; +let green = "#a6e3a1"; +let teal = "#94e2d5"; +let sky = "#89dceb"; +let sapphire = "#74c7ec"; +let blue = "#89b4fa"; +let lavender = "#b4befe"; +let text = "#cdd6f4"; +let subtext1 = "#bac2de"; +let subtext0 = "#a6adc8"; +let overlay2 = "#9399b2"; +let overlay1 = "#7f849c"; +let overlay0 = "#6c7086"; +let surface2 = "#585b70"; +let surface1 = "#45475a"; +let surface0 = "#313244"; +let base = "#1e1e2e"; +let mantle = "#181825"; +let crust = "#11111b"; diff --git a/Components/Pill.qml b/Components/Pill.qml new file mode 100644 index 0000000..f28e1e2 --- /dev/null +++ b/Components/Pill.qml @@ -0,0 +1,139 @@ +import Quickshell +import Quickshell.Hyprland +import QtQuick +import QtQuick.Controls +import "Color.js" as Colors + +import "./Pill" + +Rectangle { + required property HyprlandMonitor monitor + id: container + state: "" + visible: true + + property bool shown: monitor !== null && monitor.focused + + Behavior on anchors.topMargin { + SmoothedAnimation { duration: 70; easing.type: Easing.OutBounce } + } + + opacity: shown ? 1 : 0 + + Behavior on opacity { + NumberAnimation {duration: 50} + } + + anchors { + top: parent.top + topMargin: shown ? 5 : -implicitHeight + horizontalCenter: parent.horizontalCenter + } + + MouseArea { + id: mouseArea + anchors.fill: parent + + onClicked: container.state == 'expanded' ? container.state = "" : container.state = 'expanded'; + + } + + implicitWidth: 130 + implicitHeight: 30 + + radius: 30 + + property real gradientMidpoint: 0.4 + + gradient: Gradient { + GradientStop { position: 0.0; color: Colors.surface0 } + GradientStop { position: container.gradientMidpoint; color: Colors.surface0 } + GradientStop { position: 1.0; color: Colors.overlay0 } + } + + + component SmoothAnim: SpringAnimation { + spring: 3 + mass: 0.5 + damping: 0.18 + } + + Behavior on implicitHeight { + SmoothAnim {} + } + + Behavior on implicitWidth { + SmoothAnim {} + } + + Behavior on gradientMidpoint { + NumberAnimation { + duration: 100 + } + } + + states: [ + State { + name: "" + StateChangeScript { + script: mainLoader.replace(defaultComponent) + } + }, + State { + name: "expanded" + StateChangeScript { + script: mainLoader.replace(expandedComponent) + } + PropertyChanges { container.gradientMidpoint: 0.7} + PropertyChanges { container.implicitHeight: 130} + PropertyChanges { container.implicitWidth: 300} + } + ] + + StackView { + id: mainLoader + anchors.fill: parent + + MouseArea { + id: mouseAreaStack + anchors.fill: parent + hoverEnabled: true + + // FIX part 1: Prevent internal StackView items from changing cursor grab + propagateComposedEvents: true + + onClicked: { + container.state == 'expanded' ? container.state = "" : container.state = 'expanded'; + print("clicked") + } + + onExited: { + container.state = "" + } + } + + enabled:false + + initialItem: defaultComponent + + // Custom animations for switching components + replaceEnter: Transition { + PropertyAnimation { property: "opacity"; from: 0; to: 1; duration: 100 } + PropertyAnimation { property: "scale"; from: 0.9; to: 1.0; duration: 100 } + } + replaceExit: Transition { + PropertyAnimation { property: "opacity"; from: 1; to: 0; duration: 100 } + } + } + + Component { + id: defaultComponent + Default {} + } + + Component { + id: expandedComponent + Expanded {} + } + +} diff --git a/Components/Pill/Default.qml b/Components/Pill/Default.qml new file mode 100644 index 0000000..7ffa2d9 --- /dev/null +++ b/Components/Pill/Default.qml @@ -0,0 +1,16 @@ +import Quickshell +import Quickshell.Hyprland +import QtQuick +import QtQuick.Controls +import "../Color.js" as Colors +import "../" + +Item { + Text { + font.family: "FiraMono Nerd Font" + anchors.centerIn: parent + font.pixelSize: 15 + color: Colors.text + text: Clock.time + } +} diff --git a/Components/Pill/Expanded.qml b/Components/Pill/Expanded.qml new file mode 100644 index 0000000..7450533 --- /dev/null +++ b/Components/Pill/Expanded.qml @@ -0,0 +1,29 @@ +import Quickshell +import Quickshell.Hyprland +import QtQuick +import QtQuick.Layouts +import "../Color.js" as Colors +import "../" + +Item { + anchors.fill: parent + + Column { + spacing: 5 + anchors.centerIn: parent + + Text { + font.family: "FiraMono Nerd Font" + font.pixelSize: 40 + color: Colors.text + anchors.horizontalCenter: parent.horizontalCenter + text: Clock.time + } + Text { + font.family: "FiraMono Nerd Font" + color: Colors.subtext0 + anchors.horizontalCenter: parent.horizontalCenter + text: Clock.day + } + } +} diff --git a/shell.qml b/shell.qml new file mode 100644 index 0000000..fc6f2ae --- /dev/null +++ b/shell.qml @@ -0,0 +1,10 @@ +import Quickshell +import Quickshell.Hyprland +import QtQuick +import "Components/Color.js" as Colors + +import "Components" + +Scope { + Bar {} +}