summaryrefslogtreecommitdiff
path: root/modules/bar/components
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bar/components')
-rw-r--r--modules/bar/components/StatusIcons.qml204
1 files changed, 126 insertions, 78 deletions
diff --git a/modules/bar/components/StatusIcons.qml b/modules/bar/components/StatusIcons.qml
index 971ec4d..45f943e 100644
--- a/modules/bar/components/StatusIcons.qml
+++ b/modules/bar/components/StatusIcons.qml
@@ -1,3 +1,5 @@
+pragma ComponentBehavior: Bound
+
import qs.widgets
import qs.services
import qs.utils
@@ -6,117 +8,163 @@ import Quickshell
import Quickshell.Bluetooth
import Quickshell.Services.UPower
import QtQuick
+import QtQuick.Layouts
Item {
id: root
property color colour: Colours.palette.m3secondary
- readonly property Item network: network
- readonly property real bs: bluetooth.y
- readonly property real be: repeater.count > 0 ? devices.y + devices.implicitHeight : bluetooth.y + bluetooth.implicitHeight
- readonly property Item battery: battery
+ readonly property list<var> hoverAreas: [
+ {
+ name: "audio",
+ item: audioIcon,
+ enabled: Config.bar.status.showAudio
+ },
+ {
+ name: "network",
+ item: networkIcon,
+ enabled: Config.bar.status.showNetwork
+ },
+ {
+ name: "bluetooth",
+ item: bluetoothGroup,
+ enabled: Config.bar.status.showBluetooth
+ },
+ {
+ name: "battery",
+ item: batteryIcon,
+ enabled: Config.bar.status.showBattery
+ }
+ ]
clip: true
- implicitWidth: Math.max(network.implicitWidth, bluetooth.implicitWidth, devices.implicitWidth, battery.implicitWidth)
- implicitHeight: network.implicitHeight + bluetooth.implicitHeight + bluetooth.anchors.topMargin + (repeater.count > 0 ? devices.implicitHeight + devices.anchors.topMargin : 0) + battery.implicitHeight + battery.anchors.topMargin
+ implicitWidth: iconColumn.implicitWidth
+ implicitHeight: iconColumn.implicitHeight
- MaterialIcon {
- id: network
-
- animate: true
- text: Network.active ? Icons.getNetworkIcon(Network.active.strength ?? 0) : "wifi_off"
- color: root.colour
+ ColumnLayout {
+ id: iconColumn
anchors.horizontalCenter: parent.horizontalCenter
- }
-
- MaterialIcon {
- id: bluetooth
-
- anchors.horizontalCenter: network.horizontalCenter
- anchors.top: network.bottom
- anchors.topMargin: Appearance.spacing.smaller / 2
+ spacing: Appearance.spacing.smaller / 2
- animate: true
- text: Bluetooth.defaultAdapter?.enabled ? "bluetooth" : "bluetooth_disabled"
- color: root.colour
- }
+ // Audio icon
+ Loader {
+ id: audioIcon
- Column {
- id: devices
+ asynchronous: true
+ active: Config.bar.status.showAudio
+ visible: active
- anchors.horizontalCenter: bluetooth.horizontalCenter
- anchors.top: bluetooth.bottom
- anchors.topMargin: Appearance.spacing.smaller / 2
+ sourceComponent: MaterialIcon {
+ animate: true
+ text: Audio.muted ? "volume_off" : Audio.volume >= 0.66 ? "volume_up" : Audio.volume >= 0.33 ? "volume_down" : "volume_mute"
+ color: root.colour
+ }
+ }
- spacing: Appearance.spacing.smaller / 2
+ // Network icon
+ Loader {
+ id: networkIcon
- Repeater {
- id: repeater
+ asynchronous: true
+ active: Config.bar.status.showNetwork
+ visible: active
- model: ScriptModel {
- values: Bluetooth.devices.values.filter(d => d.state !== BluetoothDeviceState.Disconnected)
+ sourceComponent: MaterialIcon {
+ animate: true
+ text: Network.active ? Icons.getNetworkIcon(Network.active.strength ?? 0) : "wifi_off"
+ color: root.colour
}
+ }
- MaterialIcon {
- id: device
+ // Bluetooth section (grouped for hover area)
+ Loader {
+ id: bluetoothGroup
- required property BluetoothDevice modelData
+ asynchronous: true
+ active: Config.bar.status.showBluetooth
+ visible: active
- animate: true
- text: Icons.getBluetoothIcon(modelData.icon)
- color: root.colour
- fill: 1
+ sourceComponent: ColumnLayout {
+ spacing: Appearance.spacing.smaller / 2
- SequentialAnimation on opacity {
- running: device.modelData.state !== BluetoothDeviceState.Connected
- alwaysRunToEnd: true
- loops: Animation.Infinite
+ // Bluetooth icon
+ MaterialIcon {
+ animate: true
+ text: Bluetooth.defaultAdapter?.enabled ? "bluetooth" : "bluetooth_disabled"
+ color: root.colour
+ }
- Anim {
- from: 1
- to: 0
- easing.bezierCurve: Appearance.anim.curves.standardAccel
+ // Connected bluetooth devices
+ Repeater {
+ model: ScriptModel {
+ values: Bluetooth.devices.values.filter(d => d.state !== BluetoothDeviceState.Disconnected)
}
- Anim {
- from: 0
- to: 1
- easing.bezierCurve: Appearance.anim.curves.standardDecel
+
+ MaterialIcon {
+ id: device
+
+ required property BluetoothDevice modelData
+
+ animate: true
+ text: Icons.getBluetoothIcon(modelData.icon)
+ color: root.colour
+ fill: 1
+
+ SequentialAnimation on opacity {
+ running: device.modelData.state !== BluetoothDeviceState.Connected
+ alwaysRunToEnd: true
+ loops: Animation.Infinite
+
+ Anim {
+ from: 1
+ to: 0
+ easing.bezierCurve: Appearance.anim.curves.standardAccel
+ }
+ Anim {
+ from: 0
+ to: 1
+ easing.bezierCurve: Appearance.anim.curves.standardDecel
+ }
+ }
}
}
}
}
- }
- MaterialIcon {
- id: battery
+ // Battery icon
+ Loader {
+ id: batteryIcon
- anchors.horizontalCenter: devices.horizontalCenter
- anchors.top: repeater.count > 0 ? devices.bottom : bluetooth.bottom
- anchors.topMargin: Appearance.spacing.smaller / 2
+ asynchronous: true
+ active: Config.bar.status.showBattery
+ visible: active
- animate: true
- text: {
- if (!UPower.displayDevice.isLaptopBattery) {
- if (PowerProfiles.profile === PowerProfile.PowerSaver)
- return "energy_savings_leaf";
- if (PowerProfiles.profile === PowerProfile.Performance)
- return "rocket_launch";
- return "balance";
- }
+ sourceComponent: MaterialIcon {
+ animate: true
+ text: {
+ if (!UPower.displayDevice.isLaptopBattery) {
+ if (PowerProfiles.profile === PowerProfile.PowerSaver)
+ return "energy_savings_leaf";
+ if (PowerProfiles.profile === PowerProfile.Performance)
+ return "rocket_launch";
+ return "balance";
+ }
- const perc = UPower.displayDevice.percentage;
- const charging = !UPower.onBattery;
- if (perc === 1)
- return charging ? "battery_charging_full" : "battery_full";
- let level = Math.floor(perc * 7);
- if (charging && (level === 4 || level === 1))
- level--;
- return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
+ const perc = UPower.displayDevice.percentage;
+ const charging = !UPower.onBattery;
+ if (perc === 1)
+ return charging ? "battery_charging_full" : "battery_full";
+ let level = Math.floor(perc * 7);
+ if (charging && (level === 4 || level === 1))
+ level--;
+ return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`;
+ }
+ color: !UPower.onBattery || UPower.displayDevice.percentage > 0.2 ? root.colour : Colours.palette.m3error
+ fill: 1
+ }
}
- color: !UPower.onBattery || UPower.displayDevice.percentage > 0.2 ? root.colour : Colours.palette.m3error
- fill: 1
}
Behavior on implicitHeight {