1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

dankbar: convert center section to use WidgetHost

This commit is contained in:
bbedward
2025-12-04 19:37:21 -05:00
parent 63d121b796
commit ad0f3fa33b
3 changed files with 343 additions and 422 deletions

View File

@@ -1,6 +1,5 @@
import QtQuick import QtQuick
import qs.Common import qs.Common
import qs.Services
Item { Item {
id: root id: root
@@ -19,7 +18,7 @@ Item {
property bool forceVerticalLayout: false property bool forceVerticalLayout: false
readonly property bool isVertical: overrideAxisLayout ? forceVerticalLayout : (axis?.isVertical ?? false) readonly property bool isVertical: overrideAxisLayout ? forceVerticalLayout : (axis?.isVertical ?? false)
readonly property real spacing: { readonly property real widgetSpacing: {
const baseSpacing = noBackground ? 2 : Theme.spacingXS; const baseSpacing = noBackground ? 2 : Theme.spacingXS;
const outlineThickness = (barConfig?.widgetOutlineEnabled ?? false) ? (barConfig?.widgetOutlineThickness ?? 1) : 0; const outlineThickness = (barConfig?.widgetOutlineEnabled ?? false) ? (barConfig?.widgetOutlineThickness ?? 1) : 0;
return baseSpacing + (outlineThickness * 2); return baseSpacing + (outlineThickness * 2);
@@ -33,36 +32,32 @@ Item {
if (SettingsData.centeringMode === "geometric") { if (SettingsData.centeringMode === "geometric") {
applyGeometricLayout(); applyGeometricLayout();
} else { } else {
// Default to index layout or if value is not 'geometric'
applyIndexLayout(); applyIndexLayout();
} }
} }
function applyGeometricLayout() { function applyGeometricLayout() {
if ((isVertical ? height : width) <= 0 || !visible) { if ((isVertical ? height : width) <= 0 || !visible)
return; return;
}
centerWidgets = []; centerWidgets = [];
totalWidgets = 0; totalWidgets = 0;
totalSize = 0; totalSize = 0;
for (var i = 0; i < centerRepeater.count; i++) { for (var i = 0; i < centerRepeater.count; i++) {
const item = centerRepeater.itemAt(i); const loader = centerRepeater.itemAt(i);
if (item && item.active && item.item && getWidgetVisible(item.widgetId)) { if (loader && loader.active && loader.item) {
centerWidgets.push(item.item); centerWidgets.push(loader.item);
totalWidgets++; totalWidgets++;
totalSize += isVertical ? item.item.height : item.item.width; totalSize += isVertical ? loader.item.height : loader.item.width;
} }
} }
if (totalWidgets === 0) { if (totalWidgets === 0)
return; return;
}
if (totalWidgets > 1) { if (totalWidgets > 1)
totalSize += spacing * (totalWidgets - 1); totalSize += widgetSpacing * (totalWidgets - 1);
}
positionWidgetsGeometric(); positionWidgetsGeometric();
} }
@@ -70,7 +65,6 @@ Item {
function positionWidgetsGeometric() { function positionWidgetsGeometric() {
const parentLength = isVertical ? height : width; const parentLength = isVertical ? height : width;
const parentCenter = parentLength / 2; const parentCenter = parentLength / 2;
let currentPos = parentCenter - (totalSize / 2); let currentPos = parentCenter - (totalSize / 2);
centerWidgets.forEach(widget => { centerWidgets.forEach(widget => {
@@ -81,67 +75,53 @@ Item {
widget.anchors.horizontalCenter = undefined; widget.anchors.horizontalCenter = undefined;
widget.x = currentPos; widget.x = currentPos;
} }
const widgetSize = isVertical ? widget.height : widget.width; const widgetSize = isVertical ? widget.height : widget.width;
currentPos += widgetSize + spacing; currentPos += widgetSize + widgetSpacing;
}); });
} }
function applyIndexLayout() { function applyIndexLayout() {
if ((isVertical ? height : width) <= 0 || !visible) { if ((isVertical ? height : width) <= 0 || !visible)
return; return;
}
centerWidgets = []; centerWidgets = [];
totalWidgets = 0; totalWidgets = 0;
totalSize = 0; totalSize = 0;
let configuredWidgets = 0;
let configuredMiddleWidget = null; let configuredMiddleWidget = null;
let configuredLeftWidget = null; let configuredLeftWidget = null;
let configuredRightWidget = null; let configuredRightWidget = null;
for (var i = 0; i < centerRepeater.count; i++) { const configuredWidgets = centerRepeater.count;
const item = centerRepeater.itemAt(i);
if (item && getWidgetVisible(item.widgetId)) {
configuredWidgets++;
}
}
const isOddConfigured = configuredWidgets % 2 === 1; const isOddConfigured = configuredWidgets % 2 === 1;
const configuredMiddlePos = Math.floor(configuredWidgets / 2); const configuredMiddlePos = Math.floor(configuredWidgets / 2);
const configuredLeftPos = isOddConfigured ? -1 : ((configuredWidgets / 2) - 1); const configuredLeftPos = isOddConfigured ? -1 : ((configuredWidgets / 2) - 1);
const configuredRightPos = isOddConfigured ? -1 : (configuredWidgets / 2); const configuredRightPos = isOddConfigured ? -1 : (configuredWidgets / 2);
let currentConfigIndex = 0;
for (var i = 0; i < centerRepeater.count; i++) { for (var i = 0; i < centerRepeater.count; i++) {
const item = centerRepeater.itemAt(i); const wrapper = centerRepeater.itemAt(i);
if (item && getWidgetVisible(item.widgetId)) { if (!wrapper)
if (isOddConfigured && currentConfigIndex === configuredMiddlePos && item.active && item.item) { continue;
configuredMiddleWidget = item.item;
} if (isOddConfigured && i === configuredMiddlePos && wrapper.active && wrapper.item)
if (!isOddConfigured && currentConfigIndex === configuredLeftPos && item.active && item.item) { configuredMiddleWidget = wrapper.item;
configuredLeftWidget = item.item; if (!isOddConfigured && i === configuredLeftPos && wrapper.active && wrapper.item)
} configuredLeftWidget = wrapper.item;
if (!isOddConfigured && currentConfigIndex === configuredRightPos && item.active && item.item) { if (!isOddConfigured && i === configuredRightPos && wrapper.active && wrapper.item)
configuredRightWidget = item.item; configuredRightWidget = wrapper.item;
}
if (item.active && item.item) { if (wrapper.active && wrapper.item) {
centerWidgets.push(item.item); centerWidgets.push(wrapper.item);
totalWidgets++; totalWidgets++;
totalSize += isVertical ? item.item.height : item.item.width; totalSize += isVertical ? wrapper.item.height : wrapper.item.width;
}
currentConfigIndex++;
} }
} }
if (totalWidgets === 0) { if (totalWidgets === 0)
return; return;
}
if (totalWidgets > 1) { if (totalWidgets > 1)
totalSize += spacing * (totalWidgets - 1); totalSize += widgetSpacing * (totalWidgets - 1);
}
positionWidgetsByIndex(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget); positionWidgetsByIndex(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget);
} }
@@ -151,11 +131,10 @@ Item {
const isOddConfigured = configuredWidgets % 2 === 1; const isOddConfigured = configuredWidgets % 2 === 1;
centerWidgets.forEach(widget => { centerWidgets.forEach(widget => {
if (isVertical) { if (isVertical)
widget.anchors.verticalCenter = undefined; widget.anchors.verticalCenter = undefined;
} else { else
widget.anchors.horizontalCenter = undefined; widget.anchors.horizontalCenter = undefined;
}
}); });
if (isOddConfigured && configuredMiddleWidget) { if (isOddConfigured && configuredMiddleWidget) {
@@ -163,42 +142,40 @@ Item {
const middleIndex = centerWidgets.indexOf(middleWidget); const middleIndex = centerWidgets.indexOf(middleWidget);
const middleSize = isVertical ? middleWidget.height : middleWidget.width; const middleSize = isVertical ? middleWidget.height : middleWidget.width;
if (isVertical) { if (isVertical)
middleWidget.y = parentCenter - (middleSize / 2); middleWidget.y = parentCenter - (middleSize / 2);
} else { else
middleWidget.x = parentCenter - (middleSize / 2); middleWidget.x = parentCenter - (middleSize / 2);
}
let currentPos = isVertical ? middleWidget.y : middleWidget.x; let currentPos = isVertical ? middleWidget.y : middleWidget.x;
for (var i = middleIndex - 1; i >= 0; i--) { for (var i = middleIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width; const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size); currentPos -= (widgetSpacing + size);
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
} }
}
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize; currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize;
for (var i = middleIndex + 1; i < totalWidgets; i++) { for (var i = middleIndex + 1; i < totalWidgets; i++) {
currentPos += spacing; currentPos += widgetSpacing;
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width; currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
} }
} else { return;
}
if (totalWidgets === 1) { if (totalWidgets === 1) {
const widget = centerWidgets[0]; const widget = centerWidgets[0];
const size = isVertical ? widget.height : widget.width; const size = isVertical ? widget.height : widget.width;
if (isVertical) { if (isVertical)
widget.y = parentCenter - (size / 2); widget.y = parentCenter - (size / 2);
} else { else
widget.x = parentCenter - (size / 2); widget.x = parentCenter - (size / 2);
}
return; return;
} }
@@ -207,37 +184,33 @@ Item {
const middleIndex = Math.floor(totalWidgets / 2); const middleIndex = Math.floor(totalWidgets / 2);
const middleWidget = centerWidgets[middleIndex]; const middleWidget = centerWidgets[middleIndex];
if (!middleWidget) { if (!middleWidget)
return; return;
}
const middleSize = isVertical ? middleWidget.height : middleWidget.width; const middleSize = isVertical ? middleWidget.height : middleWidget.width;
if (isVertical) { if (isVertical)
middleWidget.y = parentCenter - (middleSize / 2); middleWidget.y = parentCenter - (middleSize / 2);
} else { else
middleWidget.x = parentCenter - (middleSize / 2); middleWidget.x = parentCenter - (middleSize / 2);
}
let currentPos = isVertical ? middleWidget.y : middleWidget.x; let currentPos = isVertical ? middleWidget.y : middleWidget.x;
for (var i = middleIndex - 1; i >= 0; i--) { for (var i = middleIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width; const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size); currentPos -= (widgetSpacing + size);
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
} }
}
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize; currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize;
for (var i = middleIndex + 1; i < totalWidgets; i++) { for (var i = middleIndex + 1; i < totalWidgets; i++) {
currentPos += spacing; currentPos += widgetSpacing;
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width; currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
} }
} else { } else {
@@ -246,11 +219,10 @@ Item {
const fallbackLeft = centerWidgets[leftIndex]; const fallbackLeft = centerWidgets[leftIndex];
const fallbackRight = centerWidgets[rightIndex]; const fallbackRight = centerWidgets[rightIndex];
if (!fallbackLeft || !fallbackRight) { if (!fallbackLeft || !fallbackRight)
return; return;
}
const halfSpacing = spacing / 2; const halfSpacing = widgetSpacing / 2;
const leftSize = isVertical ? fallbackLeft.height : fallbackLeft.width; const leftSize = isVertical ? fallbackLeft.height : fallbackLeft.width;
if (isVertical) { if (isVertical) {
@@ -264,22 +236,20 @@ Item {
let currentPos = isVertical ? fallbackLeft.y : fallbackLeft.x; let currentPos = isVertical ? fallbackLeft.y : fallbackLeft.x;
for (var i = leftIndex - 1; i >= 0; i--) { for (var i = leftIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width; const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size); currentPos -= (widgetSpacing + size);
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
} }
}
currentPos = (isVertical ? fallbackRight.y + fallbackRight.height : fallbackRight.x + fallbackRight.width); currentPos = (isVertical ? fallbackRight.y + fallbackRight.height : fallbackRight.x + fallbackRight.width);
for (var i = rightIndex + 1; i < totalWidgets; i++) { for (var i = rightIndex + 1; i < totalWidgets; i++) {
currentPos += spacing; currentPos += widgetSpacing;
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width; currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
} }
} }
@@ -290,7 +260,7 @@ Item {
const rightWidget = configuredRightWidget; const rightWidget = configuredRightWidget;
const leftIndex = centerWidgets.indexOf(leftWidget); const leftIndex = centerWidgets.indexOf(leftWidget);
const rightIndex = centerWidgets.indexOf(rightWidget); const rightIndex = centerWidgets.indexOf(rightWidget);
const halfSpacing = spacing / 2; const halfSpacing = widgetSpacing / 2;
const leftSize = isVertical ? leftWidget.height : leftWidget.width; const leftSize = isVertical ? leftWidget.height : leftWidget.width;
if (isVertical) { if (isVertical) {
@@ -304,82 +274,23 @@ Item {
let currentPos = isVertical ? leftWidget.y : leftWidget.x; let currentPos = isVertical ? leftWidget.y : leftWidget.x;
for (var i = leftIndex - 1; i >= 0; i--) { for (var i = leftIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width; const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size); currentPos -= (widgetSpacing + size);
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
} }
}
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width); currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width);
for (var i = rightIndex + 1; i < totalWidgets; i++) { for (var i = rightIndex + 1; i < totalWidgets; i++) {
currentPos += spacing; currentPos += widgetSpacing;
if (isVertical) { if (isVertical)
centerWidgets[i].y = currentPos; centerWidgets[i].y = currentPos;
} else { else
centerWidgets[i].x = currentPos; centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width; currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
} }
} }
}
function getWidgetVisible(widgetId) {
const widgetVisibility = {
"cpuUsage": DgopService.dgopAvailable,
"memUsage": DgopService.dgopAvailable,
"cpuTemp": DgopService.dgopAvailable,
"gpuTemp": DgopService.dgopAvailable,
"network_speed_monitor": DgopService.dgopAvailable
};
return widgetVisibility[widgetId] ?? true;
}
function getWidgetComponent(widgetId) {
// Build dynamic component map including plugins
let baseMap = {
"launcherButton": "launcherButtonComponent",
"workspaceSwitcher": "workspaceSwitcherComponent",
"focusedWindow": "focusedWindowComponent",
"runningApps": "runningAppsComponent",
"clock": "clockComponent",
"music": "mediaComponent",
"weather": "weatherComponent",
"systemTray": "systemTrayComponent",
"privacyIndicator": "privacyIndicatorComponent",
"clipboard": "clipboardComponent",
"cpuUsage": "cpuUsageComponent",
"memUsage": "memUsageComponent",
"diskUsage": "diskUsageComponent",
"cpuTemp": "cpuTempComponent",
"gpuTemp": "gpuTempComponent",
"notificationButton": "notificationButtonComponent",
"battery": "batteryComponent",
"controlCenterButton": "controlCenterButtonComponent",
"idleInhibitor": "idleInhibitorComponent",
"spacer": "spacerComponent",
"separator": "separatorComponent",
"network_speed_monitor": "networkComponent",
"keyboard_layout_name": "keyboardLayoutNameComponent",
"vpn": "vpnComponent",
"notepadButton": "notepadButtonComponent",
"colorPicker": "colorPickerComponent",
"systemUpdate": "systemUpdateComponent"
};
// For built-in components, get from components property
const componentKey = baseMap[widgetId];
if (componentKey && root.components[componentKey]) {
return root.components[componentKey];
}
// For plugin components, get from PluginService
var parts = widgetId.split(":");
var pluginId = parts[0];
let pluginComponents = PluginService.getWidgetComponents();
return pluginComponents[pluginId] || null;
}
height: parent.height height: parent.height
width: parent.width width: parent.width
@@ -392,177 +303,71 @@ Item {
onTriggered: root.updateLayout() onTriggered: root.updateLayout()
} }
Component.onCompleted: { Component.onCompleted: layoutTimer.restart()
layoutTimer.restart();
}
onWidthChanged: { onWidthChanged: {
if (width > 0) { if (width > 0)
layoutTimer.restart(); layoutTimer.restart();
} }
}
onHeightChanged: { onHeightChanged: {
if (height > 0) { if (height > 0)
layoutTimer.restart(); layoutTimer.restart();
} }
}
onVisibleChanged: { onVisibleChanged: {
if (visible && (isVertical ? height : width) > 0) { if (visible && (isVertical ? height : width) > 0)
layoutTimer.restart(); layoutTimer.restart();
} }
}
Repeater { Repeater {
id: centerRepeater id: centerRepeater
model: root.widgetsModel model: root.widgetsModel
Loader { onCountChanged: layoutTimer.restart()
Item {
property var itemData: modelData property var itemData: modelData
property string widgetId: itemData.widgetId readonly property real itemSpacing: root.widgetSpacing
property var widgetData: itemData
property int spacerSize: itemData.size || 20 width: widgetLoader.item ? widgetLoader.item.width : 0
height: widgetLoader.item ? widgetLoader.item.height : 0
readonly property bool active: widgetLoader.active
readonly property var item: widgetLoader.item
WidgetHost {
id: widgetLoader
anchors.verticalCenter: !root.isVertical ? parent.verticalCenter : undefined anchors.verticalCenter: !root.isVertical ? parent.verticalCenter : undefined
anchors.horizontalCenter: root.isVertical ? parent.horizontalCenter : undefined anchors.horizontalCenter: root.isVertical ? parent.horizontalCenter : undefined
active: root.getWidgetVisible(itemData.widgetId) && (itemData.widgetId !== "music" || MprisController.activePlayer !== null)
sourceComponent: root.getWidgetComponent(itemData.widgetId)
opacity: (itemData.enabled !== false) ? 1 : 0
asynchronous: false
onLoaded: { widgetId: itemData.widgetId
if (!item) { widgetData: itemData
return; spacerSize: itemData.size || 20
} components: root.components
item.widthChanged.connect(() => { isInColumn: root.isVertical
if (layoutTimer) axis: root.axis
layoutTimer.restart(); section: "center"
}); parentScreen: root.parentScreen
item.heightChanged.connect(() => { widgetThickness: root.widgetThickness
if (layoutTimer) barThickness: root.barThickness
layoutTimer.restart(); barSpacing: root.barSpacing
}); barConfig: root.barConfig
if (root.axis && "axis" in item) { isFirst: index === 0
item.axis = Qt.binding(() => root.axis); isLast: index === centerRepeater.count - 1
} sectionSpacing: parent.itemSpacing
if (root.axis && "isVertical" in item) { isLeftBarEdge: false
try { isRightBarEdge: false
item.isVertical = Qt.binding(() => root.axis.isVertical); isTopBarEdge: false
} catch (e) {} isBottomBarEdge: false
onContentItemReady: contentItem => {
contentItem.widthChanged.connect(() => layoutTimer.restart());
contentItem.heightChanged.connect(() => layoutTimer.restart());
} }
// Inject properties for plugin widgets onActiveChanged: layoutTimer.restart()
if ("section" in item) {
item.section = root.section;
}
if ("parentScreen" in item) {
item.parentScreen = Qt.binding(() => root.parentScreen);
}
if ("widgetThickness" in item) {
item.widgetThickness = Qt.binding(() => root.widgetThickness);
}
if ("barThickness" in item) {
item.barThickness = Qt.binding(() => root.barThickness);
}
if ("barSpacing" in item) {
item.barSpacing = Qt.binding(() => root.barSpacing);
}
if ("barConfig" in item) {
item.barConfig = Qt.binding(() => root.barConfig);
}
if ("sectionSpacing" in item) {
item.sectionSpacing = Qt.binding(() => root.spacing);
}
if ("widgetData" in item) {
item.widgetData = Qt.binding(() => widgetData);
}
if ("isFirst" in item) {
item.isFirst = Qt.binding(() => {
for (var i = 0; i < centerRepeater.count; i++) {
const checkItem = centerRepeater.itemAt(i);
if (checkItem && checkItem.active && checkItem.item) {
return checkItem.item === item;
}
}
return false;
});
}
if ("isLast" in item) {
item.isLast = Qt.binding(() => {
for (var i = centerRepeater.count - 1; i >= 0; i--) {
const checkItem = centerRepeater.itemAt(i);
if (checkItem && checkItem.active && checkItem.item) {
return checkItem.item === item;
}
}
return false;
});
}
if ("isLeftBarEdge" in item) {
item.isLeftBarEdge = false;
}
if ("isRightBarEdge" in item) {
item.isRightBarEdge = false;
}
if ("isTopBarEdge" in item) {
item.isTopBarEdge = false;
}
if ("isBottomBarEdge" in item) {
item.isBottomBarEdge = false;
}
if (item.pluginService !== undefined) {
var parts = model.widgetId.split(":");
var pluginId = parts[0];
var variantId = parts.length > 1 ? parts[1] : null;
if (item.pluginId !== undefined) {
item.pluginId = pluginId;
}
if (item.variantId !== undefined) {
item.variantId = variantId;
}
if (item.variantData !== undefined && variantId) {
item.variantData = PluginService.getPluginVariantData(pluginId, variantId);
}
item.pluginService = PluginService;
}
if (item.popoutService !== undefined) {
item.popoutService = PopoutService;
}
layoutTimer.restart();
}
onActiveChanged: {
layoutTimer.restart();
}
}
}
Connections {
target: PluginService
function onPluginLoaded(pluginId) {
// Force refresh of component lookups
for (var i = 0; i < centerRepeater.count; i++) {
var item = centerRepeater.itemAt(i);
if (item && item.widgetId.startsWith(pluginId)) {
item.sourceComponent = root.getWidgetComponent(item.widgetId);
}
}
}
function onPluginUnloaded(pluginId) {
// Force refresh of component lookups
for (var i = 0; i < centerRepeater.count; i++) {
var item = centerRepeater.itemAt(i);
if (item && item.widgetId.startsWith(pluginId)) {
item.sourceComponent = root.getWidgetComponent(item.widgetId);
}
} }
} }
} }

View File

@@ -130,7 +130,7 @@ Item {
{ {
"id": "gpuTemp", "id": "gpuTemp",
"text": I18n.tr("GPU Temperature"), "text": I18n.tr("GPU Temperature"),
"description": I18n.tr("GPU temperature display"), "description": "",
"icon": "auto_awesome_mosaic", "icon": "auto_awesome_mosaic",
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : I18n.tr("This widget prevents GPU power off states, which can significantly impact battery life on laptops. It is not recommended to use this on laptops with hybrid graphics."), "warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : I18n.tr("This widget prevents GPU power off states, which can significantly impact battery life on laptops. It is not recommended to use this on laptops with hybrid graphics."),
"enabled": DgopService.dgopAvailable "enabled": DgopService.dgopAvailable

View File

@@ -168,7 +168,17 @@ Column {
} }
StyledText { StyledText {
text: modelData.description text: {
if (modelData.id === "gpuTemp") {
var selectedIdx = modelData.selectedGpuIndex !== undefined ? modelData.selectedGpuIndex : 0;
if (DgopService.availableGpus && DgopService.availableGpus.length > selectedIdx) {
var gpu = DgopService.availableGpus[selectedIdx];
return gpu.driver ? gpu.driver.toUpperCase() : "";
}
return I18n.tr("No GPU detected");
}
return modelData.description;
}
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6) color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6)
elide: Text.ElideRight elide: Text.ElideRight
@@ -185,39 +195,37 @@ Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS spacing: Theme.spacingXS
Item { DankActionButton {
width: 60 id: gpuMenuButton
height: 32
visible: modelData.id === "gpuTemp" visible: modelData.id === "gpuTemp"
buttonSize: 32
iconName: "more_vert"
iconSize: 18
iconColor: Theme.outline
onClicked: {
gpuContextMenu.widgetData = modelData;
gpuContextMenu.sectionId = root.sectionId;
gpuContextMenu.widgetIndex = index;
DankDropdown { var buttonPos = gpuMenuButton.mapToItem(root, 0, 0);
id: gpuDropdown var popupWidth = gpuContextMenu.width;
anchors.fill: parent var popupHeight = gpuContextMenu.height;
popupWidth: -1
currentValue: { var xPos = buttonPos.x - popupWidth - Theme.spacingS;
var selectedIndex = modelData.selectedGpuIndex !== undefined ? modelData.selectedGpuIndex : 0; if (xPos < 0) {
if (DgopService.availableGpus && DgopService.availableGpus.length > selectedIndex && selectedIndex >= 0) { xPos = buttonPos.x + gpuMenuButton.width + Theme.spacingS;
var gpu = DgopService.availableGpus[selectedIndex];
return gpu.driver.toUpperCase();
}
return DgopService.availableGpus && DgopService.availableGpus.length > 0 ? DgopService.availableGpus[0].driver.toUpperCase() : "";
}
options: {
var gpuOptions = [];
if (DgopService.availableGpus && DgopService.availableGpus.length > 0) {
for (var i = 0; i < DgopService.availableGpus.length; i++) {
var gpu = DgopService.availableGpus[i];
gpuOptions.push(gpu.driver.toUpperCase());
}
}
return gpuOptions;
}
onValueChanged: value => {
var gpuIndex = options.indexOf(value);
if (gpuIndex >= 0) {
root.gpuSelectionChanged(root.sectionId, index, gpuIndex);
} }
var yPos = buttonPos.y - popupHeight / 2 + gpuMenuButton.height / 2;
if (yPos < 0) {
yPos = Theme.spacingS;
} else if (yPos + popupHeight > root.height) {
yPos = root.height - popupHeight - Theme.spacingS;
} }
gpuContextMenu.x = xPos;
gpuContextMenu.y = yPos;
gpuContextMenu.open();
} }
} }
@@ -1123,4 +1131,112 @@ Column {
} }
} }
} }
Popup {
id: gpuContextMenu
property var widgetData: null
property string sectionId: ""
property int widgetIndex: -1
width: 250
height: gpuMenuColumn.implicitHeight + Theme.spacingS * 2
padding: 0
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 0
}
contentItem: Item {
Column {
id: gpuMenuColumn
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: 2
Repeater {
model: DgopService.availableGpus || []
delegate: Rectangle {
required property var modelData
required property int index
width: gpuMenuColumn.width
height: 40
radius: Theme.cornerRadius
color: gpuOptionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
property bool isSelected: {
var selectedIdx = gpuContextMenu.widgetData ? (gpuContextMenu.widgetData.selectedGpuIndex !== undefined ? gpuContextMenu.widgetData.selectedGpuIndex : 0) : 0;
return index === selectedIdx;
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.right: checkIcon.left
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "memory"
size: 18
color: isSelected ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Column {
anchors.verticalCenter: parent.verticalCenter
spacing: 2
StyledText {
text: modelData.driver ? modelData.driver.toUpperCase() : ""
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: isSelected ? Theme.primary : Theme.surfaceText
}
StyledText {
text: modelData.displayName || ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideRight
width: 180
}
}
}
DankIcon {
id: checkIcon
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
name: "check"
size: 18
color: Theme.primary
visible: isSelected
}
MouseArea {
id: gpuOptionArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.gpuSelectionChanged(gpuContextMenu.sectionId, gpuContextMenu.widgetIndex, index);
gpuContextMenu.close();
}
}
}
}
}
}
}
} }