summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-28 00:21:53 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-28 00:21:53 +1000
commitcba440bcfced79eda2764e441c68239b6c594457 (patch)
tree15e72a41a47015a1440a7c6b54c51d8f182ebe24
parenthyprland: use qs hyprland service (diff)
downloadcaelestia-shell-cba440bcfced79eda2764e441c68239b6c594457.tar.gz
caelestia-shell-cba440bcfced79eda2764e441c68239b6c594457.tar.bz2
caelestia-shell-cba440bcfced79eda2764e441c68239b6c594457.zip
feat: anims + box padding
box provide padding and animate size and colour provide box and boxlayout for with/without layout provide clippingbox provide label for anim + rendertype configure QtQuick controls
-rw-r--r--config/Appearance.qml18
-rw-r--r--config/BarConfig.qml13
-rw-r--r--modules/bar/ActiveWindow.qml10
-rw-r--r--modules/bar/Bar.qml41
-rw-r--r--modules/bar/Clock.qml6
-rw-r--r--modules/bar/OsIcon.qml14
-rw-r--r--modules/bar/Workspaces.qml66
-rw-r--r--shell.qml7
-rw-r--r--widgets/Box.qml90
-rw-r--r--widgets/BoxLayout.qml97
-rw-r--r--widgets/ClippingBox.qml87
-rw-r--r--widgets/ClippingBoxLayout.qml98
-rw-r--r--widgets/Label.qml16
-rw-r--r--widgets/MaterialIcon.qml2
14 files changed, 526 insertions, 39 deletions
diff --git a/config/Appearance.qml b/config/Appearance.qml
index 8c441b1..263b653 100644
--- a/config/Appearance.qml
+++ b/config/Appearance.qml
@@ -54,6 +54,24 @@ Singleton {
}
}
+ readonly property QtObject anim: QtObject {
+ readonly property QtObject curves: QtObject {
+ readonly property list<real> emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1]
+ readonly property list<real> emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1]
+ readonly property list<real> emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1]
+ readonly property list<real> standard: [0.2, 0, 0, 1, 1, 1]
+ readonly property list<real> standardAccel: [0.3, 0, 1, 1, 1, 1]
+ readonly property list<real> standardDecel: [0, 0, 0, 1, 1, 1]
+ }
+
+ readonly property QtObject durations: QtObject {
+ readonly property int small: 200
+ readonly property int normal: 400
+ readonly property int large: 600
+ readonly property int extraLarge: 1000
+ }
+ }
+
readonly property QtObject colours: QtObject {
property color primary: "#85D2E7"
property color secondary: "#B2CBD3"
diff --git a/config/BarConfig.qml b/config/BarConfig.qml
new file mode 100644
index 0000000..a61e7cd
--- /dev/null
+++ b/config/BarConfig.qml
@@ -0,0 +1,13 @@
+pragma Singleton
+
+import Quickshell
+import QtQuick
+
+Singleton {
+ property bool vertical: false
+
+ readonly property QtObject workspaces: QtObject {
+ property int shown: 10
+ property string style: ""
+ }
+}
diff --git a/modules/bar/ActiveWindow.qml b/modules/bar/ActiveWindow.qml
index f65a83f..f351534 100644
--- a/modules/bar/ActiveWindow.qml
+++ b/modules/bar/ActiveWindow.qml
@@ -5,17 +5,19 @@ import "root:/config"
import QtQuick
import QtQuick.Layouts
-Box {
+ClippingBoxLayout {
id: root
- property color colour: Appearance.colours.pink
+ readonly property color colour: Appearance.colours.pink
+
+ animated: true
MaterialIcon {
Layout.alignment: Qt.AlignCenter
- text: Icons.getAppCategoryIcon(Hyprland.activeClient?.wmClass) ?? "desktop_windows"
+ text: Icons.getAppCategoryIcon(Hyprland.activeClient?.class) ?? "desktop_windows"
color: root.colour
}
- Text {
+ Label {
Layout.alignment: Qt.AlignCenter
text: Hyprland.activeClient?.title ?? "Desktop"
diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml
index 5aa18f7..6e18f50 100644
--- a/modules/bar/Bar.qml
+++ b/modules/bar/Bar.qml
@@ -2,6 +2,7 @@ import "root:/widgets"
import "root:/config"
import Quickshell
import Quickshell.Wayland
+import QtQuick
Variants {
model: Quickshell.screens
@@ -9,12 +10,13 @@ Variants {
WlrLayershell {
id: win
- property var modelData
- property bool vertical: false
+ required property ShellScreen modelData
+ readonly property bool vertical: BarConfig.vertical
screen: modelData
namespace: "caelestia-bar"
- color: Appearance.alpha(Appearance.colours.base, false)
+ // color: Appearance.alpha(Appearance.colours.base, false)
+ color: "transparent"
anchors {
top: true
@@ -23,25 +25,34 @@ Variants {
bottom: vertical
}
- width: contents.implicitWidth + (vertical ? Appearance.padding.normal * 2 : 0)
- height: contents.implicitHeight + (vertical ? 0 : Appearance.padding.smaller * 2)
+ width: contents.implicitWidth
+ height: contents.implicitHeight
Box {
id: contents
- vertical: win.vertical
- spacing: Appearance.spacing.larger
- x: Appearance.padding.normal
- y: vertical ? Appearance.padding.normal : Appearance.padding.smaller
+ padding: [Appearance.padding.normal, Appearance.padding.large, 0, Appearance.padding.large]
- OsIcon {}
-
- Clock {
+ BoxLayout {
vertical: win.vertical
- }
+ spacing: Appearance.spacing.larger
+ padding: [Appearance.padding.smaller, Appearance.padding.large]
+ color: Appearance.alpha(Appearance.colours.base, false)
+ radius: Appearance.rounding.small
- ActiveWindow {
- vertical: win.vertical
+ OsIcon {}
+
+ Clock {
+ vertical: win.vertical
+ }
+
+ ActiveWindow {
+ vertical: win.vertical
+ }
+
+ // Workspaces {
+ // vertical: win.vertical
+ // }
}
}
}
diff --git a/modules/bar/Clock.qml b/modules/bar/Clock.qml
index 4c743a6..2332f29 100644
--- a/modules/bar/Clock.qml
+++ b/modules/bar/Clock.qml
@@ -4,9 +4,9 @@ import "root:/config"
import QtQuick
import QtQuick.Layouts
-Box {
+BoxLayout {
id: root
- property color colour: Appearance.colours.peach
+ readonly property color colour: Appearance.colours.peach
MaterialIcon {
Layout.alignment: Qt.AlignCenter
@@ -14,7 +14,7 @@ Box {
color: root.colour
}
- Text {
+ Label {
Layout.alignment: Qt.AlignCenter
horizontalAlignment: Text.AlignJustify
diff --git a/modules/bar/OsIcon.qml b/modules/bar/OsIcon.qml
index 1737814..62ff5e6 100644
--- a/modules/bar/OsIcon.qml
+++ b/modules/bar/OsIcon.qml
@@ -5,11 +5,13 @@ import "root:/config"
import QtQuick
import QtQuick.Layouts
-Text {
- Layout.alignment: Qt.AlignCenter
+Box {
+ Label {
+ Layout.alignment: Qt.AlignCenter
- text: Icons.osIcon
- font.pointSize: Appearance.font.size.smaller
- font.family: Appearance.font.family.mono
- color: Appearance.colours.yellow
+ text: Icons.osIcon
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ color: Appearance.colours.yellow
+ }
}
diff --git a/modules/bar/Workspaces.qml b/modules/bar/Workspaces.qml
new file mode 100644
index 0000000..73995c8
--- /dev/null
+++ b/modules/bar/Workspaces.qml
@@ -0,0 +1,66 @@
+pragma ComponentBehavior: Bound
+
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import Quickshell
+import QtQuick
+import QtQuick.Layouts
+
+Item {
+ property alias vertical: root.vertical
+
+ implicitWidth: root.implicitWidth
+ implicitHeight: root.implicitHeight
+
+ Box {
+ id: root
+
+ readonly property color colour: Appearance.colours.mauve
+
+ // homogenous: true
+
+ Repeater {
+ model: BarConfig.workspaces.shown
+
+ Label {
+ required property int index
+
+ text: (index + 1).toString()
+ color: root.colour
+ }
+ }
+
+ // Text {
+ // Layout.alignment: Qt.AlignCenter
+ // horizontalAlignment: Text.AlignJustify
+
+ // 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
+ // }
+ }
+
+ Rectangle {
+ x: (root.childrenRect.width / BarConfig.workspaces.shown) * ((Hyprland.activeWorkspace?.id ?? 1) - 1)
+ y: 0
+ width: root.childrenRect.width / BarConfig.workspaces.shown
+ height: root.childrenRect.height
+ color: "red"
+ radius: 1000
+
+ // layer.enabled: true
+ // layer.effect: ShaderEffect {
+ // readonly property Item source: root
+ // fragmentShader: `
+ // varying highp vec2 qt_TexCoord0;
+ // uniform highp vec4 color;
+ // uniform sampler2D source;
+ // void main() {
+ // gl_FragColor = color * (1.0 - texture2D(source, qt_TexCoord0).w);
+ // }
+ // `
+ // }
+ }
+}
diff --git a/shell.qml b/shell.qml
index 9f91e59..d22e78f 100644
--- a/shell.qml
+++ b/shell.qml
@@ -1,6 +1,13 @@
import "modules/bar"
+import "config"
import Quickshell
+import QtQuick.Controls.Material
ShellRoot {
+ Material.accent: Appearance.colours.primary
+ Material.primary: Appearance.colours.secondary
+ Material.foreground: Appearance.colours.text
+ Material.background: Appearance.colours.base
+
Bar {}
}
diff --git a/widgets/Box.qml b/widgets/Box.qml
index c0d7f06..536469e 100644
--- a/widgets/Box.qml
+++ b/widgets/Box.qml
@@ -1,16 +1,86 @@
import "root:/config"
-import QtQuick.Layouts
+import QtQuick
+
+Rectangle {
+ id: root
-GridLayout {
property bool vertical: false
- property real spacing: Appearance.spacing.small
property bool homogenous: false
+ property bool animated: false
+ property int spacing: Appearance.spacing.small
+ property var padding: 0
+
+ readonly property int paddingTop: getRealPadding().top
+ readonly property int paddingRight: getRealPadding().right
+ readonly property int paddingBottom: getRealPadding().bottom
+ readonly property int paddingLeft: getRealPadding().left
+ readonly property int paddingX: getRealPadding().x
+ readonly property int paddingY: getRealPadding().y
+
+ color: "transparent"
+
+ implicitWidth: childrenRect.width + paddingX
+ implicitHeight: childrenRect.height + paddingY
+
+ function getRealPadding() {
+ const pad = {};
+
+ if (Array.isArray(padding)) {
+ if (padding.length === 2) {
+ pad.top = pad.bottom = padding[0];
+ pad.left = pad.right = padding[1];
+ } else if (padding.length === 3) {
+ pad.top = padding[0];
+ pad.left = pad.right = padding[1];
+ pad.bottom = padding[2];
+ } else if (padding.length === 4) {
+ pad.top = padding[0];
+ pad.right = padding[1];
+ pad.bottom = padding[2];
+ pad.left = padding[3];
+ }
+ } else {
+ pad.top = pad.bottom = pad.left = pad.right = padding;
+ }
+
+ pad.x = pad.left + pad.right;
+ pad.y = pad.top + pad.bottom;
+
+ return pad;
+ }
+
+ onChildrenChanged: {
+ for (const child of children) {
+ child.x = Qt.binding(() => paddingLeft);
+ child.y = Qt.binding(() => paddingTop);
+ }
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+
+ Behavior on implicitWidth {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+
+ Behavior on implicitHeight {
+ enabled: root.animated
- flow: vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
- uniformCellWidths: homogenous && vertical
- uniformCellHeights: homogenous && !vertical
- rows: vertical ? -1 : 1
- columns: vertical ? 1 : -1
- rowSpacing: spacing
- columnSpacing: spacing
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
}
diff --git a/widgets/BoxLayout.qml b/widgets/BoxLayout.qml
new file mode 100644
index 0000000..12aa4f7
--- /dev/null
+++ b/widgets/BoxLayout.qml
@@ -0,0 +1,97 @@
+import "root:/config"
+import QtQuick
+import QtQuick.Layouts
+
+Rectangle {
+ id: root
+
+ property bool vertical: false
+ property bool homogenous: false
+ property bool animated: false
+ property int spacing: Appearance.spacing.small
+ property var padding: 0
+
+ readonly property int paddingTop: getRealPadding().top
+ readonly property int paddingRight: getRealPadding().right
+ readonly property int paddingBottom: getRealPadding().bottom
+ readonly property int paddingLeft: getRealPadding().left
+ readonly property int paddingX: getRealPadding().x
+ readonly property int paddingY: getRealPadding().y
+
+ color: "transparent"
+
+ implicitWidth: layout.implicitWidth + paddingX
+ implicitHeight: layout.implicitHeight + paddingY
+
+ function getRealPadding() {
+ const pad = {};
+
+ if (Array.isArray(padding)) {
+ if (padding.length === 2) {
+ pad.top = pad.bottom = padding[0];
+ pad.left = pad.right = padding[1];
+ } else if (padding.length === 3) {
+ pad.top = padding[0];
+ pad.left = pad.right = padding[1];
+ pad.bottom = padding[2];
+ } else if (padding.length === 4) {
+ pad.top = padding[0];
+ pad.right = padding[1];
+ pad.bottom = padding[2];
+ pad.left = padding[3];
+ }
+ } else {
+ pad.top = pad.bottom = pad.left = pad.right = padding;
+ }
+
+ pad.x = pad.left + pad.right;
+ pad.y = pad.top + pad.bottom;
+
+ return pad;
+ }
+
+ default property alias children: layout.children
+
+ GridLayout {
+ id: layout
+
+ x: root.paddingLeft
+ y: root.paddingTop
+
+ flow: root.vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
+ uniformCellWidths: root.homogenous || root.vertical
+ uniformCellHeights: root.homogenous || !root.vertical
+ rows: root.vertical ? -1 : 1
+ columns: root.vertical ? 1 : -1
+ rowSpacing: root.spacing
+ columnSpacing: root.spacing
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+
+ Behavior on implicitWidth {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+
+ Behavior on implicitHeight {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+}
diff --git a/widgets/ClippingBox.qml b/widgets/ClippingBox.qml
new file mode 100644
index 0000000..1ced873
--- /dev/null
+++ b/widgets/ClippingBox.qml
@@ -0,0 +1,87 @@
+import "root:/config"
+import Quickshell.Widgets
+import QtQuick
+
+ClippingRectangle {
+ id: root
+
+ property bool vertical: false
+ property bool homogenous: false
+ property bool animated: false
+ property int spacing: Appearance.spacing.small
+ property var padding: 0
+
+ readonly property int paddingTop: getRealPadding().top
+ readonly property int paddingRight: getRealPadding().right
+ readonly property int paddingBottom: getRealPadding().bottom
+ readonly property int paddingLeft: getRealPadding().left
+ readonly property int paddingX: getRealPadding().x
+ readonly property int paddingY: getRealPadding().y
+
+ color: "transparent"
+
+ implicitWidth: childrenRect.width + paddingX
+ implicitHeight: childrenRect.height + paddingY
+
+ function getRealPadding() {
+ const pad = {};
+
+ if (Array.isArray(padding)) {
+ if (padding.length === 2) {
+ pad.top = pad.bottom = padding[0];
+ pad.left = pad.right = padding[1];
+ } else if (padding.length === 3) {
+ pad.top = padding[0];
+ pad.left = pad.right = padding[1];
+ pad.bottom = padding[2];
+ } else if (padding.length === 4) {
+ pad.top = padding[0];
+ pad.right = padding[1];
+ pad.bottom = padding[2];
+ pad.left = padding[3];
+ }
+ } else {
+ pad.top = pad.bottom = pad.left = pad.right = padding;
+ }
+
+ pad.x = pad.left + pad.right;
+ pad.y = pad.top + pad.bottom;
+
+ return pad;
+ }
+
+ onChildrenChanged: {
+ for (const child of children) {
+ child.x = Qt.binding(() => paddingLeft);
+ child.y = Qt.binding(() => paddingTop);
+ }
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+
+ Behavior on implicitWidth {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+
+ Behavior on implicitHeight {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+}
diff --git a/widgets/ClippingBoxLayout.qml b/widgets/ClippingBoxLayout.qml
new file mode 100644
index 0000000..2b22c8c
--- /dev/null
+++ b/widgets/ClippingBoxLayout.qml
@@ -0,0 +1,98 @@
+import "root:/config"
+import Quickshell.Widgets
+import QtQuick
+import QtQuick.Layouts
+
+ClippingRectangle {
+ id: root
+
+ property bool vertical: false
+ property bool homogenous: false
+ property bool animated: false
+ property int spacing: Appearance.spacing.small
+ property var padding: 0
+
+ readonly property int paddingTop: getRealPadding().top
+ readonly property int paddingRight: getRealPadding().right
+ readonly property int paddingBottom: getRealPadding().bottom
+ readonly property int paddingLeft: getRealPadding().left
+ readonly property int paddingX: getRealPadding().x
+ readonly property int paddingY: getRealPadding().y
+
+ color: "transparent"
+
+ implicitWidth: layout.implicitWidth + paddingX
+ implicitHeight: layout.implicitHeight + paddingY
+
+ function getRealPadding() {
+ const pad = {};
+
+ if (Array.isArray(padding)) {
+ if (padding.length === 2) {
+ pad.top = pad.bottom = padding[0];
+ pad.left = pad.right = padding[1];
+ } else if (padding.length === 3) {
+ pad.top = padding[0];
+ pad.left = pad.right = padding[1];
+ pad.bottom = padding[2];
+ } else if (padding.length === 4) {
+ pad.top = padding[0];
+ pad.right = padding[1];
+ pad.bottom = padding[2];
+ pad.left = padding[3];
+ }
+ } else {
+ pad.top = pad.bottom = pad.left = pad.right = padding;
+ }
+
+ pad.x = pad.left + pad.right;
+ pad.y = pad.top + pad.bottom;
+
+ return pad;
+ }
+
+ default property alias children: layout.children
+
+ GridLayout {
+ id: layout
+
+ x: root.paddingLeft
+ y: root.paddingTop
+
+ flow: root.vertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
+ uniformCellWidths: root.homogenous || root.vertical
+ uniformCellHeights: root.homogenous || !root.vertical
+ rows: root.vertical ? -1 : 1
+ columns: root.vertical ? 1 : -1
+ rowSpacing: root.spacing
+ columnSpacing: root.spacing
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+
+ Behavior on implicitWidth {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+
+ Behavior on implicitHeight {
+ enabled: root.animated
+
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
+ }
+ }
+}
diff --git a/widgets/Label.qml b/widgets/Label.qml
new file mode 100644
index 0000000..e1e22ba
--- /dev/null
+++ b/widgets/Label.qml
@@ -0,0 +1,16 @@
+import "root:/config"
+import QtQuick
+
+Text {
+ id: root
+
+ renderType: Text.NativeRendering
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+}
diff --git a/widgets/MaterialIcon.qml b/widgets/MaterialIcon.qml
index 0115abf..55e6b99 100644
--- a/widgets/MaterialIcon.qml
+++ b/widgets/MaterialIcon.qml
@@ -1,7 +1,7 @@
import "root:/config"
import QtQuick
-Text {
+Label {
font.family: Appearance.font.family.material
font.pointSize: Appearance.font.size.larger
}