diff options
Diffstat (limited to 'modules/bar/components/workspaces')
| -rw-r--r-- | modules/bar/components/workspaces/OccupiedBg.qml | 48 | ||||
| -rw-r--r-- | modules/bar/components/workspaces/Workspace.qml | 18 | ||||
| -rw-r--r-- | modules/bar/components/workspaces/Workspaces.qml | 138 |
3 files changed, 204 insertions, 0 deletions
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 + } +} |