diff options
| -rw-r--r-- | bar/Workspace.qml | 82 | ||||
| -rw-r--r-- | components/ISpringAnimation.qml | 7 | ||||
| -rw-r--r-- | config/Bar.qml | 2 | ||||
| -rw-r--r-- | config/General.qml | 3 |
4 files changed, 74 insertions, 20 deletions
diff --git a/bar/Workspace.qml b/bar/Workspace.qml index c0f5b25..5fb5faf 100644 --- a/bar/Workspace.qml +++ b/bar/Workspace.qml @@ -1,5 +1,5 @@ -import QtQuick.Layouts import QtQuick +import QtQuick.Layouts import Quickshell import Quickshell.Hyprland import Quickshell.Wayland @@ -9,11 +9,16 @@ import qs.components Item { id: root - // required property ShellScreen screen // multi monitor - property var ws: Hyprland.workspaces + implicitWidth: layout.implicitWidth - // readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen) // multi monitor - // dont work no more for some reason + property var ws: Hyprland.workspaces + property int activeIndex: -1 + property bool activeOccupied: false + property real activeRectX: { + if (activeIndex < 0) + return 0; + return layout.x + activeIndex * Bar.workspaceIconSize + activeIndex * Bar.workspaceSpacing; + } function getWorkspaceStats(index) { const w = ws.values.find(i => i.id === index + 1); @@ -24,49 +29,86 @@ Item { }; } - implicitWidth: layout.implicitWidth + Rectangle { + id: activeRect + x: activeRectX + anchors.verticalCenter: layout.verticalCenter + implicitWidth: Bar.workspaceActiveIconSize + implicitHeight: Bar.workspaceIconSize - Bar.workspaceHorizontalSpacing + radius: Bar.workspaceRounding + color: root.activeOccupied ? Colors.alt : Colors.foreground + opacity: root.activeOccupied ? Bar.workspaceActiveOpacity : Bar.workspaceEmptyOpacity / 3 + Behavior on x { + ISpringAnimation {} + } + Behavior on color { + ColorAnimation { + duration: Bar.workspaceAnimationDuration + easing.type: Easing.InOutQuad + } + } + Behavior on opacity { + NumberAnimation { + duration: Bar.workspaceAnimationDuration + easing.type: Easing.InOutQuad + } + } + } RowLayout { id: layout - implicitWidth: childrenRect.width anchors.verticalCenter: parent.verticalCenter - + implicitWidth: repeater.width spacing: Bar.workspaceSpacing Repeater { + id: repeater model: Bar.workspaces Rectangle { - id: workspaceRect property var st: getWorkspaceStats(index) + property bool active: st?.isActive || false - implicitWidth: !st.isActive ? Bar.workspaceIconSize : Bar.workspaceActiveIconSize + implicitWidth: active ? Bar.workspaceActiveIconSize : Bar.workspaceIconSize implicitHeight: Bar.workspaceIconSize - Bar.workspaceHorizontalSpacing radius: Bar.workspaceRounding + color: st.isOccupied ? Colors.alt : Colors.foreground + opacity: active && st.isOccupied ? Bar.workspaceActiveOpacity : st.isOccupied ? Bar.workspaceOpacity : Bar.workspaceEmptyOpacity + Icon { anchors.centerIn: parent - text: !st.isUrgent ? Icons.ws[index + 1] : Icons.ws['urgent'] // TODO: urgent = red - font.pixelSize: Bar.workspaceIconSize / 2 - color: Colors.foreground // TODO make IText w/ ts default color - opacity: !st.isOccupied ? 0 : 1 // less contrast - // opacity: isActive(index) ? Bar.workspaceActiveOpacity : isOccupied(index) ? Bar.workspaceOpacity : Bar.workspaceEmptyOpacity + text: !st.isUrgent ? Icons.ws[index + 1] : Icons.ws['urgent'] + font.pixelSize: !active ? Bar.workspaceIconSize / 2 : Bar.workspaceActiveIconSize / 2.5 + color: Colors.foreground + opacity: !st.isOccupied ? 0 : 1 + Behavior on font.pixelSize { + ISpringAnimation {} + } } - color: st.isOccupied ? Colors.alt : Colors.foreground - opacity: st.isActive && st.isOccupied ? Bar.workspaceActiveOpacity : st.isOccupied ? Bar.workspaceOpacity : Bar.workspaceEmptyOpacity - Behavior on opacity { NumberAnimation { - duration: 200 + duration: Bar.workspaceAnimationDuration easing.type: Easing.InOutQuad } } Behavior on implicitWidth { NumberAnimation { - duration: 200 + duration: Bar.workspaceAnimationDuration + easing.type: Easing.InOutQuad + } + } + Behavior on color { + ColorAnimation { + duration: Bar.workspaceAnimationDuration easing.type: Easing.InOutQuad } } + + onActiveChanged: if (active) { + root.activeIndex = index; + root.activeOccupied = st.isOccupied; + } } } } diff --git a/components/ISpringAnimation.qml b/components/ISpringAnimation.qml new file mode 100644 index 0000000..099cab4 --- /dev/null +++ b/components/ISpringAnimation.qml @@ -0,0 +1,7 @@ +import QtQuick +import qs.config + +SpringAnimation { + spring: General.springAnimationSpring + damping: General.springAnimationDamping +} diff --git a/config/Bar.qml b/config/Bar.qml index 99e1760..198ae4f 100644 --- a/config/Bar.qml +++ b/config/Bar.qml @@ -26,6 +26,8 @@ Singleton { readonly property double workspaceOpacity: 0.8 readonly property int workspaceActiveOpacity: 1 readonly property double workspaceEmptyOpacity: 0.2 + // workspaceAnimationEasing using Hyprland's actual ws animation easing + readonly property int workspaceAnimationDuration: 200 readonly property int appIconSize: 25 diff --git a/config/General.qml b/config/General.qml index a42894b..d9993c6 100644 --- a/config/General.qml +++ b/config/General.qml @@ -16,4 +16,7 @@ Singleton { readonly property int rectMargin: Style.spacing.small readonly property int fontSize: Style.font.size.larger + + readonly property real springAnimationSpring: 8 + readonly property real springAnimationDamping: 0.4 } |
