1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-27 15:02:50 -05:00

feat: add temperature widgets, separate ram/cpu widgets, update

calculations
- make CPU calculations per-process mirror gnome (of all CPUs)
This commit is contained in:
bbedward
2025-08-08 14:43:43 -04:00
parent 105353c2a4
commit 03276b7d9a
27 changed files with 794 additions and 254 deletions

View File

@@ -15,7 +15,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -14,7 +14,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -20,7 +20,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -13,7 +13,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -49,11 +49,29 @@ Item {
"icon": "content_paste",
"enabled": true
}, {
"id": "systemResources",
"text": "System Resources",
"description": "CPU and memory usage indicators",
"id": "cpuUsage",
"text": "CPU Usage",
"description": "CPU usage indicator",
"icon": "memory",
"enabled": true
}, {
"id": "memUsage",
"text": "Memory Usage",
"description": "Memory usage indicator",
"icon": "storage",
"enabled": true
}, {
"id": "cpuTemp",
"text": "CPU Temperature",
"description": "CPU temperature display",
"icon": "device_thermostat",
"enabled": true
}, {
"id": "gpuTemp",
"text": "GPU Temperature",
"description": "GPU temperature display",
"icon": "auto_awesome_mosaic",
"enabled": true
}, {
"id": "systemTray",
"text": "System Tray",
@@ -127,7 +145,10 @@ Item {
"id": "clipboard",
"enabled": true
}, {
"id": "systemResources",
"id": "cpuUsage",
"enabled": true
}, {
"id": "memUsage",
"enabled": true
}, {
"id": "notificationButton",
@@ -147,6 +168,8 @@ Item {
};
if (widgetId === "spacer")
widgetObj.size = 20;
if (widgetId === "gpuTemp")
widgetObj.selectedGpuIndex = 0;
var widgets = [];
if (targetSection === "left") {
@@ -164,28 +187,25 @@ Item {
}
}
function removeWidgetFromSection(sectionId, itemId) {
function removeWidgetFromSection(sectionId, widgetIndex) {
var widgets = [];
if (sectionId === "left") {
widgets = SettingsData.topBarLeftWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarLeftWidgets(widgets);
} else if (sectionId === "center") {
widgets = SettingsData.topBarCenterWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarCenterWidgets(widgets);
} else if (sectionId === "right") {
widgets = SettingsData.topBarRightWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarRightWidgets(widgets);
}
}
@@ -208,7 +228,8 @@ Item {
} : {
"id": widget.id,
"enabled": enabled,
"size": widget.size
"size": widget.size,
"selectedGpuIndex": widget.selectedGpuIndex
};
break;
}
@@ -249,7 +270,8 @@ Item {
} : {
"id": widget.id,
"enabled": widget.enabled,
"size": newSize
"size": newSize,
"selectedGpuIndex": widget.selectedGpuIndex
};
break;
}
@@ -262,6 +284,37 @@ Item {
SettingsData.setTopBarRightWidgets(widgets);
}
function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) {
var widgets = [];
if (sectionId === "left")
widgets = SettingsData.topBarLeftWidgets.slice();
else if (sectionId === "center")
widgets = SettingsData.topBarCenterWidgets.slice();
else if (sectionId === "right")
widgets = SettingsData.topBarRightWidgets.slice();
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
var widget = widgets[widgetIndex];
widgets[widgetIndex] = typeof widget === "string" ? {
"id": widget,
"enabled": true,
"selectedGpuIndex": selectedGpuIndex
} : {
"id": widget.id,
"enabled": widget.enabled,
"size": widget.size,
"selectedGpuIndex": selectedGpuIndex
};
}
if (sectionId === "left")
SettingsData.setTopBarLeftWidgets(widgets);
else if (sectionId === "center")
SettingsData.setTopBarCenterWidgets(widgets);
else if (sectionId === "right")
SettingsData.setTopBarRightWidgets(widgets);
}
function getItemsForSection(sectionId) {
var widgets = [];
var widgetData = [];
@@ -275,6 +328,7 @@ Item {
var widgetId = typeof widget === "string" ? widget : widget.id;
var widgetEnabled = typeof widget === "string" ? true : widget.enabled;
var widgetSize = typeof widget === "string" ? undefined : widget.size;
var widgetSelectedGpuIndex = typeof widget === "string" ? undefined : widget.selectedGpuIndex;
var widgetDef = baseWidgetDefinitions.find((w) => {
return w.id === widgetId;
});
@@ -284,6 +338,8 @@ Item {
item.enabled = widgetEnabled;
if (widgetSize !== undefined)
item.size = widgetSize;
if (widgetSelectedGpuIndex !== undefined)
item.selectedGpuIndex = widgetSelectedGpuIndex;
widgets.push(item);
}
@@ -338,7 +394,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn
@@ -487,7 +542,7 @@ Item {
width: parent.width
spacing: Theme.spacingL
DankSections {
WidgetsTabSection {
width: parent.width
title: "Left Section"
titleIcon: "format_align_left"
@@ -505,8 +560,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -518,9 +573,12 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
DankSections {
WidgetsTabSection {
width: parent.width
title: "Center Section"
titleIcon: "format_align_center"
@@ -538,8 +596,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -551,9 +609,12 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
DankSections {
WidgetsTabSection {
width: parent.width
title: "Right Section"
titleIcon: "format_align_right"
@@ -571,8 +632,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -584,6 +645,9 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
}
}

View File

@@ -0,0 +1,384 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
import qs.Services
Column {
id: root
property var items: []
property var allWidgets: []
property string title: ""
property string titleIcon: "widgets"
property string sectionId: ""
signal itemEnabledChanged(string sectionId, string itemId, bool enabled)
signal itemOrderChanged(var newOrder)
signal addWidget(string sectionId)
signal removeWidget(string sectionId, int widgetIndex)
signal spacerSizeChanged(string sectionId, string itemId, int newSize)
signal compactModeChanged(string widgetId, bool enabled)
signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex)
width: parent.width
height: implicitHeight
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: root.titleIcon
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.title
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - 60
height: 1
}
}
Column {
id: itemsList
width: parent.width
spacing: Theme.spacingS
Repeater {
model: root.items
delegate: Item {
id: delegateItem
property bool held: dragArea.pressed
property real originalY: y
width: itemsList.width
height: 70
z: held ? 2 : 1
Rectangle {
id: itemBackground
anchors.fill: parent
anchors.margins: 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
DankIcon {
name: "drag_indicator"
size: Theme.iconSize - 4
color: Theme.outline
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM + 8
anchors.verticalCenter: parent.verticalCenter
opacity: 0.8
}
DankIcon {
name: modelData.icon
size: Theme.iconSize
color: modelData.enabled ? Theme.primary : Theme.outline
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM * 2 + 40
anchors.verticalCenter: parent.verticalCenter
}
Column {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM * 3 + 40 + Theme.iconSize
anchors.right: actionButtons.left
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: 2
StyledText {
text: modelData.text
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: modelData.enabled ? Theme.surfaceText : Theme.outline
elide: Text.ElideRight
width: parent.width
}
StyledText {
text: modelData.description
font.pixelSize: Theme.fontSizeSmall
color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6)
elide: Text.ElideRight
width: parent.width
wrapMode: Text.WordWrap
}
}
Row {
id: actionButtons
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
Item {
width: 120
height: 32
visible: modelData.id === "gpuTemp"
DankDropdown {
id: gpuDropdown
anchors.fill: parent
currentValue: {
var selectedIndex = modelData.selectedGpuIndex !== undefined ? modelData.selectedGpuIndex : 0;
if (SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > selectedIndex && selectedIndex >= 0) {
var gpu = SysMonitorService.availableGpus[selectedIndex];
return gpu.driver.toUpperCase() + " (" + Math.round(gpu.temperature || 0) + "°C)";
}
return SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > 0 ? SysMonitorService.availableGpus[0].driver.toUpperCase() + " (" + Math.round(SysMonitorService.availableGpus[0].temperature || 0) + "°C)" : "";
}
options: {
var gpuOptions = [];
if (SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > 0) {
for (var i = 0; i < SysMonitorService.availableGpus.length; i++) {
var gpu = SysMonitorService.availableGpus[i];
gpuOptions.push(gpu.driver.toUpperCase() + " (" + Math.round(gpu.temperature || 0) + "°C)");
}
}
return gpuOptions;
}
onValueChanged: (value) => {
var gpuIndex = options.indexOf(value);
if (gpuIndex >= 0) {
root.gpuSelectionChanged(root.sectionId, index, gpuIndex);
}
}
}
}
Item {
width: 32
height: 32
visible: modelData.id === "clock" || modelData.id === "music"
DankActionButton {
id: compactModeButton
anchors.fill: parent
buttonSize: 32
iconName: (modelData.id === "clock" && SettingsData.clockCompactMode) || (modelData.id === "music" && SettingsData.mediaCompactMode) ? "zoom_out" : "zoom_in"
iconSize: 18
iconColor: ((modelData.id === "clock" && SettingsData.clockCompactMode) || (modelData.id === "music" && SettingsData.mediaCompactMode)) ? Theme.primary : Theme.outline
onClicked: {
if (modelData.id === "clock") {
root.compactModeChanged("clock", !SettingsData.clockCompactMode);
} else if (modelData.id === "music") {
root.compactModeChanged("music", !SettingsData.mediaCompactMode);
}
}
}
Rectangle {
id: compactModeTooltip
width: tooltipText.contentWidth + Theme.spacingM * 2
height: tooltipText.contentHeight + Theme.spacingS * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
visible: compactModeButton.children[1] && compactModeButton.children[1].containsMouse
opacity: visible ? 1 : 0
x: -width - Theme.spacingS
y: (parent.height - height) / 2
z: 100
StyledText {
id: tooltipText
anchors.centerIn: parent
text: "Compact Mode"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
}
Behavior on opacity {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
DankActionButton {
visible: modelData.id !== "spacer"
buttonSize: 32
iconName: modelData.enabled ? "visibility" : "visibility_off"
iconSize: 18
iconColor: modelData.enabled ? Theme.primary : Theme.outline
onClicked: {
root.itemEnabledChanged(root.sectionId, modelData.id, !modelData.enabled);
}
}
Row {
visible: modelData.id === "spacer"
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
DankActionButton {
buttonSize: 24
iconName: "remove"
iconSize: 14
iconColor: Theme.outline
onClicked: {
var currentSize = modelData.size || 20;
var newSize = Math.max(5, currentSize - 5);
root.spacerSizeChanged(root.sectionId, modelData.id, newSize);
}
}
StyledText {
text: (modelData.size || 20).toString()
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
DankActionButton {
buttonSize: 24
iconName: "add"
iconSize: 14
iconColor: Theme.outline
onClicked: {
var currentSize = modelData.size || 20;
var newSize = Math.min(5000, currentSize + 5);
root.spacerSizeChanged(root.sectionId, modelData.id, newSize);
}
}
}
DankActionButton {
buttonSize: 32
iconName: "close"
iconSize: 18
iconColor: Theme.error
onClicked: {
root.removeWidget(root.sectionId, index);
}
}
}
MouseArea {
id: dragArea
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 60
hoverEnabled: true
cursorShape: Qt.SizeVerCursor
drag.target: held ? delegateItem : undefined
drag.axis: Drag.YAxis
drag.minimumY: -delegateItem.height
drag.maximumY: itemsList.height
preventStealing: true
onPressed: {
delegateItem.z = 2;
delegateItem.originalY = delegateItem.y;
}
onReleased: {
delegateItem.z = 1;
if (drag.active) {
var newIndex = Math.round(delegateItem.y / (delegateItem.height + itemsList.spacing));
newIndex = Math.max(0, Math.min(newIndex, root.items.length - 1));
if (newIndex !== index) {
var newItems = root.items.slice();
var draggedItem = newItems.splice(index, 1)[0];
newItems.splice(newIndex, 0, draggedItem);
root.itemOrderChanged(newItems.map((item) => {
return ({
"id": item.id,
"enabled": item.enabled,
"size": item.size
});
}));
}
}
delegateItem.x = 0;
delegateItem.y = delegateItem.originalY;
}
}
Behavior on y {
enabled: !dragArea.held && !dragArea.drag.active
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
}
}
Rectangle {
width: 200
height: 40
radius: Theme.cornerRadius
color: addButtonArea.containsMouse ? Theme.primaryContainer : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: "Add Widget"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
anchors.centerIn: parent
}
MouseArea {
id: addButtonArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.addWidget(root.sectionId);
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}