pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell.Bluetooth import Caelestia.Components import Caelestia.Config import qs.components import qs.components.controls import qs.services import qs.modules.nexus import qs.modules.bar.popouts as BarPopouts StyledRect { id: root required property DrawerVisibilities visibilities required property BarPopouts.Wrapper popouts readonly property var quickToggles: { const seenIds = new Set(); return Config.utilities.quickToggles.filter(item => { if (!(item.enabled ?? true)) return false; if (seenIds.has(item.id)) { return false; } if (item.id === "vpn") { return GlobalConfig.utilities.vpn.provider.some(p => typeof p === "object" ? (p.enabled === true) : false); } seenIds.add(item.id); return true; }); } readonly property int splitIndex: Math.ceil(quickToggles.length / 2) readonly property bool needExtraRow: quickToggles.length > 6 Layout.fillWidth: true implicitHeight: layout.implicitHeight + Tokens.padding.extraLargeIncreased radius: Tokens.rounding.large color: Colours.tPalette.m3surfaceContainer ColumnLayout { id: layout anchors.fill: parent anchors.margins: Tokens.padding.large spacing: Tokens.spacing.medium StyledText { text: qsTr("Quick Toggles") font: Tokens.font.body.medium } QuickToggleRow { model: root.needExtraRow ? root.quickToggles.slice(0, root.splitIndex) : root.quickToggles } QuickToggleRow { visible: root.needExtraRow model: root.needExtraRow ? root.quickToggles.slice(root.splitIndex) : [] } } component QuickToggleRow: ButtonRow { property alias model: repeater.model Layout.fillWidth: true spacing: Tokens.spacing.small Repeater { id: repeater delegate: DelegateChooser { role: "id" DelegateChoice { roleValue: "wifi" delegate: Toggle { icon: "wifi" checked: Nmcli.wifiEnabled onClicked: Nmcli.toggleWifi() } } DelegateChoice { roleValue: "bluetooth" delegate: Toggle { icon: "bluetooth" checked: Bluetooth.defaultAdapter?.enabled ?? false // qmllint disable unresolved-type onClicked: { const adapter = Bluetooth.defaultAdapter; // qmllint disable unresolved-type if (adapter) adapter.enabled = !adapter.enabled; } } } DelegateChoice { roleValue: "mic" delegate: Toggle { icon: "mic" checked: !Audio.sourceMuted onClicked: { const audio = Audio.source?.audio; if (audio) audio.muted = !audio.muted; } } } DelegateChoice { roleValue: "settings" delegate: Toggle { icon: "settings" inactiveOnColour: Colours.palette.m3onSurfaceVariant isToggle: false onClicked: { root.visibilities.utilities = false; WindowFactory.create(); } } } DelegateChoice { roleValue: "gameMode" delegate: Toggle { icon: "gamepad" checked: GameMode.enabled onClicked: GameMode.enabled = !GameMode.enabled } } DelegateChoice { roleValue: "dnd" delegate: Toggle { icon: "notifications_off" checked: Notifs.dnd onClicked: Notifs.dnd = !Notifs.dnd } } DelegateChoice { roleValue: "vpn" delegate: Toggle { icon: "vpn_key" checked: VPN.connected && VPN.status.state !== "needs-auth" && VPN.status.state !== "error" enabled: !VPN.connecting isToggle: VPN.status.state !== "needs-auth" && VPN.status.state !== "error" inactiveOnColour: Colours.palette.m3onSurfaceVariant onClicked: VPN.toggle() } } } } } component Toggle: IconButton { inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2) fillWidth: true isToggle: true isRound: true shapeMorph: true } }