diff --git a/components/controls/StyledProgressBar.qml b/components/controls/StyledProgressBar.qml index 36638de9..399b66fd 100644 --- a/components/controls/StyledProgressBar.qml +++ b/components/controls/StyledProgressBar.qml @@ -26,7 +26,6 @@ ProgressBar { property int waveFrequency: 6 property real waveAmplitude: 0.5 property int waveDuration: 1000 - property bool animateIndeterminate property int indeterminateAnimState: StyledProgressBar.Stopped @@ -46,7 +45,7 @@ ProgressBar { } function updateIAnimState(): void { - if (indeterminate && animateIndeterminate) { + if (indeterminate) { manager.completeEndProgress = 0; indeterminateAnimState = StyledProgressBar.Running; } else if (indeterminateAnimState === StyledProgressBar.Running) { @@ -55,7 +54,6 @@ ProgressBar { } onIndeterminateChanged: updateIAnimState() - onAnimateIndeterminateChanged: updateIAnimState() Component.onCompleted: updateIAnimState() implicitWidth: 200 @@ -63,13 +61,14 @@ ProgressBar { contentItem: Loader { anchors.fill: parent + asynchronous: true sourceComponent: root.indeterminate || root.indeterminateAnimState !== StyledProgressBar.Stopped ? indeterminateComp : determinateComp } LinearIndicatorManager { id: manager - gap: Tokens.spacing.extraSmall + gap: root.Tokens.spacing.extraSmall Anim on progress { running: root.indeterminateAnimState !== StyledProgressBar.Stopped @@ -91,10 +90,6 @@ ProgressBar { } } - Behavior on value { - Anim {} - } - Component { id: determinateComp @@ -109,7 +104,7 @@ ProgressBar { Line { property real implicitSize - Component.onCompleted: implicitSize = Qt.binding(() => parent.width * (1 - root.visualPosition) < parent.height ? parent.height : 4) + Component.onCompleted: implicitSize = Qt.binding(() => parent.width - wave.implicitWidth < parent.height ? parent.height : 4) anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter @@ -131,14 +126,11 @@ ProgressBar { Wave { id: wave - readonly property real targetWidth: parent.width * root.visualPosition - anchors.left: parent.left + Component.onCompleted: implicitWidth = Qt.binding(() => parent.width * root.visualPosition) - Anim on implicitWidth { - running: true - to: wave.targetWidth - onFinished: wave.implicitWidth = Qt.binding(() => wave.targetWidth) + Behavior on implicitWidth { + Anim {} } } } @@ -216,7 +208,7 @@ ProgressBar { implicitHeight: parent.height radius: Tokens.rounding.full - color: root.fgColour + color: root.bgColour } component Wave: WavyLine { diff --git a/modules/dashboard/Performance.qml b/modules/dashboard/Performance.qml index 899503d8..7f341433 100644 --- a/modules/dashboard/Performance.qml +++ b/modules/dashboard/Performance.qml @@ -1,3 +1,4 @@ +import "performance" import QtQuick import QtQuick.Controls import QtQuick.Layouts @@ -82,34 +83,24 @@ Item { HeroCard { Layout.fillWidth: true - Layout.minimumWidth: 400 - Layout.preferredHeight: 150 visible: Config.dashboard.performance.showCpu icon: "memory" - title: SystemUsage.cpuName ? `CPU - ${SystemUsage.cpuName}` : qsTr("CPU") - mainValue: `${Math.round(SystemUsage.cpuPerc * 100)}%` - mainLabel: qsTr("Usage") - secondaryValue: root.displayTemp(SystemUsage.cpuTemp) - secondaryLabel: qsTr("Temp") + label: qsTr("CPU") + subLabel: SystemUsage.cpuName usage: SystemUsage.cpuPerc temperature: SystemUsage.cpuTemp - accentColor: Colours.palette.m3primary + accent: Colours.palette.m3primary } HeroCard { Layout.fillWidth: true - Layout.minimumWidth: 400 - Layout.preferredHeight: 150 visible: Config.dashboard.performance.showGpu && SystemUsage.gpuType !== "NONE" icon: "desktop_windows" - title: SystemUsage.gpuName ? `GPU - ${SystemUsage.gpuName}` : qsTr("GPU") - mainValue: `${Math.round(SystemUsage.gpuPerc * 100)}%` - mainLabel: qsTr("Usage") - secondaryValue: root.displayTemp(SystemUsage.gpuTemp) - secondaryLabel: qsTr("Temp") + label: qsTr("GPU") + subLabel: SystemUsage.gpuName usage: SystemUsage.gpuPerc temperature: SystemUsage.gpuTemp - accentColor: Colours.palette.m3secondary + accent: Colours.palette.m3secondary } } @@ -327,125 +318,6 @@ Item { } } - component HeroCard: StyledClippingRect { - id: heroCard - - property string icon - property string title - property string mainValue - property string mainLabel - property string secondaryValue - property string secondaryLabel - property real usage: 0 - property real temperature: 0 - property color accentColor: Colours.palette.m3primary - readonly property real maxTemp: 100 - readonly property real tempProgress: Math.min(1, Math.max(0, temperature / maxTemp)) - property real animatedUsage: 0 - property real animatedTemp: 0 - - color: Colours.tPalette.m3surfaceContainer - radius: Tokens.rounding.extraLarge - Component.onCompleted: { - animatedUsage = usage; - animatedTemp = tempProgress; - } - onUsageChanged: animatedUsage = usage - onTempProgressChanged: animatedTemp = tempProgress - - StyledRect { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - implicitWidth: parent.width * heroCard.animatedUsage - color: Qt.alpha(heroCard.accentColor, 0.15) - } - - CardHeader { - anchors.left: parent.left - anchors.top: parent.top - anchors.leftMargin: Tokens.padding.large - anchors.topMargin: Math.round(Tokens.padding.large * 1.2) - - width: parent.width - anchors.leftMargin - usageColumn.anchors.rightMargin - usageLabel.width - Tokens.spacing.medium - icon: heroCard.icon - title: heroCard.title - accentColor: heroCard.accentColor - } - - Column { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Math.round(Tokens.padding.large * 1.2) - anchors.bottomMargin: Math.round(Tokens.padding.large * 1.3) - - spacing: Tokens.spacing.small - - Row { - spacing: Tokens.spacing.small - - StyledText { - text: heroCard.secondaryValue - font: Tokens.font.body.builders.medium.weight(Font.Medium).build() - } - - StyledText { - text: heroCard.secondaryLabel - font: Tokens.font.body.small - color: Colours.palette.m3onSurfaceVariant - anchors.baseline: parent.children[0].baseline - } - } - - ProgressBar { - implicitWidth: parent.width * 0.5 - implicitHeight: 6 - value: heroCard.tempProgress - fgColor: heroCard.accentColor - bgColor: Qt.alpha(heroCard.accentColor, 0.2) - } - } - - Column { - id: usageColumn - - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Tokens.padding.large - anchors.rightMargin: 32 - spacing: 0 - - StyledText { - id: usageLabel - - anchors.right: parent.right - text: heroCard.mainLabel - font: Tokens.font.body.medium - color: Colours.palette.m3onSurfaceVariant - } - - StyledText { - anchors.right: parent.right - text: heroCard.mainValue - font: Tokens.font.body.builders.large.size(28).weight(Font.Medium).build() - color: heroCard.accentColor - } - } - - Behavior on animatedUsage { - Anim { - type: Anim.StandardLarge - } - } - - Behavior on animatedTemp { - Anim { - type: Anim.StandardLarge - } - } - } - component GaugeCard: StyledRect { id: gaugeCard diff --git a/modules/dashboard/performance/HeroCard.qml b/modules/dashboard/performance/HeroCard.qml new file mode 100644 index 00000000..a6482b27 --- /dev/null +++ b/modules/dashboard/performance/HeroCard.qml @@ -0,0 +1,147 @@ +import QtQuick +import QtQuick.Layouts +import M3Shapes +import Caelestia.Config +import qs.components +import qs.components.controls +import qs.services + +StyledRect { + id: root + + required property string icon + required property string label + required property string subLabel + required property color accent + required property real usage + required property real temperature + + color: Colours.tPalette.m3surfaceContainer + radius: Tokens.rounding.extraLarge + + implicitWidth: Tokens.sizes.dashboard.perfHeroCardWidth + implicitHeight: Math.max(tempProg.implicitHeight + detailsRow.implicitHeight + Tokens.spacing.large, usageShape.implicitHeight + usageLabel.implicitHeight) + Tokens.padding.large * 2 + + CircularProgress { + id: tempProg + + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: Tokens.padding.large + + fgColour: root.accent + + spacing: Tokens.spacing.extraSmall + strokeWidth: Tokens.padding.extraSmall + implicitSize: Math.max(icon.implicitWidth, icon.implicitHeight) + Tokens.padding.medium * 2 + value: root.usage + + Behavior on value { + Anim {} + } + + MaterialIcon { + id: icon + + anchors.centerIn: parent + text: root.icon + color: root.accent + fontStyle: Tokens.font.icon.medium + } + } + + ColumnLayout { + anchors.left: tempProg.right + anchors.right: parent.right + anchors.verticalCenter: tempProg.verticalCenter + anchors.margins: Tokens.spacing.large + spacing: Tokens.spacing.extraSmall + + StyledText { + text: root.label + font: Tokens.font.title.medium + color: root.accent + } + + StyledText { + Layout.fillWidth: true + text: root.subLabel + font: Tokens.font.body.small + color: Colours.palette.m3onSurfaceVariant + elide: Text.ElideRight + } + } + + ColumnLayout { + id: detailsRow + + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: Tokens.padding.largeIncreased + spacing: Tokens.spacing.extraSmall + + RowLayout { + Layout.leftMargin: -Tokens.padding.extraSmall + spacing: Tokens.spacing.extraSmall + + MaterialIcon { + Layout.topMargin: Math.round(fontInfo.pointSize * 0.08) + text: root.temperature > 90 ? "thermometer_alert" : "thermometer" + color: root.temperature > 90 ? Colours.palette.m3error : root.accent + fontStyle: Tokens.font.icon.medium + fill: 1 + } + + StyledText { + text: Math.round(root.temperature) + (GlobalConfig.services.useFahrenheitPerformance ? "°F" : "°C") + font: Tokens.font.body.builders.medium.build() + } + } + + StyledProgressBar { + value: root.temperature / 100 + implicitHeight: Tokens.padding.small + fgColour: root.accent + } + } + + MaterialShape { + id: usageShape + + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: Tokens.padding.medium + + implicitSize: Tokens.sizes.dashboard.perfUsageShapeSize + color: Colours.palette.m3secondaryContainer + shape: { + if (root.usage >= 0.8) + return MaterialShape.SoftBurst; + if (root.usage >= 0.4) + return MaterialShape.Sunny; + return MaterialShape.Cookie4Sided; + } + + Behavior on color { + CAnim {} + } + + StyledText { + id: usageLabel + + anchors.bottom: parent.top + anchors.horizontalCenter: parent.horizontalCenter + + text: qsTr("Usage") + color: Colours.palette.m3onSurfaceVariant + font: Tokens.font.body.small + } + + StyledText { + anchors.centerIn: parent + text: Math.round(root.usage * 100) + "%" + color: root.accent + font: Tokens.font.headline.builders.small.width(50).build() + } + } +} diff --git a/plugin/src/Caelestia/Config/tokens.hpp b/plugin/src/Caelestia/Config/tokens.hpp index fcd8e3e9..818cf438 100644 --- a/plugin/src/Caelestia/Config/tokens.hpp +++ b/plugin/src/Caelestia/Config/tokens.hpp @@ -189,7 +189,8 @@ class DashboardTokens : public ConfigObject { CONFIG_PROPERTY(int, weatherWidth, 275) CONFIG_PROPERTY(int, mediaCoverArtSize, 150) CONFIG_PROPERTY(int, mediaVisualiserSize, 80) - CONFIG_PROPERTY(int, resourceSize, 200) + CONFIG_PROPERTY(int, perfHeroCardWidth, 400) + CONFIG_PROPERTY(int, perfUsageShapeSize, 100) public: explicit DashboardTokens(QObject* parent = nullptr)