diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 8f9cb32..2f411ff 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -127,6 +127,7 @@ Singleton { property bool showBrightness: true property bool showNotificationsHistory: true property bool showTray: true + property bool alwaysShowBatteryPercentage: false property real backgroundOpacity: 1.0 property list monitors: [] } diff --git a/Modules/Bar/Battery.qml b/Modules/Bar/Battery.qml index 69f2a46..edc346a 100644 --- a/Modules/Bar/Battery.qml +++ b/Modules/Bar/Battery.qml @@ -53,6 +53,7 @@ NPill { icon: root.batteryIcon() text: Math.round(root.percent) + "%" textColor: charging ? Color.mPrimary : Color.mOnSurface + forceShown: Settings.data.bar.alwaysShowBatteryPercentage tooltipText: { let lines = [] @@ -76,8 +77,7 @@ NPill { if (root.battery.changeRate !== undefined) { const rate = root.battery.changeRate if (rate > 0) { - lines.push(root.charging ? "Charging rate: " + rate.toFixed(2) + " W" : "Discharging rate: " + rate.toFixed( - 2) + " W") + lines.push(root.charging ? "Charging rate: " + rate.toFixed(2) + " W" : "Discharging rate: " + rate.toFixed(2) + " W") } else if (rate < 0) { lines.push("Discharging rate: " + Math.abs(rate).toFixed(2) + " W") } else { diff --git a/Modules/SettingsPanel/Tabs/BarTab.qml b/Modules/SettingsPanel/Tabs/BarTab.qml index e1db23b..e0bb137 100644 --- a/Modules/SettingsPanel/Tabs/BarTab.qml +++ b/Modules/SettingsPanel/Tabs/BarTab.qml @@ -132,6 +132,15 @@ ColumnLayout { } } + NToggle { + label: "Always show battery percentage" + description: "Show battery percentage at all times (otherwise only when charging or low)." + checked: Settings.data.bar.alwaysShowBatteryPercentage + onToggled: checked => { + Settings.data.bar.alwaysShowBatteryPercentage = checked + } + } + ColumnLayout { spacing: Style.marginXXS * scaling Layout.fillWidth: true diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index 62bc36b..b3739eb 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -16,6 +16,10 @@ Item { property color collapsedIconColor: Color.mOnSurface property real sizeMultiplier: 0.8 property bool autoHide: false + // When true, keep the pill expanded regardless of hover state + property bool forceShown: false + // Effective shown state (true if hovered/animated open or forced) + readonly property bool effectiveShown: forceShown || showPill signal shown signal hidden @@ -35,15 +39,15 @@ Item { readonly property int pillOverlap: iconSize * 0.5 readonly property int maxPillWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap) - width: iconSize + (showPill ? maxPillWidth - pillOverlap : 0) + width: iconSize + (effectiveShown ? maxPillWidth - pillOverlap : 0) height: pillHeight Rectangle { id: pill - width: showPill ? maxPillWidth : 1 + width: effectiveShown ? maxPillWidth : 1 height: pillHeight x: (iconCircle.x + iconCircle.width / 2) - width - opacity: showPill ? Style.opacityFull : Style.opacityNone + opacity: effectiveShown ? Style.opacityFull : Style.opacityNone color: pillColor topLeftRadius: pillHeight * 0.5 bottomLeftRadius: pillHeight * 0.5 @@ -56,7 +60,7 @@ Item { font.pointSize: Style.fontSizeXS * scaling font.weight: Style.fontWeightBold color: textColor - visible: showPill + visible: effectiveShown } Behavior on width { @@ -80,7 +84,8 @@ Item { width: iconSize height: iconSize radius: width * 0.5 - color: showPill ? iconCircleColor : Color.mSurfaceVariant + // When forced shown, match pill background; otherwise use accent when hovered + color: forceShown ? pillColor : (showPill ? iconCircleColor : Color.mSurfaceVariant) anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right @@ -94,7 +99,8 @@ Item { NIcon { text: root.icon font.pointSize: Style.fontSizeM * scaling - color: showPill ? iconTextColor : Color.mOnSurface + // When forced shown, use pill text color; otherwise accent color when hovered + color: forceShown ? textColor : (showPill ? iconTextColor : Color.mOnSurface) anchors.centerIn: parent } } @@ -188,12 +194,16 @@ Item { anchors.fill: parent hoverEnabled: true onEntered: { - showDelayed() + if (!forceShown) { + showDelayed() + } tooltip.show() root.entered() } onExited: { - hide() + if (!forceShown) { + hide() + } tooltip.hide() root.exited() } @@ -216,6 +226,9 @@ Item { } function hide() { + if (forceShown) { + return + } if (showPill) { hideAnim.start() } @@ -231,4 +244,16 @@ Item { delayedHideAnim.restart() } } + + onForceShownChanged: { + if (forceShown) { + // Immediately lock open without animations + showAnim.stop() + hideAnim.stop() + delayedHideAnim.stop() + showPill = true + } else { + hide() + } + } }