From a5eb2f0ae6f0827ecde6f6bdeda119ad20e77531 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 Aug 2025 21:40:29 +0700 Subject: [PATCH] bar: battery: shamshung pill style --- .../ii/modules/bar/BatteryIndicator.qml | 91 +++++++------------ .../common/widgets/ClippedProgressBar.qml | 80 ++++++++++++++++ 2 files changed, 112 insertions(+), 59 deletions(-) create mode 100644 .config/quickshell/ii/modules/common/widgets/ClippedProgressBar.qml diff --git a/.config/quickshell/ii/modules/bar/BatteryIndicator.qml b/.config/quickshell/ii/modules/bar/BatteryIndicator.qml index 1e2153eb..49897c4e 100644 --- a/.config/quickshell/ii/modules/bar/BatteryIndicator.qml +++ b/.config/quickshell/ii/modules/bar/BatteryIndicator.qml @@ -13,8 +13,6 @@ MouseArea { readonly property bool isPluggedIn: Battery.isPluggedIn readonly property real percentage: Battery.percentage readonly property bool isLow: percentage <= Config.options.battery.low / 100 - readonly property color batteryLowBackground: Appearance.m3colors.darkmode ? Appearance.m3colors.m3error : Appearance.m3colors.m3errorContainer - readonly property color batteryLowOnBackground: Appearance.m3colors.darkmode ? Appearance.m3colors.m3errorContainer : Appearance.m3colors.m3error implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2 implicitHeight: 32 @@ -27,69 +25,44 @@ MouseArea { spacing: 4 anchors.centerIn: parent - Rectangle { - implicitWidth: (isCharging ? (boltIconLoader?.item?.width ?? 0) : 0) - - Behavior on implicitWidth { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - } - - StyledText { - Layout.alignment: Qt.AlignVCenter - color: Appearance.colors.colOnLayer1 - text: `${Math.round(percentage * 100)}` - } - - CircularProgress { - enableAnimation: false - Layout.alignment: Qt.AlignVCenter - lineWidth: 2 + ClippedProgressBar { + id: batteryProgress value: percentage - implicitSize: 26 - colSecondary: (isLow && !isCharging) ? batteryLowBackground : Appearance.colors.colSecondaryContainer - colPrimary: (isLow && !isCharging) ? batteryLowOnBackground : Appearance.m3colors.m3onSecondaryContainer - fill: (isLow && !isCharging) + highlightColor: (isLow && !isCharging) ? Appearance.m3colors.m3error : Appearance.m3colors.m3onSecondaryContainer - MaterialSymbol { + Item { anchors.centerIn: parent - fill: 1 - text: "battery_android_full" - iconSize: Appearance.font.pixelSize.normal - color: (isLow && !isCharging) ? batteryLowOnBackground : Appearance.m3colors.m3onSecondaryContainer - } - } - } + width: batteryProgress.valueBarWidth + height: batteryProgress.valueBarHeight - Loader { - id: boltIconLoader - active: true - anchors.left: rowLayout.left - anchors.verticalCenter: rowLayout.verticalCenter + RowLayout { + anchors.centerIn: parent + spacing: 0 - Connections { - target: root - function onIsChargingChanged() { - if (isCharging) - boltIconLoader.active = true; - } - } + MaterialSymbol { + id: boltIcon + Layout.alignment: Qt.AlignVCenter + Layout.leftMargin: -2 + Layout.rightMargin: -2 + fill: 1 + text: "bolt" + iconSize: Appearance.font.pixelSize.smaller + visible: isCharging && percentage < 1 + onVisibleChanged: { + if (!visible) + boltIconLoader.active = false; + } - sourceComponent: MaterialSymbol { - id: boltIcon - - text: "bolt" - iconSize: Appearance.font.pixelSize.large - color: Appearance.m3colors.m3onSecondaryContainer - visible: opacity > 0 // Only show when charging - opacity: isCharging ? 1 : 0 // Keep opacity for visibility - onVisibleChanged: { - if (!visible) - boltIconLoader.active = false; - } - - Behavior on opacity { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) + Behavior on opacity { + animation: Appearance.animation.elementMove.numberAnimation.createObject(this) + } + } + StyledText { + Layout.alignment: Qt.AlignVCenter + font: batteryProgress.font + text: batteryProgress.text + } + } } } } diff --git a/.config/quickshell/ii/modules/common/widgets/ClippedProgressBar.qml b/.config/quickshell/ii/modules/common/widgets/ClippedProgressBar.qml new file mode 100644 index 00000000..d5191b19 --- /dev/null +++ b/.config/quickshell/ii/modules/common/widgets/ClippedProgressBar.qml @@ -0,0 +1,80 @@ +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.common.widgets +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Widgets +import Qt5Compat.GraphicalEffects + +/** + * A progress bar with both ends rounded and text acts as clipping like OneUI 7's battery indicator. + */ +ProgressBar { + id: root + property real valueBarWidth: 30 + property real valueBarHeight: 18 + property color highlightColor: Appearance?.colors.colPrimary ?? "#685496" + property color trackColor: ColorUtils.transparentize(highlightColor, 0.3) ?? "#F1D3F9" + property alias radius: contentItem.radius + property string text + default property Item textMask: Item { + width: valueBarWidth + height: valueBarHeight + StyledText { + anchors.centerIn: parent + font: root.font + text: root.text + } + } + + text: Math.round(value * 100) + font { + pixelSize: 13 + weight: text.length > 2 ? Font.Medium : Font.DemiBold + } + + background: Item { + implicitHeight: valueBarHeight + implicitWidth: valueBarWidth + } + + contentItem: Rectangle { + id: contentItem + anchors.fill: parent + radius: 9999 + color: root.trackColor + visible: false + + Rectangle { + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + } + width: parent.width * root.visualPosition + color: root.highlightColor + } + } + + OpacityMask { + id: roundingMask + visible: false + anchors.fill: parent + source: contentItem + maskSource: Rectangle { + width: contentItem.width + height: contentItem.height + radius: contentItem.radius + } + } + + OpacityMask { + anchors.fill: parent + source: roundingMask + invert: true + maskSource: root.textMask + } +}