import qs.config import qs.custom import qs.services import qs.util import QtQuick import QtQuick.Layouts ColumnLayout { id: root function displayTemp(temp: real): string { return `${Math.ceil(Config.services.useFahrenheit ? temp * 1.8 + 32 : temp)}°${Config.services.useFahrenheit ? "F" : "C"}`; } readonly property int padding: 20 spacing: 28 Component.onCompleted: SystemUsage.refCount++; Component.onDestruction: SystemUsage.refCount--; Resource { Layout.alignment: Qt.AlignHCenter Layout.topMargin: root.padding Layout.leftMargin: root.padding Layout.rightMargin: root.padding value1: SystemUsage.gpuPerc label1: `${Math.round(SystemUsage.gpuPerc * 100)}%` sublabel1: qsTr("GPU Usage") value2: Math.min(1, SystemUsage.gpuTemp / 90) label2: root.displayTemp(SystemUsage.gpuTemp) sublabel2: qsTr("Temp") warning2: value2 > 0.8 } Resource { Layout.alignment: Qt.AlignHCenter Layout.leftMargin: root.padding Layout.rightMargin: root.padding primary: true value1: SystemUsage.cpuPerc label1: `${Math.round(SystemUsage.cpuPerc * 100)}%` sublabel1: qsTr("CPU Usage") value2: Math.min(1, SystemUsage.cpuTemp / 90) label2: root.displayTemp(SystemUsage.cpuTemp) sublabel2: qsTr("Temp") warning2: value2 > 0.8 } Resource { Layout.alignment: Qt.AlignHCenter Layout.leftMargin: root.padding Layout.rightMargin: root.padding Layout.bottomMargin: root.padding value1: SystemUsage.memPerc label1: { const fmt = SystemUsage.formatKib(SystemUsage.memUsed); return `${+fmt.value.toFixed(1)}${fmt.unit}`; } sublabel1: qsTr("Memory") value2: SystemUsage.storagePerc label2: { const fmt = SystemUsage.formatKib(SystemUsage.storageUsed); return `${Math.floor(fmt.value)}${fmt.unit}`; } sublabel2: qsTr("Storage") } component Resource: Item { id: res required property real value1 required property string label1 required property string sublabel1 property bool warning1: value1 > 0.9 required property real value2 required property string label2 required property string sublabel2 property bool warning2: value2 > 0.9 property bool primary readonly property real primaryMult: primary ? 1.2 : 1 readonly property real thickness: 10 * primaryMult property color fg1: warning1 ? Config.colors.error : Color.mute(Config.colors.performance) property color fg2: warning2 ? Config.colors.error : Color.mute(Config.colors.performance, 1.5, 1.6) property color bg1: Qt.alpha(warning1 ? Config.colors.error : Config.colors.performance, 0.1) property color bg2: Qt.alpha(warning2 ? Config.colors.error : Config.colors.performance, 0.05) implicitWidth: implicitHeight implicitHeight: 175 * primaryMult onValue1Changed: canvas.requestPaint() onValue2Changed: canvas.requestPaint() onFg1Changed: canvas.requestPaint() onFg2Changed: canvas.requestPaint() onBg1Changed: canvas.requestPaint() onBg2Changed: canvas.requestPaint() Column { anchors.centerIn: parent readonly property color color: res.warning1 ? Color.mute(Config.colors.error, 1.2, 1.1) : res.value1 === 0 ? Config.colors.inactive : Config.colors.primary CustomText { anchors.horizontalCenter: parent.horizontalCenter text: res.label1 color: parent.color font.pointSize: Config.font.size.largest * res.primaryMult } CustomText { anchors.horizontalCenter: parent.horizontalCenter text: res.sublabel1 color: parent.color font.pointSize: Config.font.size.smaller * res.primaryMult } } Column { anchors.horizontalCenter: parent.right anchors.top: parent.verticalCenter anchors.horizontalCenterOffset: -res.thickness / 2 anchors.topMargin: res.thickness / 2 + 5 readonly property color color: res.warning2 ? Color.mute(Config.colors.error, 1.2, 1.1) : res.value2 === 0 ? Config.colors.inactive : Config.colors.primary CustomText { anchors.horizontalCenter: parent.horizontalCenter text: res.label2 color: parent.color font.pointSize: Config.font.size.smaller * res.primaryMult } CustomText { anchors.horizontalCenter: parent.horizontalCenter text: res.sublabel2 color: parent.color font.pointSize: Config.font.size.small * res.primaryMult } } Canvas { id: canvas readonly property real centerX: width / 2 readonly property real centerY: height / 2 readonly property real arc1Start: degToRad(45) readonly property real arc1End: degToRad(270) readonly property real arc2Start: degToRad(360) readonly property real arc2End: degToRad(280) function degToRad(deg: int): real { return deg * Math.PI / 180; } anchors.fill: parent onPaint: { const ctx = getContext("2d"); ctx.reset(); ctx.lineWidth = res.thickness; ctx.lineCap = "round"; const radius = (Math.min(width, height) - ctx.lineWidth) / 2; const cx = centerX; const cy = centerY; const a1s = arc1Start; const a1e = arc1End; const a2s = arc2Start; const a2e = arc2End; ctx.beginPath(); ctx.arc(cx, cy, radius, a1s, a1e, false); ctx.strokeStyle = res.bg1; ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, radius, a1s, (a1e - a1s) * res.value1 + a1s, false); ctx.strokeStyle = res.fg1; ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, radius, a2s, a2e, true); ctx.strokeStyle = res.bg2; ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, radius, a2s, (a2e - a2s) * res.value2 + a2s, true); ctx.strokeStyle = res.fg2; ctx.stroke(); } } Behavior on value1 { Anim {} } Behavior on value2 { Anim {} } Behavior on fg1 { CAnim {} } Behavior on fg2 { CAnim {} } Behavior on bg1 { CAnim {} } Behavior on bg2 { CAnim {} } } }