pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell import Quickshell.Hyprland import Qt5Compat.GraphicalEffects import Qt.labs.synchronizer import qs import qs.services import qs.modules.common import qs.modules.common.widgets import qs.modules.overlay StyledOverlayWidget { id: root property list resources: [ { "icon": "planner_review", "name": Translation.tr("CPU"), "history": ResourceUsage.cpuUsageHistory, "maxAvailableString": ResourceUsage.maxAvailableCpuString }, { "icon": "memory", "name": Translation.tr("RAM"), "history": ResourceUsage.memoryUsageHistory, "maxAvailableString": ResourceUsage.maxAvailableMemoryString }, { "icon": "swap_horiz", "name": Translation.tr("Swap"), "history": ResourceUsage.swapUsageHistory, "maxAvailableString": ResourceUsage.maxAvailableSwapString }, ] contentItem: Rectangle { id: contentItem anchors.centerIn: parent color: Appearance.m3colors.m3surfaceContainer radius: root.contentRadius property real padding: 4 implicitWidth: 350 implicitHeight: 200 // implicitHeight: contentColumn.implicitHeight + padding * 2 ColumnLayout { id: contentColumn anchors { fill: parent margins: parent.padding } spacing: 8 SecondaryTabBar { id: tabBar currentIndex: Persistent.states.overlay.resources.tabIndex onCurrentIndexChanged: { Persistent.states.overlay.resources.tabIndex = tabBar.currentIndex; } Repeater { model: root.resources.length delegate: SecondaryTabButton { required property int index property var modelData: root.resources[index] buttonIcon: modelData.icon buttonText: modelData.name } } } ResourceSummary { Layout.margins: 8 history: root.resources[tabBar.currentIndex]?.history ?? [] maxAvailableString: root.resources[tabBar.currentIndex]?.maxAvailableString ?? "--" } } } component ResourceSummary: RowLayout { id: resourceSummary required property list history required property string maxAvailableString Layout.fillWidth: true Layout.fillHeight: true spacing: 12 ColumnLayout { spacing: 2 StyledText { text: (resourceSummary.history[resourceSummary.history.length - 1] * 100).toFixed(1) + "%" font { family: Appearance.font.family.numbers variableAxes: Appearance.font.variableAxes.numbers pixelSize: Appearance.font.pixelSize.huge } } StyledText { text: Translation.tr("of %1").arg(resourceSummary.maxAvailableString) font { // family: Appearance.font.family.numbers // variableAxes: Appearance.font.variableAxes.numbers pixelSize: Appearance.font.pixelSize.smallie } color: Appearance.colors.colSubtext } Item { Layout.fillHeight: true } } Rectangle { id: graphBg Layout.fillWidth: true Layout.fillHeight: true radius: Appearance.rounding.small color: Appearance.colors.colSecondaryContainer layer.enabled: true layer.effect: OpacityMask { maskSource: Rectangle { width: graphBg.width height: graphBg.height radius: graphBg.radius } } Graph { anchors.fill: parent values: root.resources[tabBar.currentIndex]?.history ?? [] points: ResourceUsage.historyLength alignment: Graph.Alignment.Right } } } }