feat: improve lock resource widget

This commit is contained in:
2 * r + 2 * t 2026-06-01 21:10:33 +10:00
parent 58d2232c4a
commit 9665613ef1
3 changed files with 189 additions and 68 deletions

View file

@ -0,0 +1,47 @@
import QtQuick
import QtQuick.Shapes
import qs.components
import qs.services
Shape {
id: root
property color color: Colours.palette.m3surfaceContainer
property int waves: 4
property real amplitude: 3
readonly property real waveHeight: amplitude * 2
preferredRendererType: Shape.CurveRenderer
asynchronous: true
ShapePath {
strokeWidth: 0
strokeColor: "transparent"
fillColor: root.color
PathSvg {
path: {
const w = root.width;
const h = root.height;
const a = root.amplitude;
const n = Math.max(1, root.waves);
const wl = w / n;
const half = wl / 2;
let d = `M 0,${a} `;
for (let i = 0; i < n; ++i) {
const x = i * wl;
d += `Q ${x + half / 2},${-a} ${x + half},${a} `;
d += `Q ${x + half + half / 2},${3 * a} ${x + wl},${a} `;
}
d += `L ${w},${h} L 0,${h} Z`;
return d;
}
}
Behavior on fillColor {
CAnim {}
}
}
}

View file

@ -44,17 +44,8 @@ RowLayout {
Layout.fillWidth: true
spacing: Tokens.spacing.medium
StyledRect {
Resources {
Layout.fillWidth: true
implicitHeight: resources.implicitHeight
topRightRadius: Tokens.rounding.extraLarge
radius: Tokens.rounding.medium
color: Colours.tPalette.m3surfaceContainer
Resources {
id: resources
}
}
StyledRect {

View file

@ -1,22 +1,26 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import M3Shapes
import Caelestia.Config
import Caelestia.Services
import qs.components
import qs.components.controls
import qs.components.effects
import qs.components.widgets
import qs.services
GridLayout {
StyledRect {
id: root
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Tokens.padding.large
readonly property real fontScale: {
const diff = width / 391 - 1; // 391 is the width at 1080 height screen
return 1 + Math.pow(Math.abs(diff), 0.8) * Math.sign(diff);
}
rowSpacing: Tokens.spacing.largeIncreased
columnSpacing: Tokens.spacing.largeIncreased
rows: 2
columns: 2
implicitHeight: layout.implicitHeight + layout.anchors.margins * 2
radius: Tokens.rounding.extraLarge
color: Colours.tPalette.m3surfaceContainer
ServiceRef {
service: Cpu
@ -30,71 +34,150 @@ GridLayout {
service: Storage
}
Resource {
Layout.topMargin: Tokens.padding.large
icon: "memory"
value: Cpu.percentage
colour: Colours.palette.m3primary
RowLayout {
id: layout
anchors.fill: parent
anchors.margins: Tokens.padding.large
spacing: Tokens.spacing.large
Resource {
id: cpu
icon: "memory"
value: Math.round(Cpu.percentage * 100) + "%"
fillValue: Cpu.percentage
colour: Colours.palette.m3primary
shapeColour: Colours.palette.m3primaryContainer
fillColour: Qt.alpha(Colours.palette.m3secondary, 0.3)
shape: MaterialShape.Pentagon
MaterialShape {
x: cpu.mShape.pointAtAngle(45).x - implicitSize / 2 + Tokens.padding.medium
y: cpu.mShape.pointAtAngle(45).y - implicitSize / 2
shape: Cpu.temperature > 90 ? MaterialShape.SoftBurst : MaterialShape.Circle
color: Cpu.temperature > 90 ? Colours.palette.m3errorContainer : Colours.palette.m3secondaryContainer
implicitSize: {
const size = Math.round(tempLabel.implicitHeight * 2);
return size % 2 === 0 ? size : size + 1; // Ensure even size so center works properly
}
Behavior on color {
CAnim {}
}
StyledText {
id: tempLabel
anchors.centerIn: parent
anchors.verticalCenterOffset: Math.round(fontInfo.pointSize * 0.04)
text: {
const temp = Cpu.temperature;
const useF = GlobalConfig.services.useFahrenheitPerformance;
return `${Math.ceil(useF ? temp * 1.8 + 32 : temp)}°${useF ? "F" : "C"}`;
}
color: Cpu.temperature > 90 ? Colours.palette.m3onErrorContainer : Colours.palette.m3secondary
font: Tokens.font.title.builders.medium.scale(cpu.width / 112).width(50).build()
}
}
}
Resource {
icon: "memory_alt"
value: Math.round(Memory.percentage * 100) + "%"
fillValue: Memory.percentage
colour: Colours.palette.m3tertiary
shapeColour: Colours.palette.m3onTertiary
fillColour: Qt.alpha(Colours.palette.m3tertiary, 0.3)
shape: MaterialShape.Slanted
}
Resource {
icon: "hard_disk"
value: Math.round(Storage.percentage * 100) + "%"
fillValue: Storage.percentage
colour: Colours.palette.m3secondary
shapeColour: Colours.palette.m3secondaryContainer
fillColour: Qt.alpha(Colours.palette.m3secondary, 0.4)
shape: MaterialShape.Gem
}
}
Resource {
Layout.topMargin: Tokens.padding.large
icon: "thermostat"
value: Math.min(1, Cpu.temperature / 90)
colour: Colours.palette.m3secondary
}
Resource {
Layout.bottomMargin: Tokens.padding.large
icon: "memory_alt"
value: Memory.percentage
colour: Colours.palette.m3secondary
}
Resource {
Layout.bottomMargin: Tokens.padding.large
icon: "hard_disk"
value: Storage.percentage
colour: Colours.palette.m3tertiary
}
component Resource: StyledRect {
component Resource: Item {
id: res
required property string icon
required property real value
required property string value
required property color colour
required property color shapeColour
property color fillColour
property real fillValue: -1
property alias shape: shape.shape
readonly property alias mShape: shape
Layout.fillWidth: true
implicitHeight: width
color: Colours.layer(Colours.palette.m3surfaceContainerHigh, 2)
radius: Tokens.rounding.extraLarge
CircularProgress {
id: circ
anchors.fill: parent
value: res.value
padding: Tokens.padding.extraExtraLarge
fgColour: res.colour
bgColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 3)
strokeWidth: width < 200 ? Tokens.padding.small : Tokens.padding.medium
Behavior on shapeColour {
CAnim {}
}
MaterialIcon {
id: icon
MaterialShape {
id: shape
anchors.centerIn: parent
text: res.icon
color: res.colour
fontStyle: Tokens.font.icon.size((circ.arcRadius * 0.7) || 1).weight(Font.DemiBold).build()
implicitSize: res.width
color: Qt.alpha(res.shapeColour, 1)
opacity: res.shapeColour.a
layer.enabled: true
}
Behavior on value {
Anim {
type: Anim.StandardLarge
Loader {
id: fillLoader
anchors.fill: shape
active: res.fillValue >= 0
asynchronous: true
layer.enabled: active
layer.effect: Mask {
maskSource: shape
}
sourceComponent: Item {
WavyTopRect {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
implicitHeight: shape.implicitSize * res.fillValue
color: res.fillColour
}
}
}
ColumnLayout {
anchors.centerIn: parent
spacing: -Tokens.spacing.extraSmall
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
text: res.icon
color: Colours.palette.m3secondary
fontStyle: Tokens.font.icon.builders.medium.scale(root.fontScale).build()
}
StyledText {
Layout.alignment: Qt.AlignHCenter
text: res.value
color: res.colour
font: Tokens.font.headline.builders.large.scale(root.fontScale).width(50).build()
}
}
Behavior on fillValue {
Anim {}
}
}
}