pragma ComponentBehavior: Bound import Quickshell import QtQuick import QtQuick.Layouts import ZShell.Config import qs.Helpers import qs.Modules.Bar.Components.StatusIcons import qs.Modules.Bar.Components.Common import qs.Components import qs.Services WidgetBase { id: root readonly property int firstPresent: { const values = model.values; for (let i = 0; i < values.length; i++) if (!collapsed(values[i])) return i; return -1; } // Index of the first/last entry that isn't collapsed, for edge margin gating readonly property alias items: grid readonly property int lastPresent: { const values = model.values; for (let i = values.length - 1; i >= 0; i--) if (!collapsed(values[i])) return i; return -1; } readonly property real size: horizontal ? grid.implicitWidth + grid.anchors.leftMargin + grid.anchors.rightMargin : grid.implicitHeight + grid.anchors.bottomMargin + grid.anchors.topMargin readonly property int spacing: Tokens.spacing.medium / 2 // Entries that can shrink to nothing, spacing included function collapsed(entry: var): bool { if (entry.id === "lockStatus") return !Hypr.capsLock && !Hypr.numLock; return false; } bottomLeftRadius: horizontal ? Tokens.rounding.small / 2 : Tokens.rounding.full color: Colors.tPalette.m3surfaceContainer implicitHeight: horizontal ? baseSize : size implicitWidth: horizontal ? size : baseSize radius: Tokens.rounding.full topLeftRadius: Tokens.rounding.small / 2 topRightRadius: horizontal ? Tokens.rounding.full : Tokens.rounding.small / 2 Behavior on implicitHeight { enabled: !root.horizontal Anim { } } Behavior on implicitWidth { enabled: root.horizontal Anim { } } GridLayout { id: grid anchors.bottomMargin: root.horizontal ? 0 : Tokens.padding.medium anchors.fill: parent anchors.leftMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.rightMargin: root.horizontal ? Tokens.padding.extraSmall : 0 anchors.topMargin: root.horizontal ? 0 : Tokens.padding.extraSmall columns: root.horizontal ? -1 : 1 Repeater { model: ScriptModel { id: model values: Config.bar.tray.statusIcons.values.filter(e => e.enabled) } DelegateChooser { role: "id" DelegateChoice { roleValue: "audio" delegate: EntryWrapper { name: "audio" AudioWidget { horizontal: root.horizontal } } } DelegateChoice { roleValue: "microphone" delegate: EntryWrapper { name: "audio" MicWidget { horizontal: root.horizontal } } } DelegateChoice { roleValue: "power" delegate: EntryWrapper { name: "upower" UPowerWidget { } } } } } } component EntryWrapper: Item { required property int index default property Item item property real leftGap: present && index !== root.lastPresent ? margin : 0 property int margin: root.spacing / 2 required property var modelData property string name: modelData.id.toLowerCase() readonly property bool present: !root.collapsed(modelData) property real rightGap: present && index !== root.firstPresent ? margin : 0 Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: root.horizontal ? 0 : Math.round(rightGap) Layout.leftMargin: root.horizontal ? Math.round(leftGap) : 0 Layout.rightMargin: root.horizontal ? Math.round(rightGap) : 0 Layout.topMargin: root.horizontal ? 0 : Math.round(leftGap) children: item implicitHeight: item?.implicitHeight ?? 0 implicitWidth: item?.implicitWidth ?? 0 Behavior on leftGap { Anim { type: Anim.SlowEffects } } Behavior on rightGap { Anim { type: Anim.SlowEffects } } } }