summaryrefslogtreecommitdiff
path: root/modules/bar/components
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-29 09:38:23 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-29 09:38:23 +1000
commit46e1127b66a435dc4ba4b8e3ce57715da24b7743 (patch)
treef0451a122d6234240e5688110f1b03133423352f /modules/bar/components
parentrefactor: appearance fix typing (diff)
downloadcaelestia-shell-46e1127b66a435dc4ba4b8e3ce57715da24b7743.tar.gz
caelestia-shell-46e1127b66a435dc4ba4b8e3ce57715da24b7743.tar.bz2
caelestia-shell-46e1127b66a435dc4ba4b8e3ce57715da24b7743.zip
refactor: move bar components into folder
Diffstat (limited to 'modules/bar/components')
-rw-r--r--modules/bar/components/ActiveWindow.qml34
-rw-r--r--modules/bar/components/Clock.qml30
-rw-r--r--modules/bar/components/OsIcon.qml19
-rw-r--r--modules/bar/components/workspaces/OccupiedBg.qml48
-rw-r--r--modules/bar/components/workspaces/Workspace.qml18
-rw-r--r--modules/bar/components/workspaces/Workspaces.qml138
6 files changed, 287 insertions, 0 deletions
diff --git a/modules/bar/components/ActiveWindow.qml b/modules/bar/components/ActiveWindow.qml
new file mode 100644
index 0000000..596c368
--- /dev/null
+++ b/modules/bar/components/ActiveWindow.qml
@@ -0,0 +1,34 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/utils"
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+
+BoxLayout {
+ id: root
+
+ readonly property color colour: Appearance.colours.pink
+
+ padding: [Appearance.padding.smaller, 0]
+ animated: true
+ clip: true
+
+ MaterialIcon {
+ text: Icons.getAppCategoryIcon(Hyprland.activeClient?.class) ?? "desktop_windows"
+ color: root.colour
+
+ Layout.alignment: Layout.Center
+ }
+
+ Label {
+ text: Hyprland.activeClient?.title ?? "Desktop"
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ color: root.colour
+ rotation: root.vertical ? 90 : 0
+
+ Layout.alignment: Layout.Center
+ Layout.maximumWidth: root.vertical ? this.implicitHeight : this.implicitWidth
+ }
+}
diff --git a/modules/bar/components/Clock.qml b/modules/bar/components/Clock.qml
new file mode 100644
index 0000000..a34cc2c
--- /dev/null
+++ b/modules/bar/components/Clock.qml
@@ -0,0 +1,30 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+
+BoxLayout {
+ id: root
+
+ readonly property color colour: Appearance.colours.peach
+
+ padding: [Appearance.padding.smaller, 0]
+
+ MaterialIcon {
+ text: "calendar_month"
+ color: root.colour
+
+ Layout.alignment: Layout.Center
+ }
+
+ Label {
+ horizontalAlignment: Label.AlignHCenter
+ text: root.vertical ? Time.format("hh\nmm") : Time.format("dd/MM/yy hh:mm")
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ color: root.colour
+
+ Layout.alignment: Layout.Center
+ }
+}
diff --git a/modules/bar/components/OsIcon.qml b/modules/bar/components/OsIcon.qml
new file mode 100644
index 0000000..2b99de3
--- /dev/null
+++ b/modules/bar/components/OsIcon.qml
@@ -0,0 +1,19 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/utils"
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+
+Box {
+ padding: [Appearance.padding.smaller, 0]
+
+ Label {
+ text: Icons.osIcon
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ color: Appearance.colours.yellow
+
+ Layout.alignment: Layout.Center
+ }
+}
diff --git a/modules/bar/components/workspaces/OccupiedBg.qml b/modules/bar/components/workspaces/OccupiedBg.qml
new file mode 100644
index 0000000..97a27a0
--- /dev/null
+++ b/modules/bar/components/workspaces/OccupiedBg.qml
@@ -0,0 +1,48 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+import Qt5Compat.GraphicalEffects
+
+BoxLayout {
+ id: root
+
+ required property bool vertical
+ required property list<Label> workspaces
+ required property var occupied
+ required property BoxLayout layout
+
+ anchors.centerIn: parent
+ spacing: 0
+ z: -1
+
+ Repeater {
+ model: BarConfig.workspaces.shown
+
+ Rectangle {
+ required property int index
+ readonly property int roundLeft: index === 0 || !root.occupied[index] ? Appearance.rounding.full : 0
+ readonly property int roundRight: index === BarConfig.workspaces.shown - 1 || !root.occupied[index + 2] ? Appearance.rounding.full : 0
+
+ color: Appearance.alpha(Appearance.colours.surface2, true)
+ opacity: root.occupied[index + 1] ? 1 : 0
+ topLeftRadius: roundLeft
+ bottomLeftRadius: roundLeft
+ topRightRadius: roundRight
+ bottomRightRadius: roundRight
+
+ // Ugh stupid size errors on reload
+ Layout.preferredWidth: root.vertical ? layout.width : root.workspaces[index]?.width ?? 1
+ Layout.preferredHeight: root.vertical ? root.workspaces[index]?.height ?? 1 : layout.height
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+ }
+ }
+}
diff --git a/modules/bar/components/workspaces/Workspace.qml b/modules/bar/components/workspaces/Workspace.qml
new file mode 100644
index 0000000..4f53e73
--- /dev/null
+++ b/modules/bar/components/workspaces/Workspace.qml
@@ -0,0 +1,18 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import QtQuick.Layouts
+
+Label {
+ required property int index
+ required property BoxLayout layout
+ required property var occupied
+ readonly property bool isWorkspace: true
+
+ text: index + 1
+ color: BarConfig.workspaces.occupiedBg || occupied[index + 1] ? Appearance.colours.text : Appearance.colours.subtext0
+ horizontalAlignment: Label.AlignHCenter
+
+ Layout.preferredWidth: layout.homogenous && !layout.vertical ? layout.height : -1
+ Layout.preferredHeight: layout.homogenous && layout.vertical ? layout.width : -1
+}
diff --git a/modules/bar/components/workspaces/Workspaces.qml b/modules/bar/components/workspaces/Workspaces.qml
new file mode 100644
index 0000000..62f22d7
--- /dev/null
+++ b/modules/bar/components/workspaces/Workspaces.qml
@@ -0,0 +1,138 @@
+pragma ComponentBehavior: Bound
+
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+import Qt5Compat.GraphicalEffects
+
+Item {
+ id: root
+
+ property alias vertical: layout.vertical
+ readonly property color colour: Appearance.colours.mauve
+ property int shown: 10
+ property bool occupiedBg: false
+ property bool showWindows: false
+
+ readonly property list<Label> workspaces: layout.children.filter(c => c.isWorkspace)
+ readonly property var occupied: Hyprland.workspaces.values.reduce((acc, curr) => {
+ acc[curr.id] = curr.lastIpcObject.windows > 0;
+ return acc;
+ }, {})
+
+ implicitWidth: layout.implicitWidth
+ implicitHeight: layout.implicitHeight
+
+ BoxLayout {
+ id: layout
+
+ padding: vertical ? [0, Appearance.padding.smaller / 2] : [Appearance.padding.smaller / 2, 0]
+ anchors.centerIn: parent
+ homogenous: true
+ spacing: 0
+
+ Repeater {
+ model: BarConfig.workspaces.shown
+
+ Workspace {
+ layout: layout
+ occupied: root.occupied
+ }
+ }
+ }
+
+ OccupiedBg {
+ opacity: BarConfig.workspaces.occupiedBg ? 1 : 0
+ vertical: root.vertical
+ workspaces: root.workspaces
+ occupied: root.occupied
+ layout: layout
+
+ Behavior on opacity {
+ Anim {
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ onPressed: event => Hyprland.dispatch(`workspace ${layout.childAt(event.x, event.y).index + 1}`)
+ onWheel: event => {
+ if (event.angleDelta.y < 0)
+ Hyprland.dispatch(`workspace r+1`);
+ else if (event.angleDelta.y > 0 && Hyprland.activeWorkspace.id > 1)
+ Hyprland.dispatch(`workspace r-1`);
+ }
+ }
+
+ Rectangle {
+ id: active
+
+ property int currentIdx: 0
+ property int lastIdx: 0
+ property real leading: root.workspaces[currentIdx][root.vertical ? "y" : "x"]
+ property real trailing: root.workspaces[lastIdx][root.vertical ? "y" : "x"]
+ property real currentSize: root.workspaces[currentIdx][root.vertical ? "height" : "width"]
+ property real size: Math.abs(leading - trailing) + currentSize
+ property real offset: Math.min(leading, trailing)
+
+ clip: true
+ x: root.vertical ? 0 : offset
+ y: root.vertical ? offset : 0
+ width: root.vertical ? layout.width : size
+ height: root.vertical ? size : layout.height
+ color: Appearance.colours.mauve
+ radius: Appearance.rounding.full
+
+ Connections {
+ target: Hyprland
+
+ function onActiveWorkspaceChanged() {
+ active.currentIdx = (Hyprland.activeWorkspace?.id ?? 1) - 1;
+ active.lastIdx = active.currentIdx;
+ }
+ }
+
+ Rectangle {
+ id: base
+
+ visible: false
+ anchors.fill: parent
+ color: Appearance.colours.base
+ }
+
+ OpacityMask {
+ source: base
+ maskSource: layout
+
+ x: root.vertical ? 0 : -parent.offset
+ y: root.vertical ? -parent.offset : 0
+ width: root.width
+ height: root.height
+ }
+
+ Behavior on leading {
+ Anim {}
+ }
+
+ Behavior on trailing {
+ Anim {
+ duration: Appearance.anim.durations.normal * 2
+ }
+ }
+
+ Behavior on currentSize {
+ Anim {}
+ }
+ }
+
+ component Anim: NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+}