171 lines
5.8 KiB
QML
171 lines
5.8 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import QtQuick.Layouts
|
|
import Quickshell.Bluetooth
|
|
import qs.components
|
|
import qs.components.controls
|
|
import qs.services
|
|
import Caelestia.Config
|
|
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)
|
|
return false;
|
|
|
|
if (seenIds.has(item.id)) {
|
|
return false;
|
|
}
|
|
|
|
if (item.id === "vpn") {
|
|
return Config.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.large * 2
|
|
|
|
radius: Tokens.rounding.normal
|
|
color: Colours.tPalette.m3surfaceContainer
|
|
|
|
ColumnLayout {
|
|
id: layout
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: Tokens.padding.large
|
|
spacing: Tokens.spacing.normal
|
|
|
|
StyledText {
|
|
text: qsTr("Quick Toggles")
|
|
font.pointSize: Tokens.font.size.normal
|
|
}
|
|
|
|
QuickToggleRow {
|
|
rowModel: root.needExtraRow ? root.quickToggles.slice(0, root.splitIndex) : root.quickToggles
|
|
}
|
|
|
|
QuickToggleRow {
|
|
visible: root.needExtraRow
|
|
rowModel: root.needExtraRow ? root.quickToggles.slice(root.splitIndex) : []
|
|
}
|
|
}
|
|
|
|
component QuickToggleRow: RowLayout {
|
|
property var rowModel: []
|
|
|
|
Layout.fillWidth: true
|
|
spacing: Tokens.spacing.small
|
|
|
|
Repeater {
|
|
model: parent.rowModel
|
|
|
|
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
|
|
toggle: false
|
|
onClicked: {
|
|
root.visibilities.utilities = false;
|
|
root.popouts.detach("network");
|
|
}
|
|
}
|
|
}
|
|
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
|
|
toggle: VPN.status.state !== "needs-auth" && VPN.status.state !== "error"
|
|
inactiveOnColour: Colours.palette.m3onSurfaceVariant
|
|
onClicked: VPN.toggle()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component Toggle: IconButton {
|
|
Layout.fillWidth: true
|
|
Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Tokens.padding.large : internalChecked ? Tokens.padding.smaller : 0)
|
|
radius: stateLayer.pressed ? Tokens.rounding.small / 2 : internalChecked ? Tokens.rounding.small : Tokens.rounding.normal
|
|
inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
|
|
toggle: true
|
|
radiusAnim.duration: Tokens.anim.durations.expressiveFastSpatial
|
|
radiusAnim.easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
|
|
|
Behavior on Layout.preferredWidth {
|
|
Anim {
|
|
duration: Tokens.anim.durations.expressiveFastSpatial
|
|
easing.bezierCurve: Tokens.anim.curves.expressiveFastSpatial
|
|
}
|
|
}
|
|
}
|
|
}
|