forked from Shinonome/dots-hyprland
hefty: bar: resources popup: show mem & cpu
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
property list<real> valueWeights: [1]
|
||||
property list<real> values: [0.5]
|
||||
property list<color> valueHighlights: ["white"]
|
||||
property list<color> valueTroughs: []
|
||||
|
||||
readonly property list<real> normalizedValueWeights: {
|
||||
const totalWeight = valueWeights.reduce((sum, weight) => sum + weight, 0)
|
||||
return valueWeights.map(weight => weight / totalWeight)
|
||||
}
|
||||
|
||||
readonly property list<real> visualEnds: {
|
||||
let cumsum = 0;
|
||||
let positions = [];
|
||||
for (let i = 0; i < normalizedValueWeights.length; i++) {
|
||||
cumsum += normalizedValueWeights[i];
|
||||
positions.push(cumsum);
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
readonly property list<real> visualPositions: {
|
||||
let positions = [];
|
||||
let lastEnd = 0;
|
||||
for(let i = 0; i < visualEnds.length; i++) {
|
||||
const thisEnd = visualEnds[i];
|
||||
const width = thisEnd - lastEnd;
|
||||
const thisPos = lastEnd + width * values[i];
|
||||
positions.push(thisPos);
|
||||
lastEnd = visualEnds[i];
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
readonly property list<var> visualSegments: {
|
||||
let segs = [];
|
||||
let lastEnd = 0;
|
||||
for(let i = 0; i < visualEnds.length; i++) {
|
||||
const thisEnd = visualEnds[i];
|
||||
const thisPos = visualPositions[i];
|
||||
segs.push([lastEnd, thisPos]);
|
||||
segs.push([thisPos, thisEnd]);
|
||||
lastEnd = visualEnds[i];
|
||||
}
|
||||
return segs;
|
||||
}
|
||||
|
||||
readonly property list<color> segmentColors: {
|
||||
var cols = [];
|
||||
for(let i = 0; i < valueHighlights.length; i++) {
|
||||
cols.push(valueHighlights[i]);
|
||||
cols.push(valueTroughs[i]);
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import qs.modules.common
|
||||
|
||||
AbstractCombinedProgressBar {
|
||||
id: root
|
||||
|
||||
property real valueBarWidth: 120
|
||||
property real valueBarHeight: 4
|
||||
property real valueBarGap: 4
|
||||
property real valueBarInnerRadius: Appearance.rounding.unsharpen
|
||||
valueHighlights: [Appearance.colors.colPrimary, Appearance.colors.colTertiary]
|
||||
valueTroughs: [Appearance.colors.colSecondaryContainer, Appearance.colors.colTertiaryContainer]
|
||||
|
||||
background: Item {
|
||||
implicitWidth: root.valueBarWidth
|
||||
implicitHeight: root.valueBarHeight
|
||||
}
|
||||
|
||||
// "negligible" = too small that it'd look weird when shown
|
||||
function isNegligibleSegment(seg: var): bool {
|
||||
const wdth = seg[1] - seg[0];
|
||||
const visualWidth = availableWidth * wdth;
|
||||
return (visualWidth <= valueBarGap + valueBarHeight)
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
Repeater {
|
||||
model: root.visualSegments
|
||||
|
||||
delegate: Rectangle {
|
||||
required property int index
|
||||
required property var modelData
|
||||
|
||||
visible: !root.isNegligibleSegment(modelData)
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
property bool atStart: index == 0
|
||||
property bool atEnd: index == root.visualSegments.length - 1
|
||||
property real displaySegStart: { // swallow previous segments if they're "negligible"
|
||||
var i = index;
|
||||
while ((i > 0 && root.isNegligibleSegment(root.visualSegments[i-1])))
|
||||
i--;
|
||||
return root.visualSegments[i][0]
|
||||
}
|
||||
|
||||
x: {
|
||||
var result = root.availableWidth * displaySegStart;
|
||||
if (!atStart) result += root.valueBarGap / 2;
|
||||
return result;
|
||||
}
|
||||
width: {
|
||||
var result = root.availableWidth * (modelData[1] - displaySegStart)
|
||||
if (atStart || atEnd) result -= root.valueBarGap / 2;
|
||||
else result -= root.valueBarGap;
|
||||
return result;
|
||||
}
|
||||
color: root.segmentColors[index % root.segmentColors.length]
|
||||
|
||||
property real startRadius: atStart ? height / 2 : root.valueBarInnerRadius
|
||||
property real endRadius: atEnd ? height / 2 : root.valueBarInnerRadius
|
||||
|
||||
topLeftRadius: startRadius
|
||||
bottomLeftRadius: startRadius
|
||||
topRightRadius: endRadius
|
||||
bottomRightRadius: endRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,102 @@ HBarWidgetWithPopout {
|
||||
W.FlyFadeEnterChoreographable {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Column {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
spacing: 2
|
||||
|
||||
Item {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
implicitHeight: memUsed.implicitHeight
|
||||
|
||||
BigSmallTextPair {
|
||||
id: memUsed
|
||||
materialSymbol: "memory"
|
||||
bigText: S.ResourceUsage.kbToGbString(S.ResourceUsage.memoryUsed, false)
|
||||
smallText: {
|
||||
const total = S.ResourceUsage.kbToGbString(S.ResourceUsage.memoryTotal, false);
|
||||
return S.Translation.tr("%1").arg(`/ ${total}`)
|
||||
}
|
||||
W.StyledText {
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
text: S.Translation.tr("Memory")
|
||||
color: C.Appearance.colors.colOutline
|
||||
}
|
||||
}
|
||||
BigSmallTextPair {
|
||||
id: swapUsed
|
||||
TextMetrics {
|
||||
id: plusTextMetric
|
||||
font: swapUsed.bigFont
|
||||
text: "+"
|
||||
}
|
||||
property real halfWidthOfAPlus: plusTextMetric.width / 2
|
||||
x: Math.min(memProg.availableWidth * memProg.visualEnds[0] - halfWidthOfAPlus, parent.width - width)
|
||||
bigText: "+ " + S.ResourceUsage.kbToGbString(S.ResourceUsage.swapUsed, false)
|
||||
smallText: {
|
||||
const total = S.ResourceUsage.kbToGbString(S.ResourceUsage.swapTotal, false);
|
||||
return `/ ${total} GB`
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
W.StyledCombinedProgressBar {
|
||||
id: memProg
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
valueWeights: [S.ResourceUsage.memoryTotal, S.ResourceUsage.swapTotal]
|
||||
values: [S.ResourceUsage.memoryUsedPercentage, S.ResourceUsage.swapUsedPercentage]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
W.FlyFadeEnterChoreographable {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Column {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
spacing: 2
|
||||
|
||||
BigSmallTextPair {
|
||||
spacing: 0
|
||||
materialSymbol: "developer_board"
|
||||
bigText: Math.round(S.ResourceUsage.cpuUsage * 100)
|
||||
smallText: "%"
|
||||
W.StyledText {
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
text: " " + S.Translation.tr("CPU")
|
||||
color: C.Appearance.colors.colOutline
|
||||
}
|
||||
}
|
||||
W.StyledCombinedProgressBar {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
property bool useSingleAggregate: S.ResourceUsage.cpuCoreUsages.length > 8
|
||||
valueWeights: useSingleAggregate ? [1] : S.ResourceUsage.cpuCoreFreqCaps
|
||||
values: useSingleAggregate ? [S.ResourceUsage.cpuUsage] : S.ResourceUsage.cpuCoreUsages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
W.FlyFadeEnterChoreographable {
|
||||
Layout.topMargin: 8
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
width: parent.width
|
||||
@@ -258,6 +354,36 @@ HBarWidgetWithPopout {
|
||||
}
|
||||
}
|
||||
|
||||
component BigSmallTextPair: RowLayout {
|
||||
id: txtPair
|
||||
property string materialSymbol: ""
|
||||
property string bigText: ""
|
||||
property string smallText: ""
|
||||
property alias bigFont: bigTxt.font
|
||||
property alias smallFont: smallTxt.font
|
||||
spacing: 6
|
||||
|
||||
W.MaterialSymbol {
|
||||
Layout.rightMargin: 6 - spacing
|
||||
visible: text.length > 0
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: txtPair.materialSymbol
|
||||
fill: 1
|
||||
iconSize: 24
|
||||
}
|
||||
W.StyledText {
|
||||
id: bigTxt
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
font.pixelSize: C.Appearance.font.pixelSize.title
|
||||
text: txtPair.bigText
|
||||
}
|
||||
W.StyledText {
|
||||
id: smallTxt
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
text: txtPair.smallText
|
||||
}
|
||||
}
|
||||
|
||||
component StatWithIcon: Item {
|
||||
id: statItem
|
||||
required property string icon
|
||||
|
||||
Reference in New Issue
Block a user