Personal noctalia plugins collection
at main 109 lines 3.9 kB view raw
1import QtQuick 2import Quickshell 3import Quickshell.Services.UPower 4import qs.Commons 5import qs.Widgets 6import qs.Modules.Bar.Extras 7import qs.Services.Hardware 8import qs.Services.UI 9 10Item { 11 id: root 12 13 property QtObject pluginApi: null 14 readonly property QtObject pluginCore: pluginApi?.mainInstance 15 16 property ShellScreen screen 17 property string widgetId: "" 18 property string section: "" 19 property int sectionWidgetIndex: -1 20 property int sectionWidgetsCount: 0 21 22 // Battery state from BatteryService 23 readonly property var selectedDevice: BatteryService.primaryDevice 24 readonly property bool isReady: BatteryService.isDeviceReady(selectedDevice) 25 readonly property real percent: isReady ? BatteryService.getPercentage(selectedDevice) : -1 26 readonly property bool isCharging: isReady ? BatteryService.isCharging(selectedDevice) : false 27 readonly property bool isPluggedIn: isReady ? BatteryService.isPluggedIn(selectedDevice) : false 28 readonly property bool isLowBattery: isReady ? BatteryService.isLowBattery(selectedDevice) : false 29 readonly property bool isCriticalBattery: isReady ? BatteryService.isCriticalBattery(selectedDevice) : false 30 31 readonly property var tooltipContent: { 32 let rows = []; 33 if (isReady) { 34 rows.push(["Battery", percent + "%"]); 35 36 let timeText = BatteryService.getTimeRemainingText(selectedDevice); 37 if (timeText) { 38 const idx = timeText.indexOf(":"); 39 if (idx >= 0) 40 rows.push([timeText.substring(0, idx).trim(), timeText.substring(idx + 1).trim()]); 41 else 42 rows.push([timeText, ""]); 43 } 44 45 let rateText = BatteryService.getRateText(selectedDevice); 46 if (rateText) { 47 const idx = rateText.indexOf(":"); 48 if (idx >= 0) 49 rows.push([rateText.substring(0, idx).trim(), rateText.substring(idx + 1).trim()]); 50 else 51 rows.push([rateText, ""]); 52 } 53 } 54 55 if (pluginCore) { 56 if (rows.length > 0) rows.push(["---", "---"]); 57 rows.push(["Charge limit", pluginCore.chargeLimit + "%"]); 58 } 59 60 return rows; 61 } 62 63 implicitWidth: pill.width 64 implicitHeight: pill.height 65 66 BarPill { 67 id: pill 68 screen: root.screen 69 oppositeDirection: BarService.getPillDirection(root) 70 forceClose: false 71 72 icon: BatteryService.getIcon(root.percent, root.isCharging, root.isPluggedIn, root.isReady) 73 text: root.isReady ? root.percent : "-" 74 suffix: pluginCore && pluginCore.chargeLimit < 100 ? "% \u2193" + pluginCore.chargeLimit : "%" 75 autoHide: false 76 customBackgroundColor: root.isCharging ? Color.mPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mError : "transparent") 77 customTextIconColor: root.isCharging ? Color.mOnPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mOnError : "transparent") 78 tooltipText: root.tooltipContent 79 80 onClicked: pluginCore?.toggle() 81 82 onRightClicked: { 83 PanelService.showContextMenu(contextMenu, pill, root.screen); 84 } 85 } 86 87 NPopupContextMenu { 88 id: contextMenu 89 model: [ 90 { 91 "label": pluginCore && pluginCore.chargeLimit < 100 92 ? "Set charge limit to 100%" 93 : "Set charge limit to 80%", 94 "action": "toggle", 95 "icon": "battery_saver", 96 "enabled": true 97 } 98 ] 99 100 onTriggered: action => { 101 contextMenu.close(); 102 PanelService.closeContextMenu(root.screen); 103 104 if (action === "toggle") { 105 pluginCore?.toggle(); 106 } 107 } 108 } 109}