1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 04:42:05 -04:00
Files
DankMaterialShell/quickshell/Modules/Settings/WidgetsTab.qml
Ron Harel 7826d827dd feat: add configurable control center group ordering (#2006)
* Add grouped element reordering to control center setting popup.

Reorganize the control center widget menu into grouped rows and add drag handles for reordering.
Introduce controlCenterGroups to drive the grouped popup layout, along with dynamic content width calculation.
Disable dependent options when their parent icon is turned off, and refine DankToggle disabled colors to better distinguish checked and unchecked states.

* Apply Control Center group order to live widget rendering.

Apply persisted `controlCenterGroupOrder` to the actual control center button rendering path instead of only using it in the settings UI.
This refactors `ControlCenterButton.qml` to derive a normalized effective group order, build a small render model from that order, and use model-driven rendering for both vertical and horizontal layouts.

Highlights:
- add a default control center group order and normalize saved order data
- ignore unknown ids, deduplicate duplicates, and append missing known groups
- add shared group visibility helpers and derive a render model from them
- render both vertical and horizontal indicators from the effective order
- preserve existing icon, color, percent text, and visibility behavior
- keep the fallback settings icon outside persisted ordering
- reconnect cached interaction refs for audio, mic, and brightness to the real rendered group containers so wheel and right-click behavior still work
- clear and refresh interaction refs on orientation, visibility, and delegate lifecycle changes
- tighten horizontal composite group sizing by measuring actual rendered content, fixing extra spacing around the audio indicator

Also updates the settings widgets UI to persist and restore control center group ordering consistently with the live control center rendering.
2026-03-16 11:11:26 -04:00

1144 lines
49 KiB
QML

import QtQuick
import QtQuick.Layouts
import Quickshell
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: widgetsTab
property var parentModal: null
property string selectedBarId: "default"
property var selectedBarConfig: {
selectedBarId;
SettingsData.barConfigs;
const index = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId);
return index !== -1 ? SettingsData.barConfigs[index] : SettingsData.barConfigs[0];
}
property bool selectedBarIsVertical: {
selectedBarId;
const pos = selectedBarConfig?.position ?? SettingsData.Position.Top;
return pos === SettingsData.Position.Left || pos === SettingsData.Position.Right;
}
property bool hasMultipleBars: SettingsData.barConfigs.length > 1
DankTooltipV2 {
id: sharedTooltip
}
property var baseWidgetDefinitions: {
var coreWidgets = [
{
"id": "layout",
"text": I18n.tr("Layout"),
"description": I18n.tr("Display and switch DWL layouts"),
"icon": "view_quilt",
"enabled": CompositorService.isDwl && DwlService.dwlAvailable,
"warning": !CompositorService.isDwl ? I18n.tr("Requires DWL compositor") : (!DwlService.dwlAvailable ? I18n.tr("DWL service not available") : undefined)
},
{
"id": "launcherButton",
"text": I18n.tr("App Launcher"),
"description": I18n.tr("Quick access to application launcher"),
"icon": "apps",
"enabled": true
},
{
"id": "workspaceSwitcher",
"text": I18n.tr("Workspace Switcher"),
"description": I18n.tr("Shows current workspace and allows switching"),
"icon": "view_module",
"enabled": true
},
{
"id": "focusedWindow",
"text": I18n.tr("Focused Window"),
"description": I18n.tr("Display currently focused application title"),
"icon": "window",
"enabled": true
},
{
"id": "runningApps",
"text": I18n.tr("Running Apps"),
"description": I18n.tr("Shows all running applications with focus indication"),
"icon": "apps",
"enabled": true
},
{
"id": "appsDock",
"text": I18n.tr("Apps Dock"),
"description": I18n.tr("Pinned and running apps with drag-and-drop"),
"icon": "dock_to_bottom",
"enabled": true
},
{
"id": "clock",
"text": I18n.tr("Clock"),
"description": I18n.tr("Current time and date display"),
"icon": "schedule",
"enabled": true
},
{
"id": "weather",
"text": I18n.tr("Weather Widget"),
"description": I18n.tr("Current weather conditions and temperature"),
"icon": "wb_sunny",
"enabled": true
},
{
"id": "music",
"text": I18n.tr("Media Controls"),
"description": I18n.tr("Control currently playing media"),
"icon": "music_note",
"enabled": true
},
{
"id": "clipboard",
"text": I18n.tr("Clipboard Manager"),
"description": I18n.tr("Access clipboard history"),
"icon": "content_paste",
"enabled": true
},
{
"id": "cpuUsage",
"text": I18n.tr("CPU Usage"),
"description": I18n.tr("CPU usage indicator"),
"icon": "memory",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
},
{
"id": "memUsage",
"text": I18n.tr("Memory Usage"),
"description": I18n.tr("Memory usage indicator"),
"icon": "developer_board",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
},
{
"id": "diskUsage",
"text": I18n.tr("Disk Usage"),
"description": I18n.tr("Percentage"),
"icon": "storage",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
},
{
"id": "cpuTemp",
"text": I18n.tr("CPU Temperature"),
"description": I18n.tr("CPU temperature display"),
"icon": "device_thermostat",
"enabled": DgopService.dgopAvailable,
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined
},
{
"id": "gpuTemp",
"text": I18n.tr("GPU Temperature"),
"description": "",
"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."),
"enabled": DgopService.dgopAvailable
},
{
"id": "systemTray",
"text": I18n.tr("System Tray"),
"description": I18n.tr("System notification area icons"),
"icon": "notifications",
"enabled": true
},
{
"id": "privacyIndicator",
"text": I18n.tr("Privacy Indicator"),
"description": I18n.tr("Shows when microphone, camera, or screen sharing is active"),
"icon": "privacy_tip",
"enabled": true
},
{
"id": "controlCenterButton",
"text": I18n.tr("Control Center"),
"description": I18n.tr("Access to system controls and settings"),
"icon": "settings",
"enabled": true
},
{
"id": "notificationButton",
"text": I18n.tr("Notification Center"),
"description": I18n.tr("Access to notifications and do not disturb"),
"icon": "notifications",
"enabled": true
},
{
"id": "battery",
"text": I18n.tr("Battery"),
"description": I18n.tr("Battery level and power management"),
"icon": "battery_std",
"enabled": true
},
{
"id": "vpn",
"text": I18n.tr("VPN"),
"description": I18n.tr("VPN status and quick connect"),
"icon": "vpn_lock",
"enabled": true
},
{
"id": "idleInhibitor",
"text": I18n.tr("Idle Inhibitor"),
"description": I18n.tr("Prevent screen timeout"),
"icon": "motion_sensor_active",
"enabled": true
},
{
"id": "capsLockIndicator",
"text": I18n.tr("Caps Lock Indicator"),
"description": I18n.tr("Shows when caps lock is active"),
"icon": "shift_lock",
"enabled": true
},
{
"id": "spacer",
"text": I18n.tr("Spacer"),
"description": I18n.tr("Customizable empty space"),
"icon": "more_horiz",
"enabled": true
},
{
"id": "separator",
"text": I18n.tr("Separator"),
"description": I18n.tr("Visual divider between widgets"),
"icon": "remove",
"enabled": true
},
{
"id": "network_speed_monitor",
"text": I18n.tr("Network Speed Monitor"),
"description": I18n.tr("Network download and upload speed display"),
"icon": "network_check",
"warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined,
"enabled": DgopService.dgopAvailable
},
{
"id": "keyboard_layout_name",
"text": I18n.tr("Keyboard Layout Name"),
"description": I18n.tr("Displays the active keyboard layout and allows switching"),
"icon": "keyboard"
},
{
"id": "notepadButton",
"text": I18n.tr("Notepad"),
"description": I18n.tr("Quick access to notepad"),
"icon": "assignment",
"enabled": true
},
{
"id": "colorPicker",
"text": I18n.tr("Color Picker"),
"description": I18n.tr("Quick access to color picker"),
"icon": "palette",
"enabled": true
},
{
"id": "systemUpdate",
"text": I18n.tr("System Update"),
"description": I18n.tr("Check for system updates"),
"icon": "update",
"enabled": SystemUpdateService.distributionSupported
},
{
"id": "powerMenuButton",
"text": I18n.tr("Power"),
"description": I18n.tr("Display the power system menu"),
"icon": "power_settings_new",
"enabled": true
},
];
var allPluginVariants = PluginService.getAllPluginVariants();
for (var i = 0; i < allPluginVariants.length; i++) {
var variant = allPluginVariants[i];
coreWidgets.push({
"id": variant.fullId,
"text": variant.name,
"description": variant.description,
"icon": variant.icon,
"enabled": variant.loaded,
"warning": !variant.loaded ? I18n.tr("Plugin is disabled - enable in Plugins settings to use") : undefined
});
}
return coreWidgets;
}
property var defaultLeftWidgets: [
{
"id": "launcherButton",
"enabled": true
},
{
"id": "workspaceSwitcher",
"enabled": true
},
{
"id": "focusedWindow",
"enabled": true
}
]
property var defaultCenterWidgets: [
{
"id": "music",
"enabled": true
},
{
"id": "clock",
"enabled": true
},
{
"id": "weather",
"enabled": true
}
]
property var defaultRightWidgets: [
{
"id": "systemTray",
"enabled": true
},
{
"id": "clipboard",
"enabled": true
},
{
"id": "notificationButton",
"enabled": true
},
{
"id": "battery",
"enabled": true
},
{
"id": "controlCenterButton",
"enabled": true
}
]
function getWidgetsForSection(sectionId) {
switch (sectionId) {
case "left":
return selectedBarConfig?.leftWidgets || [];
case "center":
return selectedBarConfig?.centerWidgets || [];
case "right":
return selectedBarConfig?.rightWidgets || [];
default:
return [];
}
}
function setWidgetsForSection(sectionId, widgets) {
switch (sectionId) {
case "left":
SettingsData.updateBarConfig(selectedBarId, {
leftWidgets: widgets
});
break;
case "center":
SettingsData.updateBarConfig(selectedBarId, {
centerWidgets: widgets
});
break;
case "right":
SettingsData.updateBarConfig(selectedBarId, {
rightWidgets: widgets
});
break;
}
}
function getWidgetsForPopup() {
return baseWidgetDefinitions.filter(widget => {
if (widget.warning && widget.warning.includes("Plugin is disabled"))
return false;
if (widget.enabled === false)
return false;
return true;
});
}
function addWidgetToSection(widgetId, targetSection) {
var widgetObj = {
"id": widgetId,
"enabled": true
};
if (widgetId === "spacer")
widgetObj.size = 20;
if (widgetId === "gpuTemp") {
widgetObj.selectedGpuIndex = 0;
widgetObj.pciId = "";
}
if (widgetId === "controlCenterButton") {
widgetObj.showNetworkIcon = SettingsData.controlCenterShowNetworkIcon;
widgetObj.showBluetoothIcon = SettingsData.controlCenterShowBluetoothIcon;
widgetObj.showAudioIcon = SettingsData.controlCenterShowAudioIcon;
widgetObj.showAudioPercent = SettingsData.controlCenterShowAudioPercent;
widgetObj.showVpnIcon = SettingsData.controlCenterShowVpnIcon;
widgetObj.showBrightnessIcon = SettingsData.controlCenterShowBrightnessIcon;
widgetObj.showBrightnessPercent = SettingsData.controlCenterShowBrightnessPercent;
widgetObj.showMicIcon = SettingsData.controlCenterShowMicIcon;
widgetObj.showMicPercent = SettingsData.controlCenterShowMicPercent;
widgetObj.showBatteryIcon = SettingsData.controlCenterShowBatteryIcon;
widgetObj.showPrinterIcon = SettingsData.controlCenterShowPrinterIcon;
widgetObj.showScreenSharingIcon = SettingsData.controlCenterShowScreenSharingIcon;
widgetObj.controlCenterGroupOrder = ["network", "vpn", "bluetooth", "audio", "microphone", "brightness", "battery", "printer", "screenSharing"];
}
if (widgetId === "runningApps") {
widgetObj.runningAppsCompactMode = SettingsData.runningAppsCompactMode;
widgetObj.runningAppsGroupByApp = SettingsData.runningAppsGroupByApp;
widgetObj.runningAppsCurrentWorkspace = SettingsData.runningAppsCurrentWorkspace;
widgetObj.runningAppsCurrentMonitor = false;
}
if (widgetId === "diskUsage") {
widgetObj.mountPath = "/";
widgetObj.diskUsageMode = 0;
}
if (widgetId === "cpuUsage" || widgetId === "memUsage" || widgetId === "cpuTemp" || widgetId === "gpuTemp")
widgetObj.minimumWidth = true;
if (widgetId === "memUsage")
widgetObj.showInGb = false;
var widgets = getWidgetsForSection(targetSection).slice();
widgets.push(widgetObj);
setWidgetsForSection(targetSection, widgets);
}
function removeWidgetFromSection(sectionId, widgetIndex) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex >= 0 && widgetIndex < widgets.length)
widgets.splice(widgetIndex, 1);
setWidgetsForSection(sectionId, widgets);
}
function cloneWidgetData(widget) {
if (typeof widget === "string")
return {
"id": widget,
"enabled": true
};
var result = {
"id": widget.id,
"enabled": widget.enabled
};
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"];
for (var i = 0; i < keys.length; i++) {
if (widget[keys[i]] !== undefined)
result[keys[i]] = widget[keys[i]];
}
return result;
}
function handleItemEnabledChanged(sectionId, itemId, enabled) {
var widgets = getWidgetsForSection(sectionId).slice();
for (var i = 0; i < widgets.length; i++) {
var widget = widgets[i];
var widgetId = typeof widget === "string" ? widget : widget.id;
if (widgetId !== itemId)
continue;
var newWidget = cloneWidgetData(widget);
newWidget.enabled = enabled;
widgets[i] = newWidget;
break;
}
setWidgetsForSection(sectionId, widgets);
}
function handleItemOrderChanged(sectionId, newOrder) {
setWidgetsForSection(sectionId, newOrder);
}
function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length)
return;
var widget = widgets[widgetIndex];
var widgetId = typeof widget === "string" ? widget : widget.id;
if (widgetId !== "spacer")
return;
var newWidget = cloneWidgetData(widget);
newWidget.size = newSize;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length)
return;
var pciId = DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : "";
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.selectedGpuIndex = selectedGpuIndex;
newWidget.pciId = pciId;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleDiskMountSelectionChanged(sectionId, widgetIndex, mountPath) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length)
return;
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.mountPath = mountPath;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length)
return;
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget[settingName] = value;
if (!value) {
switch (settingName) {
case "showAudioIcon":
newWidget.showAudioPercent = false;
break;
case "showMicIcon":
newWidget.showMicPercent = false;
break;
case "showBrightnessIcon":
newWidget.showBrightnessPercent = false;
break;
}
}
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleControlCenterGroupOrderChanged(sectionId, widgetIndex, groupOrder) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length)
return;
var previousWidget = widgets[widgetIndex];
var newWidget = cloneWidgetData(previousWidget);
newWidget.controlCenterGroupOrder = groupOrder.slice();
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handlePrivacySettingChanged(sectionId, widgetIndex, settingName, value) {
switch (settingName) {
case "showMicIcon":
SettingsData.set("privacyShowMicIcon", value);
break;
case "showCameraIcon":
SettingsData.set("privacyShowCameraIcon", value);
break;
case "showScreenSharingIcon":
SettingsData.set("privacyShowScreenShareIcon", value);
break;
}
}
function handleMinimumWidthChanged(sectionId, widgetIndex, enabled) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
setWidgetsForSection(sectionId, widgets);
return;
}
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.minimumWidth = enabled;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleShowSwapChanged(sectionId, widgetIndex, enabled) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
setWidgetsForSection(sectionId, widgets);
return;
}
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.showSwap = enabled;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleShowInGbChanged(sectionId, widgetIndex, enabled) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
setWidgetsForSection(sectionId, widgets);
return;
}
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.showInGb = enabled;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleDiskUsageModeChanged(sectionId, widgetIndex, mode) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
setWidgetsForSection(sectionId, widgets);
return;
}
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget.diskUsageMode = mode;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value) {
var widgets = getWidgetsForSection(sectionId).slice();
if (widgetIndex < 0 || widgetIndex >= widgets.length) {
setWidgetsForSection(sectionId, widgets);
return;
}
var newWidget = cloneWidgetData(widgets[widgetIndex]);
newWidget[settingName] = value;
widgets[widgetIndex] = newWidget;
setWidgetsForSection(sectionId, widgets);
}
function handleCompactModeChanged(sectionId, widgetId, value) {
var widgets = getWidgetsForSection(sectionId).slice();
for (var i = 0; i < widgets.length; i++) {
var widget = widgets[i];
var currentId = typeof widget === "string" ? widget : widget.id;
if (currentId !== widgetId)
continue;
var newWidget = cloneWidgetData(widget);
switch (widgetId) {
case "music":
newWidget.mediaSize = value;
break;
case "clock":
newWidget.clockCompactMode = value;
break;
case "focusedWindow":
newWidget.focusedWindowCompactMode = value;
break;
case "runningApps":
newWidget.runningAppsCompactMode = value;
break;
case "keyboard_layout_name":
newWidget.keyboardLayoutNameCompactMode = value;
break;
}
widgets[i] = newWidget;
break;
}
setWidgetsForSection(sectionId, widgets);
}
function getItemsForSection(sectionId) {
var widgets = [];
var widgetData = getWidgetsForSection(sectionId);
widgetData.forEach(widget => {
var isString = typeof widget === "string";
var widgetId = isString ? widget : widget.id;
var widgetDef = baseWidgetDefinitions.find(w => w.id === widgetId);
if (!widgetDef)
return;
var item = Object.assign({}, widgetDef);
item.enabled = isString ? true : widget.enabled;
if (!isString) {
if (widget.size !== undefined)
item.size = widget.size;
if (widget.selectedGpuIndex !== undefined)
item.selectedGpuIndex = widget.selectedGpuIndex;
if (widget.pciId !== undefined)
item.pciId = widget.pciId;
if (widget.mountPath !== undefined)
item.mountPath = widget.mountPath;
if (widget.diskUsageMode !== undefined)
item.diskUsageMode = widget.diskUsageMode;
if (widget.showNetworkIcon !== undefined)
item.showNetworkIcon = widget.showNetworkIcon;
if (widget.showBluetoothIcon !== undefined)
item.showBluetoothIcon = widget.showBluetoothIcon;
if (widget.showAudioIcon !== undefined)
item.showAudioIcon = widget.showAudioIcon;
if (widget.showAudioPercent !== undefined)
item.showAudioPercent = widget.showAudioPercent;
if (widget.showVpnIcon !== undefined)
item.showVpnIcon = widget.showVpnIcon;
if (widget.showBrightnessIcon !== undefined)
item.showBrightnessIcon = widget.showBrightnessIcon;
if (widget.showBrightnessPercent !== undefined)
item.showBrightnessPercent = widget.showBrightnessPercent;
if (widget.showMicIcon !== undefined)
item.showMicIcon = widget.showMicIcon;
if (widget.showMicPercent !== undefined)
item.showMicPercent = widget.showMicPercent;
if (widget.showBatteryIcon !== undefined)
item.showBatteryIcon = widget.showBatteryIcon;
if (widget.showPrinterIcon !== undefined)
item.showPrinterIcon = widget.showPrinterIcon;
if (widget.showScreenSharingIcon !== undefined)
item.showScreenSharingIcon = widget.showScreenSharingIcon;
if (widget.controlCenterGroupOrder !== undefined)
item.controlCenterGroupOrder = widget.controlCenterGroupOrder;
if (widget.minimumWidth !== undefined)
item.minimumWidth = widget.minimumWidth;
if (widget.showSwap !== undefined)
item.showSwap = widget.showSwap;
if (widget.showInGb !== undefined)
item.showInGb = widget.showInGb;
if (widget.mediaSize !== undefined)
item.mediaSize = widget.mediaSize;
if (widget.clockCompactMode !== undefined)
item.clockCompactMode = widget.clockCompactMode;
if (widget.focusedWindowCompactMode !== undefined)
item.focusedWindowCompactMode = widget.focusedWindowCompactMode;
if (widget.runningAppsCompactMode !== undefined)
item.runningAppsCompactMode = widget.runningAppsCompactMode;
if (widget.runningAppsGroupByApp !== undefined)
item.runningAppsGroupByApp = widget.runningAppsGroupByApp;
if (widget.runningAppsCurrentWorkspace !== undefined)
item.runningAppsCurrentWorkspace = widget.runningAppsCurrentWorkspace;
if (widget.runningAppsCurrentMonitor !== undefined)
item.runningAppsCurrentMonitor = widget.runningAppsCurrentMonitor;
if (widget.keyboardLayoutNameCompactMode !== undefined)
item.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode;
if (widget.barMaxVisibleApps !== undefined)
item.barMaxVisibleApps = widget.barMaxVisibleApps;
if (widget.barMaxVisibleRunningApps !== undefined)
item.barMaxVisibleRunningApps = widget.barMaxVisibleRunningApps;
if (widget.barShowOverflowBadge !== undefined)
item.barShowOverflowBadge = widget.barShowOverflowBadge;
}
widgets.push(item);
});
return widgets;
}
Component.onCompleted: {
const leftWidgets = selectedBarConfig?.leftWidgets;
const centerWidgets = selectedBarConfig?.centerWidgets;
const rightWidgets = selectedBarConfig?.rightWidgets;
if (!leftWidgets)
setWidgetsForSection("left", defaultLeftWidgets);
if (!centerWidgets)
setWidgetsForSection("center", defaultCenterWidgets);
if (!rightWidgets)
setWidgetsForSection("right", defaultRightWidgets);
const sections = ["left", "center", "right"];
sections.forEach(sectionId => {
var widgets = getWidgetsForSection(sectionId).slice();
var updated = false;
for (var i = 0; i < widgets.length; i++) {
var widget = widgets[i];
if (typeof widget === "object" && widget.id === "spacer" && !widget.size) {
widgets[i] = Object.assign({}, widget, {
"size": 20
});
updated = true;
}
}
if (updated)
setWidgetsForSection(sectionId, widgets);
});
}
LazyLoader {
id: widgetSelectionPopupLoader
active: false
WidgetSelectionPopup {
id: widgetSelectionPopupItem
parentModal: widgetsTab.parentModal
onWidgetSelected: (widgetId, targetSection) => {
widgetsTab.addWidgetToSection(widgetId, targetSection);
}
}
}
function showWidgetSelectionPopup(sectionId) {
widgetSelectionPopupLoader.active = true;
if (!widgetSelectionPopupLoader.item)
return;
widgetSelectionPopupLoader.item.targetSection = sectionId;
widgetSelectionPopupLoader.item.allWidgets = widgetsTab.getWidgetsForPopup();
widgetSelectionPopupLoader.item.show();
}
DankFlickable {
anchors.fill: parent
clip: true
contentHeight: mainColumn.height + Theme.spacingXL
contentWidth: width
Column {
id: mainColumn
topPadding: 4
width: Math.min(550, parent.width - Theme.spacingL * 2)
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingXL
StyledRect {
width: parent.width
height: barSelectorContent.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
visible: hasMultipleBars
Column {
id: barSelectorContent
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "toolbar"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Select Bar")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankButtonGroup {
id: barSelectorGroup
width: parent.width
model: SettingsData.barConfigs.map(cfg => cfg.name || ("Bar " + (SettingsData.barConfigs.indexOf(cfg) + 1)))
currentIndex: {
const idx = SettingsData.barConfigs.findIndex(cfg => cfg.id === selectedBarId);
return idx >= 0 ? idx : 0;
}
checkEnabled: false
onSelectionChanged: (index, selected) => {
if (!selected)
return;
if (index >= 0 && index < SettingsData.barConfigs.length)
selectedBarId = SettingsData.barConfigs[index].id;
}
}
}
}
StyledRect {
width: parent.width
height: widgetManagementHeader.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
Column {
id: widgetManagementHeader
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
RowLayout {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "widgets"
size: Theme.iconSize
color: Theme.primary
Layout.alignment: Qt.AlignVCenter
}
StyledText {
text: I18n.tr("Widget Management")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
Layout.alignment: Qt.AlignVCenter
}
Item {
height: 1
Layout.fillWidth: true
}
Rectangle {
width: resetContentRow.implicitWidth + Theme.spacingM * 2
height: 28
radius: Theme.cornerRadius
color: resetArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariant
Layout.alignment: Qt.AlignVCenter
border.width: 0
Row {
id: resetContentRow
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "refresh"
size: 14
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Reset")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: resetArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
setWidgetsForSection("left", defaultLeftWidgets);
setWidgetsForSection("center", defaultCenterWidgets);
setWidgetsForSection("right", defaultRightWidgets);
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
StyledText {
width: parent.width
text: I18n.tr("Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
}
}
}
Column {
width: parent.width
spacing: Theme.spacingL
StyledRect {
width: parent.width
height: leftSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
WidgetsTabSection {
id: leftSection
anchors.fill: parent
anchors.margins: Theme.spacingL
title: selectedBarIsVertical ? I18n.tr("Top Section") : I18n.tr("Left Section")
titleIcon: "format_align_left"
sectionId: "left"
allWidgets: widgetsTab.baseWidgetDefinitions
items: widgetsTab.getItemsForSection("left")
onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
}
onItemOrderChanged: newOrder => {
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
}
onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId);
}
onRemoveWidget: (sectionId, index) => {
widgetsTab.removeWidgetFromSection(sectionId, index);
}
onSpacerSizeChanged: (sectionId, index, size) => {
widgetsTab.handleSpacerSizeChanged(sectionId, index, size);
}
onGpuSelectionChanged: (sectionId, index, gpuIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, index, gpuIndex);
}
onDiskMountSelectionChanged: (sectionId, index, mountPath) => {
widgetsTab.handleDiskMountSelectionChanged(sectionId, index, mountPath);
}
onControlCenterSettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handleControlCenterSettingChanged(sectionId, index, setting, value);
}
onControlCenterGroupOrderChanged: (sectionId, index, groupOrder) => {
widgetsTab.handleControlCenterGroupOrderChanged(sectionId, index, groupOrder);
}
onPrivacySettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handlePrivacySettingChanged(sectionId, index, setting, value);
}
onMinimumWidthChanged: (sectionId, index, enabled) => {
widgetsTab.handleMinimumWidthChanged(sectionId, index, enabled);
}
onShowSwapChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
}
onShowInGbChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
}
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
}
onCompactModeChanged: (widgetId, value) => {
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
}
onOverflowSettingChanged: (sectionId, widgetIndex, settingName, value) => {
widgetsTab.handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value);
}
}
}
StyledRect {
width: parent.width
height: centerSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
WidgetsTabSection {
id: centerSection
anchors.fill: parent
anchors.margins: Theme.spacingL
title: selectedBarIsVertical ? I18n.tr("Middle Section") : I18n.tr("Center Section")
titleIcon: "format_align_center"
sectionId: "center"
allWidgets: widgetsTab.baseWidgetDefinitions
items: widgetsTab.getItemsForSection("center")
onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
}
onItemOrderChanged: newOrder => {
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
}
onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId);
}
onRemoveWidget: (sectionId, index) => {
widgetsTab.removeWidgetFromSection(sectionId, index);
}
onSpacerSizeChanged: (sectionId, index, size) => {
widgetsTab.handleSpacerSizeChanged(sectionId, index, size);
}
onGpuSelectionChanged: (sectionId, index, gpuIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, index, gpuIndex);
}
onDiskMountSelectionChanged: (sectionId, index, mountPath) => {
widgetsTab.handleDiskMountSelectionChanged(sectionId, index, mountPath);
}
onControlCenterSettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handleControlCenterSettingChanged(sectionId, index, setting, value);
}
onControlCenterGroupOrderChanged: (sectionId, index, groupOrder) => {
widgetsTab.handleControlCenterGroupOrderChanged(sectionId, index, groupOrder);
}
onPrivacySettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handlePrivacySettingChanged(sectionId, index, setting, value);
}
onMinimumWidthChanged: (sectionId, index, enabled) => {
widgetsTab.handleMinimumWidthChanged(sectionId, index, enabled);
}
onShowSwapChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
}
onShowInGbChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
}
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
}
onCompactModeChanged: (widgetId, value) => {
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
}
onOverflowSettingChanged: (sectionId, widgetIndex, settingName, value) => {
widgetsTab.handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value);
}
}
}
StyledRect {
width: parent.width
height: rightSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
border.width: 0
WidgetsTabSection {
id: rightSection
anchors.fill: parent
anchors.margins: Theme.spacingL
title: selectedBarIsVertical ? I18n.tr("Bottom Section") : I18n.tr("Right Section")
titleIcon: "format_align_right"
sectionId: "right"
allWidgets: widgetsTab.baseWidgetDefinitions
items: widgetsTab.getItemsForSection("right")
onItemEnabledChanged: (sectionId, itemId, enabled) => {
widgetsTab.handleItemEnabledChanged(sectionId, itemId, enabled);
}
onItemOrderChanged: newOrder => {
widgetsTab.handleItemOrderChanged(sectionId, newOrder);
}
onAddWidget: sectionId => {
showWidgetSelectionPopup(sectionId);
}
onRemoveWidget: (sectionId, index) => {
widgetsTab.removeWidgetFromSection(sectionId, index);
}
onSpacerSizeChanged: (sectionId, index, size) => {
widgetsTab.handleSpacerSizeChanged(sectionId, index, size);
}
onGpuSelectionChanged: (sectionId, index, gpuIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, index, gpuIndex);
}
onDiskMountSelectionChanged: (sectionId, index, mountPath) => {
widgetsTab.handleDiskMountSelectionChanged(sectionId, index, mountPath);
}
onControlCenterSettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handleControlCenterSettingChanged(sectionId, index, setting, value);
}
onControlCenterGroupOrderChanged: (sectionId, index, groupOrder) => {
widgetsTab.handleControlCenterGroupOrderChanged(sectionId, index, groupOrder);
}
onPrivacySettingChanged: (sectionId, index, setting, value) => {
widgetsTab.handlePrivacySettingChanged(sectionId, index, setting, value);
}
onMinimumWidthChanged: (sectionId, index, enabled) => {
widgetsTab.handleMinimumWidthChanged(sectionId, index, enabled);
}
onShowSwapChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowSwapChanged(sectionId, index, enabled);
}
onShowInGbChanged: (sectionId, index, enabled) => {
widgetsTab.handleShowInGbChanged(sectionId, index, enabled);
}
onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => {
widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode);
}
onCompactModeChanged: (widgetId, value) => {
widgetsTab.handleCompactModeChanged(sectionId, widgetId, value);
}
onOverflowSettingChanged: (sectionId, widgetIndex, settingName, value) => {
widgetsTab.handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value);
}
}
}
}
}
}
}