mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
404 lines
12 KiB
QML
404 lines
12 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import Quickshell
|
|
import qs.Commons
|
|
import qs.Modules.MainScreen
|
|
import qs.Services.System
|
|
import qs.Services.UI
|
|
import qs.Widgets
|
|
|
|
SmartPanel {
|
|
id: root
|
|
|
|
Component.onCompleted: SystemStatService.registerComponent("panel-systemstats")
|
|
Component.onDestruction: SystemStatService.unregisterComponent("panel-systemstats")
|
|
|
|
preferredWidth: Math.round(440 * Style.uiScaleRatio)
|
|
|
|
panelContent: Item {
|
|
id: panelContent
|
|
property real contentPreferredHeight: mainColumn.implicitHeight + Style.margin2L
|
|
readonly property real cardHeight: 90 * Style.uiScaleRatio
|
|
|
|
// Get diskPath from bar's SystemMonitor widget if available, otherwise use "/"
|
|
readonly property string diskPath: {
|
|
const sysMonWidget = BarService.lookupWidget("SystemMonitor");
|
|
if (sysMonWidget && sysMonWidget.diskPath) {
|
|
return sysMonWidget.diskPath;
|
|
}
|
|
return "/";
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: mainColumn
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginL
|
|
spacing: Style.marginM
|
|
|
|
// HEADER
|
|
NBox {
|
|
Layout.fillWidth: true
|
|
implicitHeight: headerRow.implicitHeight + Style.margin2M
|
|
|
|
RowLayout {
|
|
id: headerRow
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginM
|
|
spacing: Style.marginM
|
|
|
|
NIcon {
|
|
icon: "device-analytics"
|
|
pointSize: Style.fontSizeXXL
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("system-monitor.title")
|
|
pointSize: Style.fontSizeL
|
|
font.weight: Style.fontWeightBold
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
NIconButton {
|
|
icon: "close"
|
|
tooltipText: I18n.tr("common.close")
|
|
baseSize: Style.baseWidgetSize * 0.8
|
|
onClicked: {
|
|
root.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CPU Card (dual-line: usage % + temperature °C)
|
|
NBox {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: panelContent.cardHeight
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginS
|
|
anchors.bottomMargin: Style.radiusM * 0.5
|
|
spacing: Style.marginXS
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginXS
|
|
|
|
NIcon {
|
|
icon: "cpu-usage"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: `${Math.round(SystemStatService.cpuUsage)}% (${SystemStatService.cpuFreq.replace(/[^0-9.]/g, "")} GHz)`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
font.family: Settings.data.ui.fontFixed
|
|
}
|
|
|
|
NIcon {
|
|
icon: "cpu-temperature"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mSecondary
|
|
}
|
|
|
|
NText {
|
|
text: `${Math.round(SystemStatService.cpuTemp)}°C`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mSecondary
|
|
font.family: Settings.data.ui.fontFixed
|
|
Layout.rightMargin: Style.marginS
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("system-monitor.cpu-usage")
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
}
|
|
|
|
NGraph {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
values: SystemStatService.cpuHistory
|
|
values2: SystemStatService.cpuTempHistory
|
|
minValue: 0
|
|
maxValue: 100
|
|
minValue2: Math.max(SystemStatService.cpuTempHistoryMin - 5, 0)
|
|
maxValue2: Math.max(SystemStatService.cpuTempHistoryMax + 5, 1)
|
|
color: Color.mPrimary
|
|
color2: Color.mSecondary
|
|
strokeWidth: Math.max(1, Style.uiScaleRatio)
|
|
fill: true
|
|
fillOpacity: 0.15
|
|
updateInterval: SystemStatService.cpuUsageIntervalMs
|
|
}
|
|
}
|
|
}
|
|
|
|
// Memory Card (single-line + optional swap indicator)
|
|
NBox {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: panelContent.cardHeight
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginS
|
|
anchors.bottomMargin: Style.radiusM * 0.5
|
|
spacing: Style.marginXS
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginXS
|
|
|
|
NIcon {
|
|
icon: "memory"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: `${Math.round(SystemStatService.memPercent)}% (${(SystemStatService.memGb).toFixed(1)} GiB)`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
font.family: Settings.data.ui.fontFixed
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("common.memory")
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
}
|
|
|
|
NGraph {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
values: SystemStatService.memHistory
|
|
minValue: 0
|
|
maxValue: 100
|
|
color: Color.mPrimary
|
|
strokeWidth: Math.max(1, Style.uiScaleRatio)
|
|
fill: true
|
|
fillOpacity: 0.15
|
|
updateInterval: SystemStatService.memIntervalMs
|
|
}
|
|
}
|
|
}
|
|
|
|
// Network Card (dual-line: RX + TX speeds)
|
|
NBox {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: panelContent.cardHeight
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginS
|
|
anchors.bottomMargin: Style.radiusM * 0.5
|
|
spacing: Style.marginXS
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginXS
|
|
|
|
NIcon {
|
|
icon: "download-speed"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: SystemStatService.formatSpeed(SystemStatService.rxSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mPrimary
|
|
font.family: Settings.data.ui.fontFixed
|
|
Layout.rightMargin: Style.marginS
|
|
}
|
|
|
|
NIcon {
|
|
icon: "upload-speed"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mSecondary
|
|
}
|
|
|
|
NText {
|
|
text: SystemStatService.formatSpeed(SystemStatService.txSpeed).replace(/([0-9.]+)([A-Za-z]+)/, "$1 $2") + "/s"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mSecondary
|
|
font.family: Settings.data.ui.fontFixed
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("common.network")
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
}
|
|
|
|
NGraph {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
values: SystemStatService.rxSpeedHistory
|
|
values2: SystemStatService.txSpeedHistory
|
|
minValue: 0
|
|
maxValue: SystemStatService.rxMaxSpeed
|
|
minValue2: 0
|
|
maxValue2: SystemStatService.txMaxSpeed
|
|
color: Color.mPrimary
|
|
color2: Color.mSecondary
|
|
strokeWidth: Math.max(1, Style.uiScaleRatio)
|
|
fill: true
|
|
fillOpacity: 0.15
|
|
updateInterval: SystemStatService.networkIntervalMs
|
|
animateScale: true
|
|
}
|
|
}
|
|
}
|
|
|
|
// Detailed Stats section
|
|
NBox {
|
|
Layout.fillWidth: true
|
|
implicitHeight: detailsColumn.implicitHeight + Style.margin2M
|
|
|
|
ColumnLayout {
|
|
id: detailsColumn
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.margins: Style.marginM
|
|
spacing: Style.marginXS
|
|
|
|
// Load Average
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginS
|
|
visible: SystemStatService.nproc > 0
|
|
|
|
NIcon {
|
|
icon: "cpu-usage"
|
|
pointSize: Style.fontSizeM
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("system-monitor.load-average") + ":"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
NText {
|
|
text: `${SystemStatService.loadAvg1.toFixed(2)} • ${SystemStatService.loadAvg5.toFixed(2)} • ${SystemStatService.loadAvg15.toFixed(2)}`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignRight
|
|
}
|
|
}
|
|
|
|
// GPU Temperature (only if available)
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginS
|
|
visible: SystemStatService.gpuAvailable
|
|
|
|
NIcon {
|
|
icon: "gpu-temperature"
|
|
pointSize: Style.fontSizeM
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("system-monitor.gpu-temp") + ":"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
NText {
|
|
text: `${Math.round(SystemStatService.gpuTemp)}°C`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignRight
|
|
}
|
|
}
|
|
|
|
// Disk usage
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginS
|
|
|
|
NIcon {
|
|
icon: "storage"
|
|
pointSize: Style.fontSizeM
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("system-monitor.disk") + ":"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
NText {
|
|
text: {
|
|
const usedGb = SystemStatService.diskUsedGb[panelContent.diskPath] || 0;
|
|
const sizeGb = SystemStatService.diskSizeGb[panelContent.diskPath] || 0;
|
|
const percent = SystemStatService.diskPercents[panelContent.diskPath] || 0;
|
|
return `${percent}% (${usedGb.toFixed(1)} / ${sizeGb.toFixed(1)} GB)`;
|
|
}
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignRight
|
|
elide: Text.ElideMiddle
|
|
}
|
|
}
|
|
|
|
// Swap details (only visible if swap is enabled)
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Style.marginS
|
|
visible: SystemStatService.swapTotalGb > 0
|
|
|
|
NIcon {
|
|
icon: "exchange"
|
|
pointSize: Style.fontSizeM
|
|
color: Color.mPrimary
|
|
}
|
|
|
|
NText {
|
|
text: I18n.tr("bar.system-monitor.swap-usage-label") + ":"
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurfaceVariant
|
|
}
|
|
|
|
NText {
|
|
text: `${(SystemStatService.swapGb).toFixed(1)} / ${(SystemStatService.swapTotalGb).toFixed(1)} GiB`
|
|
pointSize: Style.fontSizeXS
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignRight
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|