mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Add BatteryPanel with charge level, power profile settings, prevent sleep toggle, battery health (if available)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
.qmlls.ini
|
.qmlls.ini
|
||||||
.zed
|
.zed
|
||||||
Bin/battery-manager/uninstall-battery-manager.sh
|
Bin/battery-manager/uninstall-battery-manager.sh
|
||||||
|
.idea
|
||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Helligkeit",
|
||||||
|
"charge-level": "Ladestand",
|
||||||
"charging": "Wird geladen.",
|
"charging": "Wird geladen.",
|
||||||
"charging-rate": "Laderate: {rate} W.",
|
"charging-rate": "Laderate: {rate} W.",
|
||||||
"discharging": "Wird entladen.",
|
"discharging": "Wird entladen.",
|
||||||
"discharging-rate": "Entladerate: {rate} W.",
|
"discharging-rate": "Entladerate: {rate} W.",
|
||||||
"health": "Zustand: {percent}%",
|
"health": "Zustand: {percent}%",
|
||||||
|
"inhibit-idle-description": "Hält das System wach.",
|
||||||
|
"inhibit-idle-label": "Ruhezustand verhindern",
|
||||||
"idle": "Leerlauf.",
|
"idle": "Leerlauf.",
|
||||||
"no-battery-detected": "Keine Batterie erkannt.",
|
"no-battery-detected": "Keine Batterie erkannt.",
|
||||||
|
"panel-title": "Akku",
|
||||||
"plugged-in": "Angeschlossen.",
|
"plugged-in": "Angeschlossen.",
|
||||||
|
"power-profile": "Energieprofil",
|
||||||
"time-left": "Verbleibende Zeit: {time}.",
|
"time-left": "Verbleibende Zeit: {time}.",
|
||||||
"time-until-full": "Zeit bis vollständig geladen: {time}."
|
"time-until-full": "Zeit bis vollständig geladen: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Brightness",
|
||||||
|
"charge-level": "Charge level",
|
||||||
"charging": "Charging",
|
"charging": "Charging",
|
||||||
"charging-rate": "Charging rate: {rate} W",
|
"charging-rate": "Charging rate: {rate} W",
|
||||||
"discharging": "Discharging",
|
"discharging": "Discharging",
|
||||||
"discharging-rate": "Discharging rate: {rate} W",
|
"discharging-rate": "Discharging rate: {rate} W",
|
||||||
"health": "Health: {percent}%",
|
"health": "Health: {percent}%",
|
||||||
|
"inhibit-idle-description": "Keeps the system awake.",
|
||||||
|
"inhibit-idle-label": "Prevent sleep",
|
||||||
"idle": "Idle",
|
"idle": "Idle",
|
||||||
"no-battery-detected": "No battery detected",
|
"no-battery-detected": "No battery detected",
|
||||||
|
"panel-title": "Battery",
|
||||||
"plugged-in": "Plugged in",
|
"plugged-in": "Plugged in",
|
||||||
|
"power-profile": "Power profile",
|
||||||
"time-left": "Time left: {time}",
|
"time-left": "Time left: {time}",
|
||||||
"time-until-full": "Time until full: {time}"
|
"time-until-full": "Time until full: {time}"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Brillo",
|
||||||
|
"charge-level": "Nivel de carga",
|
||||||
"charging": "Cargando.",
|
"charging": "Cargando.",
|
||||||
"charging-rate": "Tasa de carga: {rate} W.",
|
"charging-rate": "Tasa de carga: {rate} W.",
|
||||||
"discharging": "Descargando.",
|
"discharging": "Descargando.",
|
||||||
"discharging-rate": "Tasa de descarga: {rate} W.",
|
"discharging-rate": "Tasa de descarga: {rate} W.",
|
||||||
"health": "Salud: {percent}%",
|
"health": "Salud: {percent}%",
|
||||||
|
"inhibit-idle-description": "Mantiene el sistema despierto.",
|
||||||
|
"inhibit-idle-label": "Evitar suspensión",
|
||||||
"idle": "Inactivo.",
|
"idle": "Inactivo.",
|
||||||
"no-battery-detected": "No se detectó ninguna batería.",
|
"no-battery-detected": "No se detectó ninguna batería.",
|
||||||
|
"panel-title": "Batería",
|
||||||
"plugged-in": "Conectado.",
|
"plugged-in": "Conectado.",
|
||||||
|
"power-profile": "Perfil de energía",
|
||||||
"time-left": "Tiempo restante: {time}.",
|
"time-left": "Tiempo restante: {time}.",
|
||||||
"time-until-full": "Tiempo hasta carga completa: {time}."
|
"time-until-full": "Tiempo hasta carga completa: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Luminosité",
|
||||||
|
"charge-level": "Niveau de charge",
|
||||||
"charging": "En charge.",
|
"charging": "En charge.",
|
||||||
"charging-rate": "Taux de charge : {rate} W.",
|
"charging-rate": "Taux de charge : {rate} W.",
|
||||||
"discharging": "En décharge.",
|
"discharging": "En décharge.",
|
||||||
"discharging-rate": "Taux de décharge : {rate} W.",
|
"discharging-rate": "Taux de décharge : {rate} W.",
|
||||||
"health": "État : {percent}%",
|
"health": "État : {percent}%",
|
||||||
|
"inhibit-idle-description": "Maintient le système éveillé.",
|
||||||
|
"inhibit-idle-label": "Empêcher la veille",
|
||||||
"idle": "Inactif.",
|
"idle": "Inactif.",
|
||||||
"no-battery-detected": "Aucune batterie détectée.",
|
"no-battery-detected": "Aucune batterie détectée.",
|
||||||
|
"panel-title": "Batterie",
|
||||||
"plugged-in": "Branché.",
|
"plugged-in": "Branché.",
|
||||||
|
"power-profile": "Profil d’alimentation",
|
||||||
"time-left": "Temps restant : {time}.",
|
"time-left": "Temps restant : {time}.",
|
||||||
"time-until-full": "Temps jusqu'à charge complète : {time}."
|
"time-until-full": "Temps jusqu'à charge complète : {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Helderheid",
|
||||||
|
"charge-level": "Laadniveau",
|
||||||
"charging": "Opladen.",
|
"charging": "Opladen.",
|
||||||
"charging-rate": "Laadsnelheid: {rate} W.",
|
"charging-rate": "Laadsnelheid: {rate} W.",
|
||||||
"discharging": "Ontladen.",
|
"discharging": "Ontladen.",
|
||||||
"discharging-rate": "Ontlaadsnelheid: {rate} W.",
|
"discharging-rate": "Ontlaadsnelheid: {rate} W.",
|
||||||
"health": "Gezondheid: {percent}%",
|
"health": "Gezondheid: {percent}%",
|
||||||
|
"inhibit-idle-description": "Houdt het systeem wakker.",
|
||||||
|
"inhibit-idle-label": "Slaapstand voorkomen",
|
||||||
"idle": "In rust.",
|
"idle": "In rust.",
|
||||||
"no-battery-detected": "Geen batterij gedetecteerd.",
|
"no-battery-detected": "Geen batterij gedetecteerd.",
|
||||||
|
"panel-title": "Batterij",
|
||||||
"plugged-in": "Op netstroom.",
|
"plugged-in": "Op netstroom.",
|
||||||
|
"power-profile": "Energieprofiel",
|
||||||
"time-left": "Resterende tijd: {time}.",
|
"time-left": "Resterende tijd: {time}.",
|
||||||
"time-until-full": "Tijd tot vol: {time}."
|
"time-until-full": "Tijd tot vol: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Brilho",
|
||||||
|
"charge-level": "Nível de carga",
|
||||||
"charging": "Carregando.",
|
"charging": "Carregando.",
|
||||||
"charging-rate": "Taxa de carregamento: {rate} W.",
|
"charging-rate": "Taxa de carregamento: {rate} W.",
|
||||||
"discharging": "Descarregando.",
|
"discharging": "Descarregando.",
|
||||||
"discharging-rate": "Taxa de descarregamento: {rate} W.",
|
"discharging-rate": "Taxa de descarregamento: {rate} W.",
|
||||||
"health": "Saúde: {percent}%",
|
"health": "Saúde: {percent}%",
|
||||||
|
"inhibit-idle-description": "Mantém o sistema acordado.",
|
||||||
|
"inhibit-idle-label": "Impedir suspensão",
|
||||||
"idle": "Ocioso.",
|
"idle": "Ocioso.",
|
||||||
"no-battery-detected": "Nenhuma bateria detectada.",
|
"no-battery-detected": "Nenhuma bateria detectada.",
|
||||||
|
"panel-title": "Bateria",
|
||||||
"plugged-in": "Conectado.",
|
"plugged-in": "Conectado.",
|
||||||
|
"power-profile": "Perfil de energia",
|
||||||
"time-left": "Tempo restante: {time}.",
|
"time-left": "Tempo restante: {time}.",
|
||||||
"time-until-full": "Tempo até carga completa: {time}."
|
"time-until-full": "Tempo até carga completa: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Яркость",
|
||||||
|
"charge-level": "Уровень заряда",
|
||||||
"charging": "Зарядка.",
|
"charging": "Зарядка.",
|
||||||
"charging-rate": "Скорость зарядки: {rate} Вт.",
|
"charging-rate": "Скорость зарядки: {rate} Вт.",
|
||||||
"discharging": "Разрядка.",
|
"discharging": "Разрядка.",
|
||||||
"discharging-rate": "Скорость разрядки: {rate} Вт.",
|
"discharging-rate": "Скорость разрядки: {rate} Вт.",
|
||||||
"health": "Здоровье: {percent}%",
|
"health": "Здоровье: {percent}%",
|
||||||
|
"inhibit-idle-description": "Не дает системе уснуть.",
|
||||||
|
"inhibit-idle-label": "Запрет сна",
|
||||||
"idle": "Простой.",
|
"idle": "Простой.",
|
||||||
"no-battery-detected": "Батарея не обнаружена.",
|
"no-battery-detected": "Батарея не обнаружена.",
|
||||||
|
"panel-title": "Батарея",
|
||||||
"plugged-in": "Подключено.",
|
"plugged-in": "Подключено.",
|
||||||
|
"power-profile": "Профиль питания",
|
||||||
"time-left": "Осталось времени: {time}.",
|
"time-left": "Осталось времени: {time}.",
|
||||||
"time-until-full": "Время до полной зарядки: {time}."
|
"time-until-full": "Время до полной зарядки: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Parlaklık",
|
||||||
|
"charge-level": "Şarj seviyesi",
|
||||||
"charging": "Şarj oluyor.",
|
"charging": "Şarj oluyor.",
|
||||||
"charging-rate": "Şarj oranı: {rate} W.",
|
"charging-rate": "Şarj oranı: {rate} W.",
|
||||||
"discharging": "Deşarj oluyor.",
|
"discharging": "Deşarj oluyor.",
|
||||||
"discharging-rate": "Deşarj oranı: {rate} W.",
|
"discharging-rate": "Deşarj oranı: {rate} W.",
|
||||||
"health": "Sağlık: {percent}%",
|
"health": "Sağlık: {percent}%",
|
||||||
|
"inhibit-idle-description": "Sistemi uyanık tutar.",
|
||||||
|
"inhibit-idle-label": "Uykuya engelle",
|
||||||
"idle": "Boşta.",
|
"idle": "Boşta.",
|
||||||
"no-battery-detected": "Pil tespit edilmedi.",
|
"no-battery-detected": "Pil tespit edilmedi.",
|
||||||
|
"panel-title": "Pil",
|
||||||
"plugged-in": "Prize takılı.",
|
"plugged-in": "Prize takılı.",
|
||||||
|
"power-profile": "Güç profili",
|
||||||
"time-left": "Kalan süre: {time}.",
|
"time-left": "Kalan süre: {time}.",
|
||||||
"time-until-full": "Dolma süresi: {time}."
|
"time-until-full": "Dolma süresi: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "Яскравість",
|
||||||
|
"charge-level": "Рівень заряду",
|
||||||
"charging": "Зарядка.",
|
"charging": "Зарядка.",
|
||||||
"charging-rate": "Швидкість зарядки: {rate} Вт.",
|
"charging-rate": "Швидкість зарядки: {rate} Вт.",
|
||||||
"discharging": "Розрядка.",
|
"discharging": "Розрядка.",
|
||||||
"discharging-rate": "Швидкість розрядки: {rate} Вт.",
|
"discharging-rate": "Швидкість розрядки: {rate} Вт.",
|
||||||
"health": "Здоров'я: {percent}%",
|
"health": "Здоров'я: {percent}%",
|
||||||
|
"inhibit-idle-description": "Підтримує систему активною.",
|
||||||
|
"inhibit-idle-label": "Запобігати сну",
|
||||||
"idle": "Бездіяльність.",
|
"idle": "Бездіяльність.",
|
||||||
"no-battery-detected": "Батарею не виявлено.",
|
"no-battery-detected": "Батарею не виявлено.",
|
||||||
|
"panel-title": "Батарея",
|
||||||
"plugged-in": "Підключено.",
|
"plugged-in": "Підключено.",
|
||||||
|
"power-profile": "Профіль живлення",
|
||||||
"time-left": "Залишилось часу: {time}.",
|
"time-left": "Залишилось часу: {time}.",
|
||||||
"time-until-full": "Час до повного заряду: {time}."
|
"time-until-full": "Час до повного заряду: {time}."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -381,14 +381,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"battery": {
|
"battery": {
|
||||||
|
"brightness": "亮度",
|
||||||
|
"charge-level": "电量",
|
||||||
"charging": "正在充电。",
|
"charging": "正在充电。",
|
||||||
"charging-rate": "充电速率:{rate} W。",
|
"charging-rate": "充电速率:{rate} W。",
|
||||||
"discharging": "正在放电。",
|
"discharging": "正在放电。",
|
||||||
"discharging-rate": "放电速率:{rate} W。",
|
"discharging-rate": "放电速率:{rate} W。",
|
||||||
"health": "健康状况:{percent}%",
|
"health": "健康状况:{percent}%",
|
||||||
|
"inhibit-idle-description": "保持系统唤醒。",
|
||||||
|
"inhibit-idle-label": "防止睡眠",
|
||||||
"idle": "空闲。",
|
"idle": "空闲。",
|
||||||
"no-battery-detected": "未检测到电池。",
|
"no-battery-detected": "未检测到电池。",
|
||||||
|
"panel-title": "电池",
|
||||||
"plugged-in": "已接通电源。",
|
"plugged-in": "已接通电源。",
|
||||||
|
"power-profile": "电源模式",
|
||||||
"time-left": "剩余时间:{time}。",
|
"time-left": "剩余时间:{time}。",
|
||||||
"time-until-full": "充满所需时间:{time}。"
|
"time-until-full": "充满所需时间:{time}。"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ Item {
|
|||||||
}
|
}
|
||||||
return lines.join("\n");
|
return lines.join("\n");
|
||||||
}
|
}
|
||||||
|
onClicked: PanelService.getPanel("batteryPanel", screen)?.toggle(this)
|
||||||
onRightClicked: {
|
onRightClicked: {
|
||||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||||
if (popupMenuWindow) {
|
if (popupMenuWindow) {
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ Item {
|
|||||||
backgroundColor: panelBackgroundColor
|
backgroundColor: panelBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Battery
|
||||||
|
PanelBackground {
|
||||||
|
panel: root.windowRoot.batteryPanelPlaceholder
|
||||||
|
shapeContainer: backgroundsShape
|
||||||
|
backgroundColor: panelBackgroundColor
|
||||||
|
}
|
||||||
|
|
||||||
// Bluetooth
|
// Bluetooth
|
||||||
PanelBackground {
|
PanelBackground {
|
||||||
panel: root.windowRoot.bluetoothPanelPlaceholder
|
panel: root.windowRoot.bluetoothPanelPlaceholder
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import qs.Commons
|
|||||||
import qs.Modules.Bar
|
import qs.Modules.Bar
|
||||||
import qs.Modules.Bar.Extras
|
import qs.Modules.Bar.Extras
|
||||||
import qs.Modules.Panels.Audio
|
import qs.Modules.Panels.Audio
|
||||||
|
import qs.Modules.Panels.Battery
|
||||||
import qs.Modules.Panels.Bluetooth
|
import qs.Modules.Panels.Bluetooth
|
||||||
import qs.Modules.Panels.Brightness
|
import qs.Modules.Panels.Brightness
|
||||||
import qs.Modules.Panels.Calendar
|
import qs.Modules.Panels.Calendar
|
||||||
@@ -33,6 +34,7 @@ PanelWindow {
|
|||||||
|
|
||||||
// Expose panels as readonly property aliases
|
// Expose panels as readonly property aliases
|
||||||
readonly property alias audioPanel: audioPanel
|
readonly property alias audioPanel: audioPanel
|
||||||
|
readonly property alias batteryPanel: batteryPanel
|
||||||
readonly property alias bluetoothPanel: bluetoothPanel
|
readonly property alias bluetoothPanel: bluetoothPanel
|
||||||
readonly property alias brightnessPanel: brightnessPanel
|
readonly property alias brightnessPanel: brightnessPanel
|
||||||
readonly property alias calendarPanel: calendarPanel
|
readonly property alias calendarPanel: calendarPanel
|
||||||
@@ -49,6 +51,7 @@ PanelWindow {
|
|||||||
|
|
||||||
// Expose panel placeholders for AllBackgrounds
|
// Expose panel placeholders for AllBackgrounds
|
||||||
readonly property var audioPanelPlaceholder: audioPanel.panelPlaceholder
|
readonly property var audioPanelPlaceholder: audioPanel.panelPlaceholder
|
||||||
|
readonly property var batteryPanelPlaceholder: batteryPanel.panelPlaceholder
|
||||||
readonly property var bluetoothPanelPlaceholder: bluetoothPanel.panelPlaceholder
|
readonly property var bluetoothPanelPlaceholder: bluetoothPanel.panelPlaceholder
|
||||||
readonly property var brightnessPanelPlaceholder: brightnessPanel.panelPlaceholder
|
readonly property var brightnessPanelPlaceholder: brightnessPanel.panelPlaceholder
|
||||||
readonly property var calendarPanelPlaceholder: calendarPanel.panelPlaceholder
|
readonly property var calendarPanelPlaceholder: calendarPanel.panelPlaceholder
|
||||||
@@ -168,6 +171,12 @@ PanelWindow {
|
|||||||
screen: root.screen
|
screen: root.screen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BatteryPanel {
|
||||||
|
id: batteryPanel
|
||||||
|
objectName: "batteryPanel-" + (root.screen?.name || "unknown")
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
|
||||||
BluetoothPanel {
|
BluetoothPanel {
|
||||||
id: bluetoothPanel
|
id: bluetoothPanel
|
||||||
objectName: "bluetoothPanel-" + (root.screen?.name || "unknown")
|
objectName: "bluetoothPanel-" + (root.screen?.name || "unknown")
|
||||||
|
|||||||
@@ -0,0 +1,289 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.UPower
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Modules.MainScreen
|
||||||
|
import qs.Services.Hardware
|
||||||
|
import qs.Services.Power
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
SmartPanel {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
preferredWidth: Math.round(360 * Style.uiScaleRatio)
|
||||||
|
preferredHeight: Math.round(460 * Style.uiScaleRatio)
|
||||||
|
|
||||||
|
readonly property var battery: UPower.displayDevice
|
||||||
|
readonly property bool isReady: battery && battery.ready && battery.isLaptopBattery && battery.isPresent
|
||||||
|
readonly property int percent: isReady ? Math.round(battery.percentage * 100) : -1
|
||||||
|
readonly property bool charging: isReady ? battery.state === UPowerDeviceState.Charging : false
|
||||||
|
readonly property bool healthSupported: isReady && battery.healthSupported
|
||||||
|
readonly property bool healthAvailable: healthSupported
|
||||||
|
readonly property int healthPercent: healthAvailable ? Math.round(battery.healthPercentage) : -1
|
||||||
|
readonly property string timeText: {
|
||||||
|
if (!isReady)
|
||||||
|
return I18n.tr("battery.no-battery-detected");
|
||||||
|
if (charging && battery.timeToFull > 0) {
|
||||||
|
return I18n.tr("battery.time-until-full", {
|
||||||
|
"time": Time.formatVagueHumanReadableDuration(battery.timeToFull)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!charging && battery.timeToEmpty > 0) {
|
||||||
|
return I18n.tr("battery.time-left", {
|
||||||
|
"time": Time.formatVagueHumanReadableDuration(battery.timeToEmpty)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return I18n.tr("battery.idle");
|
||||||
|
}
|
||||||
|
readonly property string iconName: BatteryService.getIcon(percent, charging, isReady)
|
||||||
|
readonly property bool profilesAvailable: PowerProfileService.available
|
||||||
|
property int profileIndex: profileToIndex(PowerProfileService.profile)
|
||||||
|
property bool manualInhibitActive: manualInhibitorEnabled()
|
||||||
|
|
||||||
|
panelContent: Item {
|
||||||
|
property real contentPreferredHeight: mainLayout.implicitHeight + Style.marginL * 2
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginL
|
||||||
|
spacing: Style.marginM
|
||||||
|
|
||||||
|
// HEADER
|
||||||
|
NBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: headerRow.implicitHeight + (Style.marginM * 2)
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: headerRow
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginM
|
||||||
|
spacing: Style.marginM
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
pointSize: Style.fontSizeXXL
|
||||||
|
color: Color.mPrimary
|
||||||
|
icon: iconName
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Style.marginXXS
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: I18n.tr("battery.panel-title")
|
||||||
|
pointSize: Style.fontSizeL
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: timeText
|
||||||
|
pointSize: Style.fontSizeS
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIconButton {
|
||||||
|
icon: "close"
|
||||||
|
tooltipText: I18n.tr("tooltips.close")
|
||||||
|
baseSize: Style.baseWidgetSize * 0.8
|
||||||
|
onClicked: root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Charge level + health/time
|
||||||
|
NBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: chargeLayout.implicitHeight + Style.marginM * 2
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: chargeLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginM
|
||||||
|
spacing: Style.marginS
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Style.marginS
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: I18n.tr("battery.charge-level")
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
pointSize: Style.fontSizeS
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
NText {
|
||||||
|
text: percent >= 0 ? `${percent}%` : "--"
|
||||||
|
color: Color.mOnSurface
|
||||||
|
pointSize: Style.fontSizeS
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: Math.round(8 * Style.uiScaleRatio)
|
||||||
|
radius: height / 2
|
||||||
|
color: Color.mSurfaceVariant
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
height: parent.height
|
||||||
|
radius: parent.radius
|
||||||
|
width: {
|
||||||
|
var ratio = Math.max(0, Math.min(1, percent / 100));
|
||||||
|
return parent.width * ratio;
|
||||||
|
}
|
||||||
|
color: Color.mPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Style.marginL
|
||||||
|
visible: healthAvailable
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: I18n.tr("battery.health", {"percent": healthPercent})
|
||||||
|
color: Color.mOnSurface
|
||||||
|
pointSize: Style.fontSizeS
|
||||||
|
font.weight: Style.fontWeightMedium
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Power profile and idle inhibit controls
|
||||||
|
NBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: controlsLayout.implicitHeight + Style.marginM * 2
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: controlsLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Style.marginM
|
||||||
|
spacing: Style.marginM
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Style.marginS
|
||||||
|
NIcon {
|
||||||
|
icon: PowerProfileService.getIcon(); pointSize: Style.fontSizeM; color: Color.mPrimary
|
||||||
|
}
|
||||||
|
NText {
|
||||||
|
text: I18n.tr("battery.power-profile")
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
color: Color.mOnSurface
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
NText {
|
||||||
|
text: PowerProfileService.getName()
|
||||||
|
color: Color.mOnSurfaceVariant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NValueSlider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
from: 0
|
||||||
|
to: 2
|
||||||
|
stepSize: 1
|
||||||
|
snapAlways: true
|
||||||
|
value: profileIndex
|
||||||
|
enabled: profilesAvailable
|
||||||
|
onPressedChanged: function (pressed, v) {
|
||||||
|
if (!pressed) {
|
||||||
|
setProfileByIndex(Math.round(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMoved: function (v) {
|
||||||
|
profileIndex = Math.round(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
checked: manualInhibitActive
|
||||||
|
label: I18n.tr("battery.inhibit-idle-label")
|
||||||
|
description: I18n.tr("battery.inhibit-idle-description")
|
||||||
|
onToggled: function (checked) {
|
||||||
|
if (checked) {
|
||||||
|
IdleInhibitorService.addManualInhibitor(null);
|
||||||
|
} else {
|
||||||
|
IdleInhibitorService.removeManualInhibitor();
|
||||||
|
}
|
||||||
|
manualInhibitActive = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function profileToIndex(p) {
|
||||||
|
switch (p) {
|
||||||
|
case PowerProfile.PowerSaver:
|
||||||
|
return 0;
|
||||||
|
case PowerProfile.Balanced:
|
||||||
|
return 1;
|
||||||
|
case PowerProfile.Performance:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function indexToProfile(idx) {
|
||||||
|
switch (idx) {
|
||||||
|
case 0:
|
||||||
|
return PowerProfile.PowerSaver;
|
||||||
|
case 2:
|
||||||
|
return PowerProfile.Performance;
|
||||||
|
default:
|
||||||
|
return PowerProfile.Balanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileByIndex(idx) {
|
||||||
|
var prof = indexToProfile(idx);
|
||||||
|
profileIndex = idx;
|
||||||
|
PowerProfileService.setProfile(prof);
|
||||||
|
}
|
||||||
|
|
||||||
|
function manualInhibitorEnabled() {
|
||||||
|
return IdleInhibitorService.activeInhibitors && IdleInhibitorService.activeInhibitors.indexOf("manual") >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: IdleInhibitorService
|
||||||
|
|
||||||
|
function onIsInhibitedChanged() {
|
||||||
|
manualInhibitActive = manualInhibitorEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: inhibitorPoll
|
||||||
|
interval: 1000
|
||||||
|
repeat: true
|
||||||
|
running: true
|
||||||
|
onTriggered: manualInhibitActive = manualInhibitorEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: PowerProfileService
|
||||||
|
|
||||||
|
function onProfileChanged() {
|
||||||
|
profileIndex = profileToIndex(PowerProfileService.profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user