feat: improve dash perf cpu/gpu cards

Also separate out into multiple files
This commit is contained in:
2 * r + 2 * t 2026-04-25 17:51:36 +10:00
parent b6b3514852
commit bb573ea971
4 changed files with 164 additions and 152 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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()
}
}
}

View file

@ -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)