mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
battery-widget: better tooltip, reworked logic and improved display
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
"device-label": "Akkugerät",
|
||||
"display-mode-description": "Wählen Sie, wie der Akku in der Leiste angezeigt wird.",
|
||||
"display-mode-graphic": "Grafischer Akku",
|
||||
"display-mode-graphic-clean": "Grafische Batterie (ohne %)",
|
||||
"display-mode-icon-always": "Symbol - Immer % anzeigen",
|
||||
"display-mode-icon-hover": "Symbol - Beim Hover anzeigen",
|
||||
"display-mode-icon-only": "Nur Symbol",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Battery device",
|
||||
"display-mode-description": "Choose how the battery is displayed in the bar.",
|
||||
"display-mode-graphic": "Graphical battery",
|
||||
"display-mode-graphic-clean": "Graphical battery (no %)",
|
||||
"display-mode-icon-always": "Icon - Always show %",
|
||||
"display-mode-icon-hover": "Icon - Show on hover",
|
||||
"display-mode-icon-only": "Icon only",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Dispositivo de batería",
|
||||
"display-mode-description": "Elige cómo se muestra la batería en la barra.",
|
||||
"display-mode-graphic": "Batería gráfica",
|
||||
"display-mode-graphic-clean": "Batería gráfica (sin %)",
|
||||
"display-mode-icon-always": "Icono - Siempre mostrar %",
|
||||
"display-mode-icon-hover": "Icono - Mostrar al pasar",
|
||||
"display-mode-icon-only": "Solo icono",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Dispositif à pile",
|
||||
"display-mode-description": "Choisissez comment la batterie est affichée dans la barre.",
|
||||
"display-mode-graphic": "Batterie graphique",
|
||||
"display-mode-graphic-clean": "Batterie graphique (sans %)",
|
||||
"display-mode-icon-always": "Icône - Toujours afficher %",
|
||||
"display-mode-icon-hover": "Icône - Afficher au survol",
|
||||
"display-mode-icon-only": "Icône seulement",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Akkumulátor eszköz",
|
||||
"display-mode-description": "Válassza ki, hogyan jelenjen meg az akkumulátor a sávban.",
|
||||
"display-mode-graphic": "Grafikus akkumulátor",
|
||||
"display-mode-graphic-clean": "Grafikus akkumulátor (százalék nélkül)",
|
||||
"display-mode-icon-always": "Ikon - Mindig mutassa a %-ot",
|
||||
"display-mode-icon-hover": "Ikon - Rámutatásra megjelenik",
|
||||
"display-mode-icon-only": "Csak ikon",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "バッテリーデバイス",
|
||||
"display-mode-description": "バッテリーをバーにどのように表示するかを選択します。",
|
||||
"display-mode-graphic": "グラフィックバッテリー",
|
||||
"display-mode-graphic-clean": "グラフィカルバッテリー (パーセント表示なし)",
|
||||
"display-mode-icon-always": "アイコン - 常に%を表示",
|
||||
"display-mode-icon-hover": "アイコン - ホバー時に表示",
|
||||
"display-mode-icon-only": "アイコンのみ",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "배터리 장치",
|
||||
"display-mode-description": "배터리가 바에 어떻게 표시될지 선택하세요.",
|
||||
"display-mode-graphic": "그래픽 배터리",
|
||||
"display-mode-graphic-clean": "그래픽 배터리 (퍼센트 없음)",
|
||||
"display-mode-icon-always": "아이콘 - 항상 % 표시",
|
||||
"display-mode-icon-hover": "아이콘 - 호버 시 표시",
|
||||
"display-mode-icon-only": "아이콘만",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Accuapparaat",
|
||||
"display-mode-description": "Kies hoe de batterij wordt weergegeven in de balk.",
|
||||
"display-mode-graphic": "Grafische accu",
|
||||
"display-mode-graphic-clean": "Grafische batterij (geen %)",
|
||||
"display-mode-icon-always": "Pictogram - Altijd % tonen",
|
||||
"display-mode-icon-hover": "Icoon - Tonen bij hover",
|
||||
"display-mode-icon-only": "Alleen pictogram",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Urządzenie baterii",
|
||||
"display-mode-description": "Wybierz, jak bateria jest wyświetlana na pasku.",
|
||||
"display-mode-graphic": "Graficzna bateria",
|
||||
"display-mode-graphic-clean": "Graficzna bateria (bez %)",
|
||||
"display-mode-icon-always": "Ikona - Zawsze pokazuj %",
|
||||
"display-mode-icon-hover": "Ikona - Pokaż po najechaniu",
|
||||
"display-mode-icon-only": "Tylko ikona",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Dispositivo de bateria",
|
||||
"display-mode-description": "Escolha como a bateria é exibida na barra.",
|
||||
"display-mode-graphic": "Bateria gráfica",
|
||||
"display-mode-graphic-clean": "Bateria gráfica (sem %)",
|
||||
"display-mode-icon-always": "Ícone - Sempre mostrar %",
|
||||
"display-mode-icon-hover": "Ícone - Mostrar ao passar",
|
||||
"display-mode-icon-only": "Apenas ícone",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Устройство с батареей",
|
||||
"display-mode-description": "Выберите, как отображается батарея на панели.",
|
||||
"display-mode-graphic": "Графическая батарея",
|
||||
"display-mode-graphic-clean": "Графическая батарея (без %)",
|
||||
"display-mode-icon-always": "Значок - Всегда показывать %",
|
||||
"display-mode-icon-hover": "Иконка - Показать при наведении",
|
||||
"display-mode-icon-only": "Только значок",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Batterienhet",
|
||||
"display-mode-description": "Välj hur batteriet visas i fältet.",
|
||||
"display-mode-graphic": "Grafiskt batteri",
|
||||
"display-mode-graphic-clean": "Grafiskt batteri (ingen %)",
|
||||
"display-mode-icon-always": "Ikon - Visa alltid %",
|
||||
"display-mode-icon-hover": "Ikon - Visa vid hovring",
|
||||
"display-mode-icon-only": "Endast ikon",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Pil cihazı",
|
||||
"display-mode-description": "Pilin çubukta nasıl görüntüleneceğini seçin.",
|
||||
"display-mode-graphic": "Grafik pil",
|
||||
"display-mode-graphic-clean": "Grafik pil (yüzde yok)",
|
||||
"display-mode-icon-always": "Simge - Her zaman % göster",
|
||||
"display-mode-icon-hover": "Simge - Üzerine gelindiğinde göster",
|
||||
"display-mode-icon-only": "Yalnızca simge",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "Пристрій живлення від батареї",
|
||||
"display-mode-description": "Виберіть, як відображається батарея на панелі.",
|
||||
"display-mode-graphic": "Графічна батарея",
|
||||
"display-mode-graphic-clean": "Графічна батарея (без %)",
|
||||
"display-mode-icon-always": "Іконка - Завжди показувати %",
|
||||
"display-mode-icon-hover": "Іконка - Показувати при наведенні",
|
||||
"display-mode-icon-only": "Лише значок",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "电池设备",
|
||||
"display-mode-description": "选择电池在任务栏中的显示方式。",
|
||||
"display-mode-graphic": "图形化电池",
|
||||
"display-mode-graphic-clean": "图形电池(无%)",
|
||||
"display-mode-icon-always": "图标 - 始终显示 %",
|
||||
"display-mode-icon-hover": "图标 - 悬停时显示",
|
||||
"display-mode-icon-only": "仅图标",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"device-label": "電池裝置",
|
||||
"display-mode-description": "選擇電池在工具列中的顯示方式。",
|
||||
"display-mode-graphic": "圖形化電池",
|
||||
"display-mode-graphic-clean": "圖形電池(無%)",
|
||||
"display-mode-icon-always": "圖示 - 始終顯示 %",
|
||||
"display-mode-icon-hover": "圖示 - 懸停時顯示",
|
||||
"display-mode-icon-only": "僅圖示",
|
||||
|
||||
@@ -12,7 +12,7 @@ Item {
|
||||
property string icon: ""
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property var tooltipText: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
|
||||
@@ -13,7 +13,7 @@ Item {
|
||||
property string icon: ""
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property var tooltipText: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
|
||||
@@ -13,7 +13,7 @@ Item {
|
||||
property string icon: ""
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property var tooltipText: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
|
||||
@@ -39,7 +39,7 @@ Item {
|
||||
readonly property real capsuleHeight: Style.getCapsuleHeightForScreen(screenName)
|
||||
|
||||
readonly property string displayMode: widgetSettings.displayMode !== undefined ? widgetSettings.displayMode : widgetMetadata.displayMode
|
||||
readonly property bool useGraphicMode: displayMode === "graphic"
|
||||
readonly property bool useGraphicMode: displayMode === "graphic" || displayMode === "graphic-clean"
|
||||
|
||||
readonly property bool hideIfNotDetected: widgetSettings.hideIfNotDetected !== undefined ? widgetSettings.hideIfNotDetected : widgetMetadata.hideIfNotDetected
|
||||
readonly property bool hideIfIdle: widgetSettings.hideIfIdle !== undefined ? widgetSettings.hideIfIdle : widgetMetadata.hideIfIdle
|
||||
@@ -58,53 +58,58 @@ Item {
|
||||
readonly property string deviceNativePath: widgetSettings.deviceNativePath !== undefined ? widgetSettings.deviceNativePath : widgetMetadata.deviceNativePath
|
||||
readonly property var selectedDevice: BatteryService.isDevicePresent(BatteryService.findDevice(deviceNativePath)) ? BatteryService.findDevice(deviceNativePath) : null
|
||||
|
||||
readonly property string tooltipText: {
|
||||
let lines = [];
|
||||
readonly property var tooltipContent: {
|
||||
if (!isReady || !isPresent) {
|
||||
return I18n.tr("battery.no-battery-detected");
|
||||
}
|
||||
const isInternal = selectedDevice.isLaptopBattery;
|
||||
|
||||
let rows = [];
|
||||
const isInternal = selectedDevice.isLaptopBattery;
|
||||
if (isInternal) {
|
||||
// Show charge percentage
|
||||
lines.push(`${I18n.tr("battery.battery-level")}: ${percent}%`);
|
||||
rows.push([I18n.tr("battery.battery-level"), `${percent}%`]);
|
||||
|
||||
let timeText = BatteryService.getTimeRemainingText(selectedDevice);
|
||||
if (timeText) {
|
||||
lines.push(timeText);
|
||||
const entries = timeText.split(":").map(a => a.trim());
|
||||
rows.push(entries);
|
||||
}
|
||||
|
||||
let rateText = BatteryService.getRateText(selectedDevice);
|
||||
console.log(rateText);
|
||||
if (rateText) {
|
||||
lines.push(rateText);
|
||||
const entries = rateText.split(":").map(a => a.trim());
|
||||
rows.push(entries);
|
||||
}
|
||||
|
||||
// Show battery health if supported (check actual battery, not DisplayDevice)
|
||||
let healthDevice = selectedDevice.healthSupported ? selectedDevice : (BatteryService.laptopBatteries.length > 0 ? BatteryService.laptopBatteries[0] : null);
|
||||
if (healthDevice && healthDevice.healthSupported) {
|
||||
lines.push(`${I18n.tr("battery.battery-health")}: ${Math.round(healthDevice.healthPercentage)}%`);
|
||||
rows.push([I18n.tr("battery.battery-health"), `${Math.round(healthDevice.healthPercentage)}%`]);
|
||||
}
|
||||
} else if (selectedDevice) {
|
||||
// External / Peripheral Device (Phone, Keyboard, Mouse, Gamepad, Headphone etc.)
|
||||
let name = BatteryService.getDeviceName(selectedDevice);
|
||||
lines.push(`${name}: ${percent}%`);
|
||||
rows.push([name, `${percent}%`]);
|
||||
}
|
||||
|
||||
// If we are showing the main laptop battery, append external devices
|
||||
if (isInternal) {
|
||||
var external = BatteryService.bluetoothBatteries;
|
||||
if (external.length > 0) {
|
||||
if (lines.length > 0)
|
||||
lines.push(""); // Separator
|
||||
if (rows.length > 0) {
|
||||
rows.push(["---", "---"]); // Separator
|
||||
}
|
||||
for (var j = 0; j < external.length; j++) {
|
||||
var dev = external[j];
|
||||
var dName = BatteryService.getDeviceName(dev);
|
||||
var dPct = BatteryService.getPercentage(dev);
|
||||
lines.push(`${dName}: ${dPct}%`);
|
||||
rows.push([dName, `${dPct}%`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lines.join("\n");
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
visible: shouldShow
|
||||
@@ -162,7 +167,7 @@ Item {
|
||||
visible: root.useGraphicMode
|
||||
anchors.centerIn: parent
|
||||
baseSize: Style.barFontSize
|
||||
showPercentageText: true
|
||||
showPercentageText: root.displayMode !== "graphic-clean"
|
||||
vertical: root.isBarVertical
|
||||
percentage: root.percent
|
||||
ready: root.isReady
|
||||
@@ -180,11 +185,13 @@ Item {
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onEntered: {
|
||||
if (root.tooltipText) {
|
||||
TooltipService.show(root, root.tooltipText, BarService.getTooltipDirection(root.screen?.name));
|
||||
if (root.tooltipContent) {
|
||||
TooltipService.show(root, root.tooltipContent, BarService.getTooltipDirection(root.screen?.name));
|
||||
}
|
||||
tooltipRefreshTimer.start();
|
||||
}
|
||||
onExited: {
|
||||
tooltipRefreshTimer.stop();
|
||||
TooltipService.hide();
|
||||
}
|
||||
onClicked: mouse => {
|
||||
@@ -196,6 +203,17 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: tooltipRefreshTimer
|
||||
interval: 1000
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (graphicMouseArea.containsMouse) {
|
||||
TooltipService.updateText(root.tooltipContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== ICON MODE ====================
|
||||
|
||||
BarPill {
|
||||
@@ -211,7 +229,7 @@ Item {
|
||||
forceClose: root.displayMode === "icon-only" || !root.isReady
|
||||
customBackgroundColor: root.isCharging ? Color.mPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mError : "transparent")
|
||||
customTextIconColor: root.isCharging ? Color.mOnPrimary : ((root.isLowBattery || root.isCriticalBattery) ? Color.mOnError : "transparent")
|
||||
tooltipText: root.tooltipText
|
||||
tooltipText: root.tooltipContent
|
||||
|
||||
onClicked: openBatteryPanel()
|
||||
onRightClicked: PanelService.showContextMenu(contextMenu, pill, screen)
|
||||
|
||||
@@ -61,6 +61,10 @@ ColumnLayout {
|
||||
"key": "graphic",
|
||||
"name": I18n.tr("bar.battery.display-mode-graphic")
|
||||
},
|
||||
{
|
||||
"key": "graphic-clean",
|
||||
"name": I18n.tr("bar.battery.display-mode-graphic-clean")
|
||||
},
|
||||
{
|
||||
"key": "icon-hover",
|
||||
"name": I18n.tr("bar.battery.display-mode-icon-hover")
|
||||
|
||||
@@ -90,7 +90,7 @@ Singleton {
|
||||
"hideWhenIdle": false
|
||||
},
|
||||
"Battery": {
|
||||
"displayMode": "graphic",
|
||||
"displayMode": "graphic-clean",
|
||||
"deviceNativePath": "__default__",
|
||||
"showPowerProfiles": false,
|
||||
"showNoctaliaPerformance": false,
|
||||
|
||||
@@ -27,11 +27,11 @@ Item {
|
||||
property bool showPercentageText: true
|
||||
property bool vertical: false
|
||||
|
||||
// Alternating state icon display (toggles between percentage and icon when charging/plugged)
|
||||
// Alternating state icon display (toggles between percentage and icon when charging)
|
||||
property bool showStateIcon: false
|
||||
|
||||
onHasStateIconChanged: {
|
||||
if (!hasStateIcon)
|
||||
onChargingChanged: {
|
||||
if (!charging)
|
||||
showStateIcon = false;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,9 @@ Item {
|
||||
}
|
||||
|
||||
// Background color for empty portion (semi-transparent)
|
||||
readonly property color emptyColor: Qt.alpha(baseColor, 0.7)
|
||||
readonly property color emptyColor: Qt.alpha(baseColor, 0.66)
|
||||
|
||||
// State icon logic
|
||||
readonly property bool hasStateIcon: (!ready || charging || pluggedIn)
|
||||
readonly property string stateIcon: {
|
||||
if (!ready)
|
||||
return "x";
|
||||
@@ -90,9 +89,9 @@ Item {
|
||||
// Timer to alternate between percentage text and state icon when charging/plugged
|
||||
Timer {
|
||||
id: alternateTimer
|
||||
interval: 3000
|
||||
interval: 5000
|
||||
repeat: true
|
||||
running: root.hasStateIcon && root.ready
|
||||
running: root.charging
|
||||
onTriggered: root.showStateIcon = !root.showStateIcon
|
||||
}
|
||||
|
||||
@@ -148,7 +147,7 @@ Item {
|
||||
NText {
|
||||
id: percentageText
|
||||
visible: opacity > 0
|
||||
opacity: root.showPercentageText && root.ready && !root.showStateIcon ? 1 : 0
|
||||
opacity: root.showPercentageText && root.ready && (root.charging ? !root.showStateIcon : !root.pluggedIn) ? 1 : 0
|
||||
x: batteryBody.x + Style.pixelAlignCenter(bodyBackground.width, width)
|
||||
y: batteryBody.y + bodyBackground.y + Style.pixelAlignCenter(bodyBackground.height, height)
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
@@ -174,7 +173,7 @@ Item {
|
||||
NIcon {
|
||||
id: stateIconOverlay
|
||||
visible: opacity > 0
|
||||
opacity: !root.ready || (root.hasStateIcon && root.showStateIcon) ? 1 : 0
|
||||
opacity: !root.ready || (root.charging ? root.showStateIcon : root.pluggedIn) ? 1 : 0
|
||||
x: batteryBody.x + Style.pixelAlignCenter(bodyBackground.width, width)
|
||||
y: batteryBody.y + bodyBackground.y + Style.pixelAlignCenter(bodyBackground.height, height)
|
||||
icon: root.stateIcon
|
||||
|
||||
Reference in New Issue
Block a user