letsss GOOO
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: widget
|
||||
|
||||
readonly property var activeModules: ["system", "cpu", "memory", "network", "disk", "diskmounts"]
|
||||
readonly property var rootMount: {
|
||||
const mounts = DgopService.diskMounts || [];
|
||||
return mounts.find(mount => mount.mount === "/") || mounts[0] || null;
|
||||
}
|
||||
readonly property real diskPercent: {
|
||||
if (!rootMount || !rootMount.percent)
|
||||
return 0;
|
||||
|
||||
return parseFloat(String(rootMount.percent).replace("%", "")) || 0;
|
||||
}
|
||||
|
||||
function formatRate(bytesPerSecond) {
|
||||
const value = bytesPerSecond || 0;
|
||||
if (value < 1024)
|
||||
return value.toFixed(0) + " B/s";
|
||||
if (value < 1024 * 1024)
|
||||
return (value / 1024).toFixed(0) + " K/s";
|
||||
if (value < 1024 * 1024 * 1024)
|
||||
return (value / (1024 * 1024)).toFixed(1) + " M/s";
|
||||
return (value / (1024 * 1024 * 1024)).toFixed(1) + " G/s";
|
||||
}
|
||||
|
||||
function formatGiB(megabytes) {
|
||||
return ((megabytes || 0) / 1024).toFixed(1) + " GiB";
|
||||
}
|
||||
|
||||
// Stats only get polled while this widget exists.
|
||||
Component.onCompleted: DgopService.addRef(widget.activeModules)
|
||||
Component.onDestruction: DgopService.removeRef(widget.activeModules)
|
||||
|
||||
component StatTile: Rectangle {
|
||||
id: tile
|
||||
|
||||
property string icon: ""
|
||||
property string label: ""
|
||||
property string value: ""
|
||||
property string detail: ""
|
||||
property real fraction: 0
|
||||
property color accent: Theme.primary
|
||||
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceLight, Theme.popupTransparency)
|
||||
border.color: Theme.outlineLight
|
||||
border.width: Theme.layerOutlineWidth
|
||||
|
||||
DankIcon {
|
||||
id: tileIcon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.spacingM
|
||||
name: tile.icon
|
||||
size: Theme.iconSize - 6
|
||||
color: tile.accent
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.left: tileIcon.right
|
||||
anchors.leftMargin: Theme.spacingXS
|
||||
anchors.verticalCenter: tileIcon.verticalCenter
|
||||
text: tile.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: tileValue
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: tileIcon.verticalCenter
|
||||
text: tile.value
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: tileDetail
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.bottom: tileTrack.top
|
||||
anchors.bottomMargin: Theme.spacingXS
|
||||
text: tile.detail
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: tileTrack
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.bottomMargin: Theme.spacingM
|
||||
height: 5
|
||||
radius: height / 2
|
||||
color: Theme.withAlpha(Theme.outline, 0.4)
|
||||
|
||||
Rectangle {
|
||||
width: parent.width * Math.max(0, Math.min(1, tile.fraction))
|
||||
height: parent.height
|
||||
radius: parent.radius
|
||||
color: tile.accent
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Grid {
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
rowSpacing: Theme.spacingS
|
||||
columnSpacing: Theme.spacingS
|
||||
|
||||
readonly property real tileWidth: (width - columnSpacing) / 2
|
||||
readonly property real tileHeight: (height - rowSpacing) / 2
|
||||
|
||||
StatTile {
|
||||
width: parent.tileWidth
|
||||
height: parent.tileHeight
|
||||
icon: "memory"
|
||||
label: "CPU"
|
||||
value: Math.round(DgopService.cpuUsage || 0) + "%"
|
||||
detail: DgopService.cpuTemperature > 0 ? DgopService.cpuTemperature.toFixed(0) + "°C" : (DgopService.cpuCores + " cores")
|
||||
fraction: (DgopService.cpuUsage || 0) / 100
|
||||
accent: DgopService.cpuUsage > 85 ? Theme.error : (DgopService.cpuUsage > 60 ? Theme.warning : Theme.primary)
|
||||
}
|
||||
|
||||
StatTile {
|
||||
width: parent.tileWidth
|
||||
height: parent.tileHeight
|
||||
icon: "developer_board"
|
||||
label: "Memory"
|
||||
value: Math.round(DgopService.memoryUsage || 0) + "%"
|
||||
detail: widget.formatGiB(DgopService.usedMemoryMB) + " / " + widget.formatGiB(DgopService.totalMemoryMB)
|
||||
fraction: (DgopService.memoryUsage || 0) / 100
|
||||
accent: DgopService.memoryUsage > 85 ? Theme.error : (DgopService.memoryUsage > 60 ? Theme.warning : Theme.primary)
|
||||
}
|
||||
|
||||
StatTile {
|
||||
width: parent.tileWidth
|
||||
height: parent.tileHeight
|
||||
icon: "swap_vert"
|
||||
label: "Network"
|
||||
value: "↓ " + widget.formatRate(DgopService.networkRxRate)
|
||||
detail: "↑ " + widget.formatRate(DgopService.networkTxRate)
|
||||
// Scaled against 100 MiB/s so the bar stays readable on fast links.
|
||||
fraction: Math.min(1, ((DgopService.networkRxRate || 0) + (DgopService.networkTxRate || 0)) / (100 * 1024 * 1024))
|
||||
accent: Theme.primary
|
||||
}
|
||||
|
||||
StatTile {
|
||||
width: parent.tileWidth
|
||||
height: parent.tileHeight
|
||||
icon: "storage"
|
||||
label: widget.rootMount ? widget.rootMount.mount : "Disk"
|
||||
value: Math.round(widget.diskPercent) + "%"
|
||||
detail: "R " + widget.formatRate(DgopService.diskReadRate) + " W " + widget.formatRate(DgopService.diskWriteRate)
|
||||
fraction: widget.diskPercent / 100
|
||||
accent: widget.diskPercent > 90 ? Theme.error : (widget.diskPercent > 75 ? Theme.warning : Theme.primary)
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Theme.spacingL * 2
|
||||
text: "dgop is not available - install it to see system stats."
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
visible: !DgopService.dgopAvailable
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user