mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
434 lines
17 KiB
QML
434 lines
17 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import qs.Common
|
|
import qs.Modules.Plugins
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
BasePill {
|
|
id: root
|
|
|
|
property bool isActive: false
|
|
property var popoutTarget: null
|
|
property var widgetData: null
|
|
property string screenName: ""
|
|
property string screenModel: ""
|
|
property bool showNetworkIcon: SettingsData.controlCenterShowNetworkIcon
|
|
property bool showBluetoothIcon: SettingsData.controlCenterShowBluetoothIcon
|
|
property bool showAudioIcon: SettingsData.controlCenterShowAudioIcon
|
|
property bool showVpnIcon: SettingsData.controlCenterShowVpnIcon
|
|
property bool showBrightnessIcon: SettingsData.controlCenterShowBrightnessIcon
|
|
property bool showMicIcon: SettingsData.controlCenterShowMicIcon
|
|
property bool showBatteryIcon: SettingsData.controlCenterShowBatteryIcon
|
|
property bool showPrinterIcon: SettingsData.controlCenterShowPrinterIcon
|
|
|
|
function getNetworkIconName() {
|
|
if (NetworkService.wifiToggling)
|
|
return "sync";
|
|
switch (NetworkService.networkStatus) {
|
|
case "ethernet":
|
|
return "lan";
|
|
case "vpn":
|
|
return NetworkService.ethernetConnected ? "lan" : NetworkService.wifiSignalIcon;
|
|
default:
|
|
return NetworkService.wifiSignalIcon;
|
|
}
|
|
}
|
|
|
|
function getNetworkIconColor() {
|
|
if (NetworkService.wifiToggling)
|
|
return Theme.primary;
|
|
return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton;
|
|
}
|
|
|
|
function getVolumeIconName() {
|
|
if (!AudioService.sink?.audio)
|
|
return "volume_up";
|
|
if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0)
|
|
return "volume_off";
|
|
if (AudioService.sink.audio.volume * 100 < 33)
|
|
return "volume_down";
|
|
return "volume_up";
|
|
}
|
|
|
|
function getMicIconName() {
|
|
if (!AudioService.source?.audio)
|
|
return "mic";
|
|
if (AudioService.source.audio.muted || AudioService.source.audio.volume === 0)
|
|
return "mic_off";
|
|
return "mic";
|
|
}
|
|
|
|
function getMicIconColor() {
|
|
if (!AudioService.source?.audio)
|
|
return Theme.outlineButton;
|
|
if (AudioService.source.audio.muted || AudioService.source.audio.volume === 0)
|
|
return Theme.outlineButton;
|
|
return Theme.widgetIconColor;
|
|
}
|
|
|
|
function getBrightnessIconName() {
|
|
const deviceName = getPinnedBrightnessDevice();
|
|
if (!deviceName)
|
|
return "brightness_medium";
|
|
const level = DisplayService.getDeviceBrightness(deviceName);
|
|
if (level <= 33)
|
|
return "brightness_low";
|
|
if (level <= 66)
|
|
return "brightness_medium";
|
|
return "brightness_high";
|
|
}
|
|
|
|
function getScreenPinKey() {
|
|
if (!root.screenName)
|
|
return "";
|
|
const screen = Quickshell.screens.find(s => s.name === root.screenName);
|
|
if (screen) {
|
|
return SettingsData.getScreenDisplayName(screen);
|
|
}
|
|
if (SettingsData.displayNameMode === "model" && root.screenModel && root.screenModel.length > 0) {
|
|
return root.screenModel;
|
|
}
|
|
return root.screenName;
|
|
}
|
|
|
|
function getPinnedBrightnessDevice() {
|
|
const pinKey = getScreenPinKey();
|
|
if (!pinKey)
|
|
return "";
|
|
const pins = SettingsData.brightnessDevicePins || {};
|
|
return pins[pinKey] || "";
|
|
}
|
|
|
|
function hasPinnedBrightnessDevice() {
|
|
return getPinnedBrightnessDevice().length > 0;
|
|
}
|
|
|
|
function handleVolumeWheel(delta) {
|
|
if (!AudioService.sink?.audio)
|
|
return;
|
|
const currentVolume = AudioService.sink.audio.volume * 100;
|
|
const newVolume = delta > 0 ? Math.min(100, currentVolume + 5) : Math.max(0, currentVolume - 5);
|
|
AudioService.sink.audio.muted = false;
|
|
AudioService.sink.audio.volume = newVolume / 100;
|
|
AudioService.playVolumeChangeSoundIfEnabled();
|
|
}
|
|
|
|
function handleMicWheel(delta) {
|
|
if (!AudioService.source?.audio)
|
|
return;
|
|
const currentVolume = AudioService.source.audio.volume * 100;
|
|
const newVolume = delta > 0 ? Math.min(100, currentVolume + 5) : Math.max(0, currentVolume - 5);
|
|
AudioService.source.audio.muted = false;
|
|
AudioService.source.audio.volume = newVolume / 100;
|
|
}
|
|
|
|
function handleBrightnessWheel(delta) {
|
|
const deviceName = getPinnedBrightnessDevice();
|
|
if (!deviceName)
|
|
return;
|
|
const currentBrightness = DisplayService.getDeviceBrightness(deviceName);
|
|
const newBrightness = delta > 0 ? Math.min(100, currentBrightness + 5) : Math.max(1, currentBrightness - 5);
|
|
DisplayService.setBrightness(newBrightness, deviceName, false);
|
|
}
|
|
|
|
function getBatteryIconColor() {
|
|
if (!BatteryService.batteryAvailable)
|
|
return Theme.widgetIconColor;
|
|
if (BatteryService.isLowBattery && !BatteryService.isCharging)
|
|
return Theme.error;
|
|
if (BatteryService.isCharging || BatteryService.isPluggedIn)
|
|
return Theme.primary;
|
|
return Theme.widgetIconColor;
|
|
}
|
|
|
|
function hasPrintJobs() {
|
|
return CupsService.getTotalJobsNum() > 0;
|
|
}
|
|
|
|
function hasNoVisibleIcons() {
|
|
return !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon && !root.showVpnIcon && !root.showBrightnessIcon && !root.showMicIcon && !root.showBatteryIcon && !root.showPrinterIcon;
|
|
}
|
|
|
|
content: Component {
|
|
Item {
|
|
implicitWidth: root.isVerticalOrientation ? (root.widgetThickness - root.horizontalPadding * 2) : controlIndicators.implicitWidth
|
|
implicitHeight: root.isVerticalOrientation ? controlColumn.implicitHeight : (root.widgetThickness - root.horizontalPadding * 2)
|
|
|
|
Column {
|
|
id: controlColumn
|
|
visible: root.isVerticalOrientation
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: root.getNetworkIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getNetworkIconColor()
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
|
}
|
|
|
|
DankIcon {
|
|
name: "vpn_lock"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: NetworkService.vpnConnected ? Theme.primary : Theme.outlineButton
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected
|
|
}
|
|
|
|
DankIcon {
|
|
name: "bluetooth"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
|
}
|
|
|
|
Rectangle {
|
|
width: audioIconV.implicitWidth + 4
|
|
height: audioIconV.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showAudioIcon
|
|
|
|
DankIcon {
|
|
id: audioIconV
|
|
name: root.getVolumeIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.widgetIconColor
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleVolumeWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: micIconV.implicitWidth + 4
|
|
height: micIconV.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showMicIcon
|
|
|
|
DankIcon {
|
|
id: micIconV
|
|
name: root.getMicIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getMicIconColor()
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleMicWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: brightnessIconV.implicitWidth + 4
|
|
height: brightnessIconV.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice()
|
|
|
|
DankIcon {
|
|
id: brightnessIconV
|
|
name: root.getBrightnessIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.widgetIconColor
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleBrightnessWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
DankIcon {
|
|
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable)
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getBatteryIconColor()
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showBatteryIcon && BatteryService.batteryAvailable
|
|
}
|
|
|
|
DankIcon {
|
|
name: "print"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.primary
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs()
|
|
}
|
|
|
|
DankIcon {
|
|
name: "settings"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.isActive ? Theme.primary : Theme.widgetIconColor
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
visible: root.hasNoVisibleIcons()
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: controlIndicators
|
|
visible: !root.isVerticalOrientation
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
id: networkIcon
|
|
name: root.getNetworkIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getNetworkIconColor()
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showNetworkIcon && NetworkService.networkAvailable
|
|
}
|
|
|
|
DankIcon {
|
|
id: vpnIcon
|
|
name: "vpn_lock"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: NetworkService.vpnConnected ? Theme.primary : Theme.outlineButton
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showVpnIcon && NetworkService.vpnAvailable && NetworkService.vpnConnected
|
|
}
|
|
|
|
DankIcon {
|
|
id: bluetoothIcon
|
|
name: "bluetooth"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: BluetoothService.connected ? Theme.primary : Theme.outlineButton
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
|
|
}
|
|
|
|
Rectangle {
|
|
width: audioIcon.implicitWidth + 4
|
|
height: audioIcon.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showAudioIcon
|
|
|
|
DankIcon {
|
|
id: audioIcon
|
|
name: root.getVolumeIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.widgetIconColor
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
id: audioWheelArea
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleVolumeWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: micIcon.implicitWidth + 4
|
|
height: micIcon.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showMicIcon
|
|
|
|
DankIcon {
|
|
id: micIcon
|
|
name: root.getMicIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getMicIconColor()
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
id: micWheelArea
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleMicWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: brightnessIcon.implicitWidth + 4
|
|
height: brightnessIcon.implicitHeight + 4
|
|
color: "transparent"
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showBrightnessIcon && DisplayService.brightnessAvailable && root.hasPinnedBrightnessDevice()
|
|
|
|
DankIcon {
|
|
id: brightnessIcon
|
|
name: root.getBrightnessIconName()
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.widgetIconColor
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
MouseArea {
|
|
id: brightnessWheelArea
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
onWheel: function (wheelEvent) {
|
|
root.handleBrightnessWheel(wheelEvent.angleDelta.y);
|
|
wheelEvent.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
DankIcon {
|
|
id: batteryIcon
|
|
name: Theme.getBatteryIcon(BatteryService.batteryLevel, BatteryService.isCharging, BatteryService.batteryAvailable)
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.getBatteryIconColor()
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showBatteryIcon && BatteryService.batteryAvailable
|
|
}
|
|
|
|
DankIcon {
|
|
id: printerIcon
|
|
name: "print"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showPrinterIcon && CupsService.cupsAvailable && root.hasPrintJobs()
|
|
}
|
|
|
|
DankIcon {
|
|
name: "settings"
|
|
size: Theme.barIconSize(root.barThickness)
|
|
color: root.isActive ? Theme.primary : Theme.widgetIconColor
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.hasNoVisibleIcons()
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.PointingHandCursor
|
|
acceptedButtons: Qt.NoButton
|
|
}
|
|
}
|
|
}
|
|
}
|