diff --git a/modules/dashboard/Performance.qml b/modules/dashboard/Performance.qml index cb07d170..7bc06a9e 100644 --- a/modules/dashboard/Performance.qml +++ b/modules/dashboard/Performance.qml @@ -1,10 +1,8 @@ import "performance" import QtQuick -import QtQuick.Controls import QtQuick.Layouts import Quickshell.Services.UPower import Caelestia.Config -import Caelestia.Internal import Caelestia.Services import qs.components import qs.services @@ -12,27 +10,17 @@ import qs.services Item { id: root - readonly property int minWidth: 400 + 400 + Tokens.spacing.medium + 120 + Tokens.padding.extraLargeIncreased + implicitWidth: placeholder.active ? Tokens.sizes.dashboard.perfPlaceholderWidth : content.implicitWidth + implicitHeight: placeholder.active ? placeholder.implicitHeight + Tokens.padding.extraLarge * 2 : content.implicitHeight - function displayTemp(temp: real): string { - return `${Math.ceil(GlobalConfig.services.useFahrenheitPerformance ? temp * 1.8 + 32 : temp)}°${GlobalConfig.services.useFahrenheitPerformance ? "F" : "C"}`; - } - - implicitWidth: Math.max(minWidth, content.implicitWidth) - implicitHeight: placeholder.visible ? placeholder.height : content.implicitHeight - - StyledRect { + Loader { id: placeholder anchors.centerIn: parent - width: 400 - height: 350 - radius: Tokens.rounding.extraLarge - color: Colours.tPalette.m3surfaceContainer - visible: !Config.dashboard.performance.showCpu && !(Config.dashboard.performance.showGpu && Gpu.type !== Gpu.None) && !Config.dashboard.performance.showMemory && !Config.dashboard.performance.showStorage && !Config.dashboard.performance.showNetwork && !(UPower.displayDevice.isLaptopBattery && Config.dashboard.performance.showBattery) + active: !Config.dashboard.performance.showCpu && !(Config.dashboard.performance.showGpu && Gpu.type !== Gpu.None) && !Config.dashboard.performance.showMemory && !Config.dashboard.performance.showStorage && !Config.dashboard.performance.showNetwork && !(UPower.displayDevice.isLaptopBattery && Config.dashboard.performance.showBattery) + asynchronous: true - ColumnLayout { - anchors.centerIn: parent + sourceComponent: ColumnLayout { spacing: Tokens.spacing.medium MaterialIcon { @@ -43,15 +31,16 @@ Item { } StyledText { + Layout.topMargin: -Tokens.spacing.small Layout.alignment: Qt.AlignHCenter text: qsTr("No widgets enabled") - font: Tokens.font.body.large + font: Tokens.font.title.large color: Colours.palette.m3onSurface } StyledText { Layout.alignment: Qt.AlignHCenter - text: qsTr("Enable widgets in dashboard settings") + text: qsTr("Enable widgets in the dashboard settings") font: Tokens.font.body.small color: Colours.palette.m3onSurfaceVariant } @@ -64,7 +53,7 @@ Item { anchors.left: parent.left anchors.right: parent.right spacing: Tokens.spacing.medium - visible: !placeholder.visible + visible: !placeholder.active ServiceRef { service: root.Config.dashboard.performance.showCpu ? Cpu : null @@ -132,127 +121,8 @@ Item { } BatteryTank { - Layout.preferredWidth: 120 - Layout.preferredHeight: mainColumn.implicitHeight + Layout.fillHeight: true visible: UPower.displayDevice.isLaptopBattery && Config.dashboard.performance.showBattery } } - - component BatteryTank: StyledClippingRect { - id: batteryTank - - property real percentage: UPower.displayDevice.percentage - property bool isCharging: UPower.displayDevice.state === UPowerDeviceState.Charging - property color accentColor: Colours.palette.m3primary - property real animatedPercentage: 0 - - color: Colours.tPalette.m3surfaceContainer - radius: Tokens.rounding.extraLarge - Component.onCompleted: animatedPercentage = percentage - onPercentageChanged: animatedPercentage = percentage - - // Background Fill - StyledRect { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: parent.height * batteryTank.animatedPercentage - color: Qt.alpha(batteryTank.accentColor, 0.15) - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: Tokens.padding.large - spacing: Tokens.spacing.small - - // Header Section - ColumnLayout { - Layout.fillWidth: true - spacing: Tokens.spacing.small - - MaterialIcon { - text: { - if (!UPower.displayDevice.isLaptopBattery) { - if (PowerProfiles.profile === PowerProfile.PowerSaver) - return "energy_savings_leaf"; - - if (PowerProfiles.profile === PowerProfile.Performance) - return "rocket_launch"; - - return "balance"; - } - if (UPower.displayDevice.state === UPowerDeviceState.FullyCharged) - return "battery_full"; - - const perc = UPower.displayDevice.percentage; - const charging = [UPowerDeviceState.Charging, UPowerDeviceState.PendingCharge].includes(UPower.displayDevice.state); - if (perc >= 0.99) - return "battery_full"; - - let level = Math.floor(perc * 7); - if (charging && (level === 4 || level === 1)) - level--; - - return charging ? `battery_charging_${(level + 3) * 10}` : `battery_${level}_bar`; - } - fontStyle: Tokens.font.icon.large - color: batteryTank.accentColor - } - - StyledText { - Layout.fillWidth: true - text: qsTr("Battery") - font: Tokens.font.body.medium - color: Colours.palette.m3onSurface - } - } - - Item { - Layout.fillHeight: true - } - - // Bottom Info Section - ColumnLayout { - Layout.fillWidth: true - spacing: -4 - - StyledText { - Layout.alignment: Qt.AlignRight - text: `${Math.round(batteryTank.percentage * 100)}%` - font: Tokens.font.body.builders.large.size(28).weight(Font.Medium).build() - color: batteryTank.accentColor - } - - StyledText { - Layout.alignment: Qt.AlignRight - text: { - if (UPower.displayDevice.state === UPowerDeviceState.FullyCharged) - return qsTr("Full"); - - if (batteryTank.isCharging) - return qsTr("Charging"); - - const s = UPower.displayDevice.timeToEmpty; - if (s === 0) - return qsTr("..."); - - const hr = Math.floor(s / 3600); - const min = Math.floor((s % 3600) / 60); - if (hr > 0) - return `${hr}h ${min}m`; - - return `${min}m`; - } - font: Tokens.font.body.small - color: Colours.palette.m3onSurfaceVariant - } - } - } - - Behavior on animatedPercentage { - Anim { - type: Anim.StandardLarge - } - } - } } diff --git a/modules/dashboard/performance/BatteryTank.qml b/modules/dashboard/performance/BatteryTank.qml new file mode 100644 index 00000000..1478af65 --- /dev/null +++ b/modules/dashboard/performance/BatteryTank.qml @@ -0,0 +1,145 @@ +import QtQuick +import QtQuick.Layouts +import Quickshell.Services.UPower +import Caelestia.Config +import Caelestia.Services +import qs.components +import qs.services + +StyledClippingRect { + id: root + + color: Colours.palette.m3secondaryContainer + radius: Tokens.rounding.large + + implicitWidth: Config.dashboard.performance.showCpu || (Config.dashboard.performance.showGpu && Gpu.type !== Gpu.None) || Config.dashboard.performance.showStorage || Config.dashboard.performance.showMemory ? Tokens.sizes.dashboard.perfBattWidth : Tokens.sizes.dashboard.perfBattWidthSingle + implicitHeight: Tokens.sizes.dashboard.perfBattHeight + + Contents { + id: layout + + anchors.fill: parent + anchors.margins: Tokens.padding.medium + + accentColour: Colours.palette.m3primary + textColour: Colours.palette.m3onSurface + subTextColour: Colours.palette.m3onSurfaceVariant + } + + StyledRect { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + implicitHeight: parent.height * UPower.displayDevice.percentage + + color: Colours.palette.m3secondary + radius: Tokens.rounding.extraSmall + clip: true + + Behavior on implicitHeight { + Anim {} + } + + Contents { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: layout.anchors.margins + height: layout.height + + accentColour: Colours.palette.m3primaryContainer + textColour: Colours.palette.m3onSecondary + subTextColour: Colours.palette.m3secondaryContainer + } + } + + component Contents: ColumnLayout { + id: contents + + required property color accentColour + required property color textColour + required property color subTextColour + readonly property bool charging: [UPowerDeviceState.Charging, UPowerDeviceState.FullyCharged, UPowerDeviceState.PendingCharge].includes(UPower.displayDevice.state) + + spacing: 0 + + MaterialIcon { + Layout.leftMargin: -Tokens.padding.extraSmall + text: "battery_full" + color: contents.accentColour + fontStyle: Tokens.font.icon.large + } + + StyledText { + Layout.fillWidth: true + text: qsTr("Battery") + color: contents.textColour + font: Tokens.font.body.medium + } + + Item { + Layout.fillHeight: true + } + + StyledText { + Layout.alignment: Qt.AlignRight + text: { + if (UPower.displayDevice.state === UPowerDeviceState.FullyCharged) + return qsTr("Full"); + + if (contents.charging) + return qsTr("Charging"); + + const s = UPower.displayDevice.timeToEmpty; + if (s === 0) + return qsTr("..."); + + const hr = Math.floor(s / 3600); + const min = Math.floor((s % 3600) / 60); + if (hr > 0) + return `${hr}h ${min}m`; + + return `${min}m`; + } + color: contents.subTextColour + font: Tokens.font.body.small + animate: true + } + + RowLayout { + Layout.topMargin: -Tokens.padding.extraSmall + Layout.bottomMargin: -Tokens.padding.small + Layout.rightMargin: -Tokens.padding.extraSmall + Layout.alignment: Qt.AlignRight + spacing: Tokens.spacing.extraSmall + + MaterialIcon { + text: "bolt" + color: contents.accentColour + fontStyle: Tokens.font.icon.large + fill: 1 + + scale: contents.charging ? 1 : 0 + opacity: contents.charging ? 1 : 0 + + Behavior on scale { + Anim { + type: Anim.FastSpatial + } + } + + Behavior on opacity { + Anim { + type: Anim.FastEffects + } + } + } + + StyledText { + text: `${Math.round(UPower.displayDevice.percentage * 100)}%` + color: contents.accentColour + font: Tokens.font.headline.medium + } + } + } +} diff --git a/plugin/src/Caelestia/Config/tokens.hpp b/plugin/src/Caelestia/Config/tokens.hpp index 119d7c80..381897f0 100644 --- a/plugin/src/Caelestia/Config/tokens.hpp +++ b/plugin/src/Caelestia/Config/tokens.hpp @@ -192,8 +192,12 @@ class DashboardTokens : public ConfigObject { CONFIG_PROPERTY(int, perfHeroCardWidth, 400) CONFIG_PROPERTY(int, perfUsageShapeSize, 100) CONFIG_PROPERTY(int, perfStorageTextWidth, 160) - CONFIG_PROPERTY(int, perfNetworkCardWidth, 280) + CONFIG_PROPERTY(int, perfNetworkCardWidth, 390) CONFIG_PROPERTY(int, perfNetworkCardHeight, 220) + CONFIG_PROPERTY(int, perfBattWidth, 150) + CONFIG_PROPERTY(int, perfBattWidthSingle, 400) + CONFIG_PROPERTY(int, perfBattHeight, 160) + CONFIG_PROPERTY(int, perfPlaceholderWidth, 700) public: explicit DashboardTokens(QObject* parent = nullptr)