From bd767f140f9e8fabcb0a2ddef54cc97871f7e7f2 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:17:44 +0100 Subject: [PATCH] hefty: bar: add system info indicator (only battery for now) --- .../topLayer/bar/widgets/HSystemInfo.qml | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemInfo.qml diff --git a/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemInfo.qml b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemInfo.qml new file mode 100644 index 000000000..04970fc64 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemInfo.qml @@ -0,0 +1,224 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell.Services.UPower + +import qs.services as S +import qs.modules.common as C +import qs.modules.common.functions as F +import qs.modules.common.widgets as W +import ".." + +HBarWidgetWithPopout { + id: root + + property bool chargingAndNotFull: S.Battery.isCharging && S.Battery.percentage < 1 + property bool powerSaving: PowerProfiles.profile == PowerProfile.PowerSaver + + popupContentWidth: popupContent.implicitWidth + popupContentHeight: popupContent.implicitHeight + + HBarWidgetContent { + id: contentRoot + vertical: root.vertical + atBottom: root.atBottom + showPopup: root.showPopup + contentImplicitWidth: activeItem.implicitWidth + contentImplicitHeight: activeItem.implicitHeight + onClicked: root.showPopup = !root.showPopup + property var activeItem: vertical ? verticalContent : horizontalContent + + W.FadeLoader { + id: horizontalContent + anchors.fill: parent + shown: !contentRoot.vertical + + sourceComponent: HorizontalSysInfo {} + } + + W.FadeLoader { + id: verticalContent + anchors.fill: parent + shown: contentRoot.vertical + + sourceComponent: HorizontalSysInfo {} + } + + SysInfoPopupContent { + id: popupContent + anchors { + top: root.vertical ? contentRoot.activeItem.top : contentRoot.activeItem.top + topMargin: root.popupContentOffsetY + left: root.vertical ? contentRoot.activeItem.left : contentRoot.activeItem.left + leftMargin: root.popupContentOffsetX + } + + shown: root.showPopup + } + } + + component HorizontalSysInfo: Item { + implicitWidth: row.implicitWidth + row.anchors.leftMargin + row.anchors.rightMargin + implicitHeight: row.implicitHeight + row.anchors.topMargin + row.anchors.bottomMargin + + RowLayout { + id: row + anchors.fill: parent + anchors.leftMargin: root.startSide ? 8 : 6 + anchors.rightMargin: root.endSide ? 0 : -3 + + Battery {} + } + } + + component Battery: Row { + spacing: 1.5 + Layout.fillHeight: true + + W.ClippedProgressBar { + id: batteryProgress + anchors.verticalCenter: parent.verticalCenter + valueBarWidth: 28 + valueBarHeight: 16 + radius: 4 + progressRadius: 0 + value: S.Battery.percentage + highlightColor: (S.Battery.isLow && !S.Battery.isCharging) ? C.Appearance.m3colors.m3error : C.Appearance.colors.colOnSecondaryContainer + font.pixelSize: boltIcon.visible ? 13 : 14 + + Item { + layer.enabled: true + width: batteryProgress.valueBarWidth + height: batteryProgress.valueBarHeight + RowLayout { + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: (parent.height - height) / 2 + } + spacing: 0 + + W.MaterialSymbol { + id: boltIcon + Layout.alignment: Qt.AlignVCenter + Layout.leftMargin: -2 + Layout.rightMargin: -2 + fill: 1 * (text == "bolt") + fillAnimation: null + text: { + if (root.chargingAndNotFull) + return "bolt"; + if (root.powerSaving) + return "nest_eco_leaf"; + return "circle"; + } + iconSize: C.Appearance.font.pixelSize.small + font.weight: Font.DemiBold + visible: root.chargingAndNotFull || root.powerSaving + } + W.VisuallyCenteredStyledText { + Layout.fillHeight: true + font: batteryProgress.font + text: batteryProgress.text + } + } + } + } + Rectangle { + anchors.verticalCenter: parent.verticalCenter + color: batteryProgress.trackColor + topRightRadius: width + bottomRightRadius: width + implicitWidth: 2.5 + implicitHeight: 8 + } + } + + component SysInfoPopupContent: W.ChoreographerGridLayout { + + W.FlyFadeEnterChoreographable { + Layout.fillWidth: true + + RowLayout { + anchors.fill: parent + spacing: 10 + + W.CircularProgress { + implicitSize: 46 + lineWidth: 3 + value: S.Battery.health / 100 + W.MaterialSymbol { + anchors.centerIn: parent + iconSize: 22 + text: { + if (root.chargingAndNotFull) + return "battery_android_plus"; + if (root.powerSaving) + return "energy_savings_leaf"; + return "battery_android_full"; + } + } + } + ColumnLayout { + Layout.fillWidth: true + spacing: 0 + RowLayout { + visible: S.Battery.knownEnergyRate + Layout.fillWidth: true + spacing: 4 + W.StyledText { + Layout.alignment: Qt.AlignBaseline + text: F.DateUtils.formatDuration(S.Battery.isCharging ? S.Battery.timeToFull : S.Battery.timeToEmpty) + font.pixelSize: C.Appearance.font.pixelSize.title + } + W.StyledText { + Layout.alignment: Qt.AlignBaseline + text: S.Battery.isCharging ? S.Translation.tr("to full") : S.Translation.tr("remaining") + } + } + RowLayout { + Layout.fillWidth: true + StatWithIcon { + visible: S.Battery.knownEnergyRate + Layout.fillWidth: true + icon: "bolt" + value: `${S.Battery.energyRate.toFixed(2)}W` + } + StatWithIcon { + Layout.fillWidth: true + icon: "heart_check" + value: `${(S.Battery.health).toFixed(1)}%` + } + } + } + } + } + } + + component StatWithIcon: Item { + id: statItem + required property string icon + required property string value + implicitWidth: statRow.implicitWidth + implicitHeight: statRow.implicitHeight + RowLayout { + id: statRow + anchors.fill: parent + spacing: 4 + W.MaterialSymbol { + Layout.fillWidth: false + Layout.alignment: Qt.AlignVCenter + text: statItem.icon + } + W.VisuallyCenteredStyledText { + Layout.fillWidth: false + Layout.fillHeight: true + text: statItem.value + } + Item { + Layout.fillWidth: true + } + } + } +}