152 lines
4.3 KiB
QML
152 lines
4.3 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import "root:/config"
|
|
import "root:/components"
|
|
import "root:/services"
|
|
import "root:/popouts"
|
|
|
|
// Compact CPU / MEM / GPU readout. Each metric is a number over a segmented
|
|
// meter; hovering opens the full gauge cluster.
|
|
BarPill {
|
|
id: root
|
|
|
|
required property var screenRef
|
|
|
|
accent: Theme.heat(Math.max(Sys.cpuUsage, Sys.memPercent))
|
|
|
|
padding: Theme.padM
|
|
implicitWidth: layout.implicitWidth + contentPad * 2
|
|
|
|
onClicked: Actions.openSystemMonitor()
|
|
|
|
Row {
|
|
id: layout
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
spacing: Theme.padM
|
|
|
|
Metric {
|
|
label: "CPU"
|
|
value: Sys.cpuUsage
|
|
readout: Math.round(Sys.cpuUsage) + "%"
|
|
widest: "100%"
|
|
}
|
|
|
|
Divider {}
|
|
|
|
Metric {
|
|
label: "MEM"
|
|
value: Sys.memPercent
|
|
readout: Sys.memUsed.toFixed(1) + "G"
|
|
widest: "88.8G"
|
|
}
|
|
|
|
Divider { visible: Sys.gpuAvailable }
|
|
|
|
Metric {
|
|
visible: Sys.gpuAvailable
|
|
label: "GPU"
|
|
value: Sys.gpuUsage
|
|
readout: Math.round(Sys.gpuUsage) + "%"
|
|
widest: "100%"
|
|
}
|
|
}
|
|
|
|
component Divider: Item {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
implicitWidth: rule.width
|
|
implicitHeight: 18
|
|
|
|
// Sized to hold its own lean — see the note on the bar's divider.
|
|
Skew {
|
|
id: rule
|
|
anchors.centerIn: parent
|
|
width: parent.height * Theme.skew + 1
|
|
height: parent.height
|
|
color: Theme.alpha(Theme.outline, 0.8)
|
|
}
|
|
}
|
|
|
|
// A tiny fixed label makes every number self-describing without turning the
|
|
// compact meter cluster back into three separate cards.
|
|
component Metric: Column {
|
|
id: metric
|
|
|
|
property string label: ""
|
|
property real value: 0
|
|
property string readout: ""
|
|
|
|
// The widest reading this metric will ever show. The number column is
|
|
// sized from this rather than from the live text, because sizing to the
|
|
// live text is what made the whole right-hand group breathe in and out:
|
|
// "9%" and "100%" are ~14px apart in Archivo Black, so every tick of the
|
|
// CPU sampler nudged the metrics, the media pill and the clock sideways.
|
|
// Reserving the maximum costs a few px of blank and buys a bar that
|
|
// never moves.
|
|
property string widest: "100%"
|
|
|
|
readonly property real numberWidth: Math.max(gauge.width, metrics.advanceWidth)
|
|
readonly property real headWidth: labelText.implicitWidth + head.spacing + numberWidth
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 2
|
|
width: Math.max(headWidth, 44)
|
|
|
|
TextMetrics {
|
|
id: metrics
|
|
text: metric.widest
|
|
font: gauge.font
|
|
}
|
|
|
|
Row {
|
|
id: head
|
|
spacing: 4
|
|
|
|
Text {
|
|
id: labelText
|
|
anchors.baseline: gauge.baseline
|
|
text: metric.label
|
|
color: Theme.muted
|
|
font.family: Theme.fontMono
|
|
font.pixelSize: Theme.fsMicro
|
|
font.weight: Font.Bold
|
|
font.letterSpacing: 0.5
|
|
renderType: Text.NativeRendering
|
|
}
|
|
|
|
Text {
|
|
id: gauge
|
|
text: metric.readout
|
|
color: Theme.heat(metric.value)
|
|
font.family: Theme.fontDisplay
|
|
font.pixelSize: Theme.fsBody
|
|
font.weight: Theme.weightDisplay
|
|
font.italic: true
|
|
font.letterSpacing: 0.5
|
|
renderType: Text.NativeRendering
|
|
|
|
Behavior on color {
|
|
ColorAnimation { duration: Theme.durBase }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Ends flush with the reading above it instead of stopping short at a
|
|
// fixed 43px, so each metric reads as one block.
|
|
MeterBar {
|
|
value: metric.value
|
|
segments: 9
|
|
spacing: 2
|
|
height: 5
|
|
width: metric.width
|
|
segmentWidth: (width - 8 * spacing) / 9
|
|
}
|
|
}
|
|
|
|
SysPopout {
|
|
id: popout
|
|
anchorItem: root
|
|
triggerHovered: root.hovered
|
|
}
|
|
}
|