From 3462bcc46ecf74f576ea4397f16492c16bd75b10 Mon Sep 17 00:00:00 2001 From: Nippy Date: Fri, 8 May 2026 19:50:49 +0200 Subject: raveos update --- .../dms/Modules/Settings/WidgetsTabSection.qml | 2940 ++++++++++++++++++++ 1 file changed, 2940 insertions(+) create mode 100644 raveos-hyprland-theme/theme-data/dms/Modules/Settings/WidgetsTabSection.qml (limited to 'raveos-hyprland-theme/theme-data/dms/Modules/Settings/WidgetsTabSection.qml') diff --git a/raveos-hyprland-theme/theme-data/dms/Modules/Settings/WidgetsTabSection.qml b/raveos-hyprland-theme/theme-data/dms/Modules/Settings/WidgetsTabSection.qml new file mode 100644 index 0000000..88c1270 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/dms/Modules/Settings/WidgetsTabSection.qml @@ -0,0 +1,2940 @@ +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: "" + + DankTooltipV2 { + id: sharedTooltip + } + + 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, int widgetIndex, int newSize) + signal compactModeChanged(string widgetId, var value) + signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex) + signal diskMountSelectionChanged(string sectionId, int widgetIndex, string mountPath) + signal controlCenterSettingChanged(string sectionId, int widgetIndex, string settingName, bool value) + signal controlCenterGroupOrderChanged(string sectionId, int widgetIndex, var groupOrder) + signal privacySettingChanged(string sectionId, int widgetIndex, string settingName, bool value) + signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled) + signal showSwapChanged(string sectionId, int widgetIndex, bool enabled) + signal showInGbChanged(string sectionId, int widgetIndex, bool enabled) + signal diskUsageModeChanged(string sectionId, int widgetIndex, int mode) + signal overflowSettingChanged(string sectionId, int widgetIndex, string settingName, var value) + + function cloneWidgetData(widget) { + 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", "trayUseInlineExpansion"]; + for (var i = 0; i < keys.length; i++) { + if (widget[keys[i]] !== undefined) + result[keys[i]] = widget[keys[i]]; + } + return result; + } + + width: parent.width + height: implicitHeight + spacing: Theme.spacingM + + Row { + 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 + } + } + + 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: 0 + + 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: { + 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 + 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 + + DankActionButton { + id: gpuMenuButton + 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; + + var buttonPos = gpuMenuButton.mapToItem(root, 0, 0); + var popupWidth = gpuContextMenu.width; + var popupHeight = gpuContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) { + xPos = buttonPos.x + gpuMenuButton.width + Theme.spacingS; + } + + 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(); + } + } + + Item { + width: 120 + height: 32 + visible: modelData.id === "diskUsage" + DankDropdown { + id: diskMountDropdown + anchors.fill: parent + currentValue: { + const mountPath = modelData.mountPath || "/"; + if (mountPath === "/") { + return "root (/)"; + } + return mountPath; + } + options: { + if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) { + return ["root (/)"]; + } + return DgopService.diskMounts.map(mount => { + if (mount.mount === "/") { + return "root (/)"; + } + return mount.mount; + }); + } + onValueChanged: value => { + const newPath = value === "root (/)" ? "/" : value; + root.diskMountSelectionChanged(root.sectionId, index, newPath); + } + } + } + + DankActionButton { + id: diskMenuButton + visible: modelData.id === "diskUsage" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + diskUsageContextMenu.widgetData = modelData; + diskUsageContextMenu.sectionId = root.sectionId; + diskUsageContextMenu.widgetIndex = index; + + var buttonPos = diskMenuButton.mapToItem(root, 0, 0); + var xPos = buttonPos.x - diskUsageContextMenu.width - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + diskMenuButton.width + Theme.spacingS; + var yPos = buttonPos.y - diskUsageContextMenu.height / 2 + diskMenuButton.height / 2; + if (yPos < 0) + yPos = Theme.spacingS; + else if (yPos + diskUsageContextMenu.height > root.height) + yPos = root.height - diskUsageContextMenu.height - Theme.spacingS; + + diskUsageContextMenu.x = xPos; + diskUsageContextMenu.y = yPos; + diskUsageContextMenu.open(); + } + } + + Item { + width: 32 + height: 32 + visible: modelData.warning !== undefined && modelData.warning !== "" + + DankIcon { + name: "warning" + size: 20 + color: Theme.error + anchors.centerIn: parent + opacity: warningArea.containsMouse ? 1.0 : 0.8 + } + + MouseArea { + id: warningArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + } + + Rectangle { + id: warningTooltip + + property string warningText: (modelData.warning !== undefined && modelData.warning !== "") ? modelData.warning : "" + + width: Math.min(250, warningTooltipText.implicitWidth) + Theme.spacingM * 2 + height: warningTooltipText.implicitHeight + Theme.spacingS * 2 + radius: Theme.cornerRadius + color: Theme.surfaceContainer + border.color: Theme.outline + border.width: 0 + visible: warningArea.containsMouse && warningText !== "" + opacity: visible ? 1 : 0 + x: -width - Theme.spacingS + y: (parent.height - height) / 2 + z: 100 + + StyledText { + id: warningTooltipText + anchors.centerIn: parent + anchors.margins: Theme.spacingS + text: warningTooltip.warningText + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + width: Math.min(250, implicitWidth) + wrapMode: Text.WordWrap + } + + Behavior on opacity { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + DankActionButton { + id: minimumWidthButton + buttonSize: 28 + visible: modelData.id === "cpuUsage" || modelData.id === "memUsage" || modelData.id === "cpuTemp" || modelData.id === "gpuTemp" + iconName: "straighten" + iconSize: 16 + iconColor: (modelData.minimumWidth !== undefined ? modelData.minimumWidth : true) ? Theme.primary : Theme.outline + onClicked: { + var currentEnabled = modelData.minimumWidth !== undefined ? modelData.minimumWidth : true; + root.minimumWidthChanged(root.sectionId, index, !currentEnabled); + } + onEntered: { + var currentEnabled = modelData.minimumWidth !== undefined ? modelData.minimumWidth : true; + const tooltipText = currentEnabled ? "Force Padding" : "Dynamic Width"; + sharedTooltip.show(tooltipText, minimumWidthButton, 0, 0, "bottom"); + } + onExited: { + sharedTooltip.hide(); + } + } + + DankActionButton { + id: memMenuButton + visible: modelData.id === "memUsage" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + memUsageContextMenu.widgetData = modelData; + memUsageContextMenu.sectionId = root.sectionId; + memUsageContextMenu.widgetIndex = index; + + var buttonPos = memMenuButton.mapToItem(root, 0, 0); + var popupWidth = memUsageContextMenu.width; + var popupHeight = memUsageContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) { + xPos = buttonPos.x + memMenuButton.width + Theme.spacingS; + } + + var yPos = buttonPos.y - popupHeight / 2 + memMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + memUsageContextMenu.x = xPos; + memUsageContextMenu.y = yPos; + memUsageContextMenu.open(); + } + } + + DankActionButton { + id: musicMenuButton + visible: modelData.id === "music" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + musicContextMenu.widgetData = modelData; + musicContextMenu.sectionId = root.sectionId; + musicContextMenu.widgetIndex = index; + + var buttonPos = musicMenuButton.mapToItem(root, 0, 0); + var popupWidth = musicContextMenu.width; + var popupHeight = musicContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + musicMenuButton.width + Theme.spacingS; + + var yPos = buttonPos.y - popupHeight / 2 + musicMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + musicContextMenu.x = xPos; + musicContextMenu.y = yPos; + musicContextMenu.open(); + } + } + + DankActionButton { + id: runningAppsMenuButton + visible: modelData.id === "runningApps" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + runningAppsContextMenu.widgetData = modelData; + runningAppsContextMenu.sectionId = root.sectionId; + runningAppsContextMenu.widgetIndex = index; + + var buttonPos = runningAppsMenuButton.mapToItem(root, 0, 0); + var popupWidth = runningAppsContextMenu.width; + var popupHeight = runningAppsContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + runningAppsMenuButton.width + Theme.spacingS; + + var yPos = buttonPos.y - popupHeight / 2 + runningAppsMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + runningAppsContextMenu.x = xPos; + runningAppsContextMenu.y = yPos; + runningAppsContextMenu.open(); + } + } + + Row { + spacing: Theme.spacingXS + visible: modelData.id === "clock" || modelData.id === "focusedWindow" || modelData.id === "keyboard_layout_name" || modelData.id === "appsDock" || modelData.id === "systemTray" + + DankActionButton { + id: compactModeButton + buttonSize: 28 + visible: modelData.id === "clock" || modelData.id === "focusedWindow" || modelData.id === "keyboard_layout_name" + iconName: { + const isCompact = (() => { + switch (modelData.id) { + case "clock": + return modelData.clockCompactMode !== undefined ? modelData.clockCompactMode : SettingsData.clockCompactMode; + case "focusedWindow": + return modelData.focusedWindowCompactMode !== undefined ? modelData.focusedWindowCompactMode : SettingsData.focusedWindowCompactMode; + case "keyboard_layout_name": + return modelData.keyboardLayoutNameCompactMode !== undefined ? modelData.keyboardLayoutNameCompactMode : SettingsData.keyboardLayoutNameCompactMode; + default: + return false; + } + })(); + return isCompact ? "zoom_out" : "zoom_in"; + } + iconSize: 16 + iconColor: { + const isCompact = (() => { + switch (modelData.id) { + case "clock": + return modelData.clockCompactMode !== undefined ? modelData.clockCompactMode : SettingsData.clockCompactMode; + case "focusedWindow": + return modelData.focusedWindowCompactMode !== undefined ? modelData.focusedWindowCompactMode : SettingsData.focusedWindowCompactMode; + case "keyboard_layout_name": + return modelData.keyboardLayoutNameCompactMode !== undefined ? modelData.keyboardLayoutNameCompactMode : SettingsData.keyboardLayoutNameCompactMode; + default: + return false; + } + })(); + return isCompact ? Theme.primary : Theme.outline; + } + onClicked: { + const currentValue = (() => { + switch (modelData.id) { + case "clock": + return modelData.clockCompactMode !== undefined ? modelData.clockCompactMode : SettingsData.clockCompactMode; + case "focusedWindow": + return modelData.focusedWindowCompactMode !== undefined ? modelData.focusedWindowCompactMode : SettingsData.focusedWindowCompactMode; + case "keyboard_layout_name": + return modelData.keyboardLayoutNameCompactMode !== undefined ? modelData.keyboardLayoutNameCompactMode : SettingsData.keyboardLayoutNameCompactMode; + default: + return false; + } + })(); + root.compactModeChanged(modelData.id, !currentValue); + } + onEntered: { + const isCompact = (() => { + switch (modelData.id) { + case "clock": + return modelData.clockCompactMode !== undefined ? modelData.clockCompactMode : SettingsData.clockCompactMode; + case "focusedWindow": + return modelData.focusedWindowCompactMode !== undefined ? modelData.focusedWindowCompactMode : SettingsData.focusedWindowCompactMode; + case "keyboard_layout_name": + return modelData.keyboardLayoutNameCompactMode !== undefined ? modelData.keyboardLayoutNameCompactMode : SettingsData.keyboardLayoutNameCompactMode; + default: + return false; + } + })(); + const tooltipText = isCompact ? "Full Size" : "Compact"; + sharedTooltip.show(tooltipText, compactModeButton, 0, 0, "bottom"); + } + onExited: { + sharedTooltip.hide(); + } + } + + DankActionButton { + id: appsDockMenuButton + buttonSize: 32 + visible: modelData.id === "appsDock" + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + appsDockContextMenu.widgetData = modelData; + appsDockContextMenu.sectionId = root.sectionId; + appsDockContextMenu.widgetIndex = index; + + var buttonPos = appsDockMenuButton.mapToItem(root, 0, 0); + var popupWidth = appsDockContextMenu.width; + var popupHeight = appsDockContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + appsDockMenuButton.width + Theme.spacingS; + + var yPos = buttonPos.y - popupHeight / 2 + appsDockMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + appsDockContextMenu.x = xPos; + appsDockContextMenu.y = yPos; + appsDockContextMenu.open(); + } + } + + DankActionButton { + id: trayMenuButton + buttonSize: 32 + visible: modelData.id === "systemTray" + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + trayContextMenu.widgetData = modelData; + trayContextMenu.sectionId = root.sectionId; + trayContextMenu.widgetIndex = index; + + var buttonPos = trayMenuButton.mapToItem(root, 0, 0); + var popupWidth = trayContextMenu.width; + var popupHeight = trayContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + trayMenuButton.width + Theme.spacingS; + + var yPos = buttonPos.y - popupHeight / 2 + trayMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + trayContextMenu.x = xPos; + trayContextMenu.y = yPos; + trayContextMenu.open(); + } + } + + 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: 0 + visible: false + opacity: visible ? 1 : 0 + x: -width - Theme.spacingS + y: (parent.height - height) / 2 + z: 100 + + StyledText { + id: tooltipText + anchors.centerIn: parent + text: I18n.tr("Compact Mode") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + } + + Behavior on opacity { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + DankActionButton { + id: ccMenuButton + visible: modelData.id === "controlCenterButton" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + controlCenterContextMenu.widgetData = modelData; + controlCenterContextMenu.sectionId = root.sectionId; + controlCenterContextMenu.widgetIndex = index; + controlCenterContextMenu.controlCenterGroups = controlCenterContextMenu.getOrderedControlCenterGroups(); + + var buttonPos = ccMenuButton.mapToItem(root, 0, 0); + var popupWidth = controlCenterContextMenu.width; + var popupHeight = controlCenterContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) { + xPos = buttonPos.x + ccMenuButton.width + Theme.spacingS; + } + + var yPos = buttonPos.y - popupHeight / 2 + ccMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + controlCenterContextMenu.x = xPos; + controlCenterContextMenu.y = yPos; + controlCenterContextMenu.open(); + } + } + + DankActionButton { + id: privacyMenuButton + visible: modelData.id === "privacyIndicator" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + privacyContextMenu.widgetData = modelData; + privacyContextMenu.sectionId = root.sectionId; + privacyContextMenu.widgetIndex = index; + + var buttonPos = privacyMenuButton.mapToItem(root, 0, 0); + var popupWidth = privacyContextMenu.width; + var popupHeight = privacyContextMenu.height; + + var xPos = buttonPos.x - popupWidth - Theme.spacingS; + if (xPos < 0) { + xPos = buttonPos.x + privacyMenuButton.width + Theme.spacingS; + } + + var yPos = buttonPos.y - popupHeight / 2 + privacyMenuButton.height / 2; + if (yPos < 0) { + yPos = Theme.spacingS; + } else if (yPos + popupHeight > root.height) { + yPos = root.height - popupHeight - Theme.spacingS; + } + + privacyContextMenu.x = xPos; + privacyContextMenu.y = yPos; + privacyContextMenu.open(); + } + } + + DankActionButton { + id: visibilityButton + 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); + } + onEntered: { + const tooltipText = modelData.enabled ? "Hide" : "Show"; + sharedTooltip.show(tooltipText, visibilityButton, 0, 0, "bottom"); + } + onExited: { + sharedTooltip.hide(); + } + } + + 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, index, 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, index, 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 => root.cloneWidgetData(item))); + } + } + 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: 0 + anchors.horizontalCenter: parent.horizontalCenter + + StyledText { + text: I18n.tr("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 + } + } + } + + Popup { + id: memUsageContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + width: 200 + height: 80 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + radius: Theme.cornerRadius + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) + border.width: 0 + } + + contentItem: Item { + Column { + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: swapToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "swap_horiz" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Show Swap") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: swapToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: memUsageContextMenu.widgetData?.showSwap ?? false + onToggled: { + root.showSwapChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, toggled); + } + } + + MouseArea { + id: swapToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + swapToggle.checked = !swapToggle.checked; + root.showSwapChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, swapToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: gbToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "straighten" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Show in GB") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: gbToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: memUsageContextMenu.widgetData?.showInGb ?? false + onToggled: { + root.showInGbChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, toggled); + } + } + + MouseArea { + id: gbToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + gbToggle.checked = !gbToggle.checked; + root.showInGbChanged(memUsageContextMenu.sectionId, memUsageContextMenu.widgetIndex, gbToggle.checked); + } + } + } + } + } + } + + Popup { + id: trayContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData + + width: 220 + height: contentColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + 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: contentColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: trayOverflowArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "arrow_selector_tool" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Use Inline Expansion") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: trayOverflowToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false + } + + MouseArea { + id: trayOverflowArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + const newValue = !(trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false); + root.overflowSettingChanged(trayContextMenu.sectionId, trayContextMenu.widgetIndex, "trayUseInlineExpansion", newValue); + } + } + } + } + } + } + + Popup { + id: diskUsageContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData + + width: 240 + height: diskMenuColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + 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: diskMenuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: "transparent" + + StyledText { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + text: I18n.tr("Disk Usage Display") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + } + } + + Repeater { + model: [ + { + label: I18n.tr("Percentage"), + mode: 0, + icon: "percent" + }, + { + label: I18n.tr("Total"), + mode: 1, + icon: "storage" + }, + { + label: I18n.tr("Remaining"), + mode: 2, + icon: "hourglass_empty" + }, + { + label: I18n.tr("Remaining / Total"), + mode: 3, + icon: "pie_chart" + } + ] + + delegate: Rectangle { + required property var modelData + required property int index + + width: diskMenuColumn.width + height: 32 + radius: Theme.cornerRadius + color: diskOptionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + function isSelected() { + return (diskUsageContextMenu.currentWidgetData?.diskUsageMode ?? 0) === modelData.mode; + } + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: modelData.icon + size: 16 + color: isSelected() ? Theme.primary : Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: modelData.label + font.pixelSize: Theme.fontSizeSmall + color: isSelected() ? Theme.primary : Theme.surfaceText + font.weight: isSelected() ? Font.Medium : Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankIcon { + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + name: "check" + size: 16 + color: Theme.primary + visible: isSelected() + } + + MouseArea { + id: diskOptionArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + root.diskUsageModeChanged(diskUsageContextMenu.sectionId, diskUsageContextMenu.widgetIndex, modelData.mode); + diskUsageContextMenu.close(); + } + } + } + } + } + } + } + + Popup { + id: controlCenterContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + readonly property real minimumContentWidth: controlCenterContentMetrics.implicitWidth + Theme.spacingS * 2 + readonly property real controlCenterRowHeight: 32 + readonly property real controlCenterRowSpacing: 1 + readonly property real controlCenterGroupVerticalPadding: Theme.spacingXS * 2 + readonly property real controlCenterMenuSpacing: 2 + width: Math.max(220, minimumContentWidth) + height: getControlCenterPopupHeight(controlCenterGroups) + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + onClosed: { + cancelControlCenterDrag(); + } + + readonly property var defaultControlCenterGroups: [ + { + id: "network", + rows: [ + { + icon: "lan", + label: I18n.tr("Network"), + setting: "showNetworkIcon" + } + ] + }, + { + id: "vpn", + rows: [ + { + icon: "vpn_lock", + label: I18n.tr("VPN"), + setting: "showVpnIcon" + } + ] + }, + { + id: "bluetooth", + rows: [ + { + icon: "bluetooth", + label: I18n.tr("Bluetooth"), + setting: "showBluetoothIcon" + } + ] + }, + { + id: "audio", + rows: [ + { + icon: "volume_up", + label: I18n.tr("Audio"), + setting: "showAudioIcon" + }, + { + icon: "percent", + label: I18n.tr("Volume"), + setting: "showAudioPercent" + } + ] + }, + { + id: "microphone", + rows: [ + { + icon: "mic", + label: I18n.tr("Microphone"), + setting: "showMicIcon" + }, + { + icon: "percent", + label: I18n.tr("Microphone Volume"), + setting: "showMicPercent" + } + ] + }, + { + id: "brightness", + rows: [ + { + icon: "brightness_high", + label: I18n.tr("Brightness"), + setting: "showBrightnessIcon" + }, + { + icon: "percent", + label: I18n.tr("Brightness Value"), + setting: "showBrightnessPercent" + } + ] + }, + { + id: "battery", + rows: [ + { + icon: "battery_full", + label: I18n.tr("Battery"), + setting: "showBatteryIcon" + } + ] + }, + { + id: "printer", + rows: [ + { + icon: "print", + label: I18n.tr("Printer"), + setting: "showPrinterIcon" + } + ] + }, + { + id: "screenSharing", + rows: [ + { + icon: "screen_record", + label: I18n.tr("Screen Sharing"), + setting: "showScreenSharingIcon" + } + ] + } + ] + property var controlCenterGroups: defaultControlCenterGroups + property int draggedControlCenterGroupIndex: -1 + property int controlCenterGroupDropIndex: -1 + + function updateControlCenterGroupDropIndex(draggedIndex, localY) { + const totalGroups = controlCenterGroups.length; + let dropIndex = totalGroups; + + for (let i = 0; i < totalGroups; i++) { + const delegate = groupRepeater.itemAt(i); + if (!delegate) + continue; + + const midpoint = delegate.y + delegate.height / 2; + if (localY < midpoint) { + dropIndex = i; + break; + } + } + + controlCenterGroupDropIndex = Math.max(0, Math.min(totalGroups, dropIndex)); + draggedControlCenterGroupIndex = draggedIndex; + } + + function finishControlCenterDrag() { + if (draggedControlCenterGroupIndex < 0) { + controlCenterGroupDropIndex = -1; + return; + } + + const fromIndex = draggedControlCenterGroupIndex; + let toIndex = controlCenterGroupDropIndex; + + draggedControlCenterGroupIndex = -1; + controlCenterGroupDropIndex = -1; + + if (toIndex < 0 || toIndex > controlCenterGroups.length || toIndex === fromIndex || toIndex === fromIndex + 1) + return; + + const groups = controlCenterGroups.slice(); + const moved = groups.splice(fromIndex, 1)[0]; + + if (toIndex > fromIndex) + toIndex -= 1; + + groups.splice(toIndex, 0, moved); + controlCenterGroups = groups; + const reorderedGroupIds = groups.map(group => group.id); + root.controlCenterGroupOrderChanged(sectionId, widgetIndex, reorderedGroupIds); + } + + function cancelControlCenterDrag() { + draggedControlCenterGroupIndex = -1; + controlCenterGroupDropIndex = -1; + } + + function getControlCenterGroupHeight(group) { + const rowCount = group?.rows?.length ?? 0; + if (rowCount <= 0) + return controlCenterGroupVerticalPadding; + + return rowCount * controlCenterRowHeight + Math.max(0, rowCount - 1) * controlCenterRowSpacing + controlCenterGroupVerticalPadding; + } + + function getControlCenterPopupHeight(groups) { + const orderedGroups = groups || []; + let totalHeight = Theme.spacingS * 2; + + for (let i = 0; i < orderedGroups.length; i++) { + totalHeight += getControlCenterGroupHeight(orderedGroups[i]); + if (i < orderedGroups.length - 1) + totalHeight += controlCenterMenuSpacing; + } + + return totalHeight; + } + + function getOrderedControlCenterGroups() { + const baseGroups = defaultControlCenterGroups.slice(); + const currentWidget = contentItem.getCurrentWidgetData(); + const savedOrder = currentWidget?.controlCenterGroupOrder; + if (!savedOrder || !savedOrder.length) + return baseGroups; + + const groupMap = {}; + for (let i = 0; i < baseGroups.length; i++) + groupMap[baseGroups[i].id] = baseGroups[i]; + + const orderedGroups = []; + for (let i = 0; i < savedOrder.length; i++) { + const groupId = savedOrder[i]; + const group = groupMap[groupId]; + if (group) { + orderedGroups.push(group); + delete groupMap[groupId]; + } + } + + for (let i = 0; i < baseGroups.length; i++) { + const group = baseGroups[i]; + if (groupMap[group.id]) + orderedGroups.push(group); + } + + return orderedGroups; + } + + background: Rectangle { + color: Theme.surfaceContainer + radius: Theme.cornerRadius + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) + border.width: 0 + } + + contentItem: Item { + function getCurrentWidgetData() { + const widgets = root.items || []; + if (controlCenterContextMenu.widgetIndex >= 0 && controlCenterContextMenu.widgetIndex < widgets.length) + return widgets[controlCenterContextMenu.widgetIndex]; + return controlCenterContextMenu.widgetData; + } + + Column { + id: menuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Item { + id: controlCenterContentMetrics + visible: false + implicitWidth: 16 + Theme.spacingS + 16 + Theme.spacingS + longestControlCenterLabelMetrics.advanceWidth + Theme.spacingM + 40 + Theme.spacingS * 2 + Theme.spacingM + } + + TextMetrics { + id: longestControlCenterLabelMetrics + font.pixelSize: Theme.fontSizeSmall + text: { + const labels = [I18n.tr("Network"), I18n.tr("VPN"), I18n.tr("Bluetooth"), I18n.tr("Audio"), I18n.tr("Volume"), I18n.tr("Microphone"), I18n.tr("Microphone Volume"), I18n.tr("Brightness"), I18n.tr("Brightness Value"), I18n.tr("Battery"), I18n.tr("Printer"), I18n.tr("Screen Sharing")]; + let longest = ""; + for (let i = 0; i < labels.length; i++) { + if (labels[i].length > longest.length) + longest = labels[i]; + } + return longest; + } + } + + Repeater { + id: groupRepeater + model: controlCenterContextMenu.controlCenterGroups + + delegate: Item { + id: delegateRoot + + required property var modelData + required property int index + + function getCheckedState(settingName) { + const wd = controlCenterContextMenu.contentItem.getCurrentWidgetData(); + switch (settingName) { + case "showNetworkIcon": + return wd?.showNetworkIcon ?? SettingsData.controlCenterShowNetworkIcon; + case "showVpnIcon": + return wd?.showVpnIcon ?? SettingsData.controlCenterShowVpnIcon; + case "showBluetoothIcon": + return wd?.showBluetoothIcon ?? SettingsData.controlCenterShowBluetoothIcon; + case "showAudioIcon": + return wd?.showAudioIcon ?? SettingsData.controlCenterShowAudioIcon; + case "showAudioPercent": + return wd?.showAudioPercent ?? SettingsData.controlCenterShowAudioPercent; + case "showMicIcon": + return wd?.showMicIcon ?? SettingsData.controlCenterShowMicIcon; + case "showMicPercent": + return wd?.showMicPercent ?? SettingsData.controlCenterShowMicPercent; + case "showBrightnessIcon": + return wd?.showBrightnessIcon ?? SettingsData.controlCenterShowBrightnessIcon; + case "showBrightnessPercent": + return wd?.showBrightnessPercent ?? SettingsData.controlCenterShowBrightnessPercent; + case "showBatteryIcon": + return wd?.showBatteryIcon ?? SettingsData.controlCenterShowBatteryIcon; + case "showPrinterIcon": + return wd?.showPrinterIcon ?? SettingsData.controlCenterShowPrinterIcon; + case "showScreenSharingIcon": + return wd?.showScreenSharingIcon ?? SettingsData.controlCenterShowScreenSharingIcon; + default: + return false; + } + } + + readonly property string rootSetting: modelData.rows[0]?.setting ?? "" + readonly property bool rootEnabled: rootSetting ? getCheckedState(rootSetting) : true + readonly property bool isDragged: controlCenterContextMenu.draggedControlCenterGroupIndex === index + readonly property bool showDropIndicatorAbove: controlCenterContextMenu.controlCenterGroupDropIndex === index + readonly property bool showDropIndicatorBelow: controlCenterContextMenu.controlCenterGroupDropIndex === controlCenterContextMenu.controlCenterGroups.length && index === controlCenterContextMenu.controlCenterGroups.length - 1 + + width: menuColumn.width + height: groupBackground.height + + Rectangle { + id: groupBackground + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: groupContent.implicitHeight + Theme.spacingXS * 2 + radius: Theme.cornerRadius + color: isDragged ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.18) : (groupHoverArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent") + opacity: isDragged ? 0.75 : 1.0 + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: -1 + height: 2 + radius: 1 + color: Theme.primary + visible: showDropIndicatorAbove + z: 3 + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: -1 + height: 2 + radius: 1 + color: Theme.primary + visible: showDropIndicatorBelow + z: 3 + } + + Item { + id: groupContent + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: Theme.spacingXS + implicitHeight: groupColumn.implicitHeight + + Column { + id: groupColumn + anchors.left: parent.left + anchors.right: parent.right + spacing: 1 + + Repeater { + id: groupColumnRepeater + model: modelData.rows + + delegate: Rectangle { + required property var modelData + required property int index + + readonly property var rowData: modelData + readonly property bool isFirstRow: index === 0 + readonly property bool rowEnabled: isFirstRow ? true : delegateRoot.rootEnabled + readonly property bool computedCheckedState: rowEnabled ? getCheckedState(rowData.setting) : false + readonly property bool rowHovered: rowEnabled && (toggleArea.containsMouse || (isFirstRow && groupDragHandleArea.containsMouse)) + + width: groupColumn.width + height: 32 + radius: Theme.cornerRadius + opacity: rowEnabled ? 1.0 : 0.5 + color: rowHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.right: toggle.left + anchors.rightMargin: Theme.spacingM + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + Item { + width: 16 + height: 16 + anchors.verticalCenter: parent.verticalCenter + + DankIcon { + anchors.centerIn: parent + name: "drag_indicator" + size: 16 + color: groupDragHandleArea.pressed || isDragged ? Theme.primary : Theme.outline + visible: isFirstRow + } + + MouseArea { + id: groupDragHandleArea + anchors.fill: parent + hoverEnabled: true + preventStealing: true + enabled: isFirstRow + cursorShape: pressed ? Qt.ClosedHandCursor : Qt.OpenHandCursor + + onPressed: mouse => { + mouse.accepted = true; + const point = mapToItem(menuColumn, mouse.x, mouse.y); + controlCenterContextMenu.updateControlCenterGroupDropIndex(delegateRoot.index, point.y); + } + onPositionChanged: mouse => { + if (!pressed) + return; + mouse.accepted = true; + const point = mapToItem(menuColumn, mouse.x, mouse.y); + controlCenterContextMenu.updateControlCenterGroupDropIndex(delegateRoot.index, point.y); + } + onReleased: mouse => { + mouse.accepted = true; + const point = mapToItem(menuColumn, mouse.x, mouse.y); + controlCenterContextMenu.updateControlCenterGroupDropIndex(delegateRoot.index, point.y); + controlCenterContextMenu.finishControlCenterDrag(); + } + onCanceled: { + controlCenterContextMenu.cancelControlCenterDrag(); + } + } + } + + DankIcon { + name: rowData.icon + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: rowData.label + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: toggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + enabled: rowEnabled + checked: computedCheckedState + + onToggled: { + if (!rowEnabled) + return; + root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, rowData.setting, toggled); + } + } + + MouseArea { + id: toggleArea + anchors.fill: parent + anchors.leftMargin: 16 + Theme.spacingS * 2 + hoverEnabled: true + cursorShape: rowEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor + enabled: rowEnabled && controlCenterContextMenu.draggedControlCenterGroupIndex < 0 + onPressed: { + if (!rowEnabled) + return; + root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, rowData.setting, !computedCheckedState); + } + } + } + } + } + + MouseArea { + id: groupHoverArea + anchors.fill: parent + hoverEnabled: true + enabled: false + } + } + } + } + } + } + } + + Popup { + id: privacyContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + width: 200 + height: 160 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + onOpened: { + console.log("Privacy context menu opened"); + } + + onClosed: { + console.log("Privacy Center context menu closed"); + } + + background: Rectangle { + color: Theme.surfaceContainer + 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: menuPrivacyColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Always on icons") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Medium + anchors.verticalCenter: parent.verticalCenter + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: micToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "mic" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Microphone") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: micToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.privacyShowMicIcon + onToggled: toggled => { + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showMicIcon", toggled); + } + } + + MouseArea { + id: micToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + micToggle.checked = !micToggle.checked; + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showMicIcon", micToggle.checked); + } + } + } + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: cameraToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "camera_video" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Camera") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: cameraToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.privacyShowCameraIcon + onToggled: toggled => { + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showCameraIcon", toggled); + } + } + + MouseArea { + id: cameraToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + cameraToggle.checked = !cameraToggle.checked; + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showCameraIcon", cameraToggle.checked); + } + } + } + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: screenshareToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "screen_share" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Screen sharing") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: screenshareToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.privacyShowScreenShareIcon + onToggled: toggled => { + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showScreenSharingIcon", toggled); + } + } + + MouseArea { + id: screenshareToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + screenshareToggle.checked = !screenshareToggle.checked; + root.privacySettingChanged(privacyContextMenu.sectionId, privacyContextMenu.widgetIndex, "showScreenSharingIcon", screenshareToggle.checked); + } + } + } + } + } + } + + 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.surfaceContainer + 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(); + } + } + } + } + } + } + } + + Popup { + id: musicContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + width: 180 + height: musicMenuColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + 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: musicMenuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Repeater { + model: [ + { + icon: "photo_size_select_small", + label: I18n.tr("Small"), + sizeValue: 0 + }, + { + icon: "photo_size_select_actual", + label: I18n.tr("Medium"), + sizeValue: 1 + }, + { + icon: "photo_size_select_large", + label: I18n.tr("Large"), + sizeValue: 2 + }, + { + icon: "fit_screen", + label: I18n.tr("Largest"), + sizeValue: 3 + } + ] + + delegate: Rectangle { + required property var modelData + required property int index + + function isSelected() { + var wd = musicContextMenu.widgetData; + var currentSize = wd?.mediaSize ?? SettingsData.mediaSize; + return currentSize === modelData.sizeValue; + } + + width: musicMenuColumn.width + height: Math.max(18, Theme.fontSizeSmall) + Theme.spacingM * 2 + radius: Theme.cornerRadius + color: musicOptionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: modelData.icon + size: 18 + color: isSelected() ? Theme.primary : Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: modelData.label + font.pixelSize: Theme.fontSizeSmall + font.weight: isSelected() ? Font.Medium : Font.Normal + color: isSelected() ? Theme.primary : Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + DankIcon { + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + name: "check" + size: 16 + color: Theme.primary + visible: isSelected() + } + + MouseArea { + id: musicOptionArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + root.compactModeChanged("music", modelData.sizeValue); + musicContextMenu.close(); + } + } + } + } + } + } + } + + Popup { + id: runningAppsContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData + + width: 240 + height: runningAppsMenuColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + 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: runningAppsMenuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: "transparent" + + StyledText { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + text: I18n.tr("Running Apps Settings") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: raCompactArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "zoom_in" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Compact Mode") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: raCompactToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: runningAppsContextMenu.currentWidgetData?.runningAppsCompactMode ?? SettingsData.runningAppsCompactMode + onToggled: { + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCompactMode", toggled); + } + } + + MouseArea { + id: raCompactArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + raCompactToggle.checked = !raCompactToggle.checked; + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCompactMode", raCompactToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: raGroupArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "apps" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Group by App") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: raGroupToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: runningAppsContextMenu.currentWidgetData?.runningAppsGroupByApp ?? SettingsData.runningAppsGroupByApp + onToggled: { + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsGroupByApp", toggled); + } + } + + MouseArea { + id: raGroupArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + raGroupToggle.checked = !raGroupToggle.checked; + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsGroupByApp", raGroupToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: raWorkspaceArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "workspaces" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Current Workspace", "Running apps filter: only show apps from the active workspace") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: raWorkspaceToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: runningAppsContextMenu.currentWidgetData?.runningAppsCurrentWorkspace ?? SettingsData.runningAppsCurrentWorkspace + onToggled: { + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCurrentWorkspace", toggled); + } + } + + MouseArea { + id: raWorkspaceArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + raWorkspaceToggle.checked = !raWorkspaceToggle.checked; + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCurrentWorkspace", raWorkspaceToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: raDisplayArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "monitor" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Current Monitor", "Running apps filter: only show apps from the same monitor") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: raDisplayToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: runningAppsContextMenu.currentWidgetData?.runningAppsCurrentMonitor ?? SettingsData.runningAppsCurrentMonitor + onToggled: { + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCurrentMonitor", toggled); + } + } + + MouseArea { + id: raDisplayArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + raDisplayToggle.checked = !raDisplayToggle.checked; + root.overflowSettingChanged(runningAppsContextMenu.sectionId, runningAppsContextMenu.widgetIndex, "runningAppsCurrentMonitor", raDisplayToggle.checked); + } + } + } + } + } + } + + Popup { + id: appsDockContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + + // Dynamically get current widget data from the items list + readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData + + width: 320 + height: appsDockMenuColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + 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: appsDockMenuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Apps Dock Settings") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + leftPadding: Theme.spacingS + } + + StyledText { + text: I18n.tr("Overflow") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + leftPadding: Theme.spacingS + } + + Column { + width: parent.width + spacing: Theme.spacingXS + + Row { + width: parent.width + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Max Pinned Apps") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + width: 120 + } + + Row { + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + DankActionButton { + buttonSize: 24 + iconName: "remove" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = appsDockContextMenu.currentWidgetData?.barMaxVisibleApps ?? SettingsData.barMaxVisibleApps; + var newVal = Math.max(0, current - 1); + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barMaxVisibleApps", newVal); + } + } + + StyledText { + text: { + var val = appsDockContextMenu.currentWidgetData?.barMaxVisibleApps ?? SettingsData.barMaxVisibleApps; + return val === 0 ? I18n.tr("All") : val; + } + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + width: 30 + } + + DankActionButton { + buttonSize: 24 + iconName: "add" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = appsDockContextMenu.currentWidgetData?.barMaxVisibleApps ?? SettingsData.barMaxVisibleApps; + var newVal = current + 1; + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barMaxVisibleApps", newVal); + } + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Max Running Apps") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + width: 120 + } + + Row { + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + DankActionButton { + buttonSize: 24 + iconName: "remove" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = appsDockContextMenu.currentWidgetData?.barMaxVisibleRunningApps ?? SettingsData.barMaxVisibleRunningApps; + var newVal = Math.max(0, current - 1); + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barMaxVisibleRunningApps", newVal); + } + } + + StyledText { + text: { + var val = appsDockContextMenu.currentWidgetData?.barMaxVisibleRunningApps ?? SettingsData.barMaxVisibleRunningApps; + return val === 0 ? I18n.tr("All") : val; + } + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + width: 30 + } + + DankActionButton { + buttonSize: 24 + iconName: "add" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = appsDockContextMenu.currentWidgetData?.barMaxVisibleRunningApps ?? SettingsData.barMaxVisibleRunningApps; + var newVal = current + 1; + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barMaxVisibleRunningApps", newVal); + } + } + } + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: badgeToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "notifications" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Show Badge") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: badgeToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: appsDockContextMenu.currentWidgetData?.barShowOverflowBadge ?? SettingsData.barShowOverflowBadge + onToggled: { + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barShowOverflowBadge", toggled); + } + } + + MouseArea { + id: badgeToggleArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + badgeToggle.checked = !badgeToggle.checked; + root.overflowSettingChanged(appsDockContextMenu.sectionId, appsDockContextMenu.widgetIndex, "barShowOverflowBadge", badgeToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + } + + StyledText { + text: I18n.tr("Visual Effects") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + leftPadding: Theme.spacingS + topPadding: Theme.spacingXS + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: hideIndicatorsArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "visibility_off" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Hide Indicators") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: hideIndicatorsToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.appsDockHideIndicators + onToggled: { + SettingsData.set("appsDockHideIndicators", toggled); + } + } + + MouseArea { + id: hideIndicatorsArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + hideIndicatorsToggle.checked = !hideIndicatorsToggle.checked; + SettingsData.set("appsDockHideIndicators", hideIndicatorsToggle.checked); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: colorizeActiveArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "palette" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Colorize Active") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: colorizeActiveToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.appsDockColorizeActive + onToggled: { + SettingsData.set("appsDockColorizeActive", toggled); + } + } + + MouseArea { + id: colorizeActiveArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + colorizeActiveToggle.checked = !colorizeActiveToggle.checked; + SettingsData.set("appsDockColorizeActive", colorizeActiveToggle.checked); + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingS + visible: SettingsData.appsDockColorizeActive + leftPadding: Theme.spacingL + Theme.spacingS + + StyledText { + text: I18n.tr("Active Color") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + width: 90 + } + + DankButtonGroup { + anchors.verticalCenter: parent.verticalCenter + model: ["pri", "sec", "pc", "err", "ok"] + buttonHeight: 22 + minButtonWidth: 32 + buttonPadding: 4 + checkIconSize: 10 + textSize: 9 + spacing: 1 + currentIndex: { + switch (SettingsData.appsDockActiveColorMode) { + case "secondary": + return 1; + case "primaryContainer": + return 2; + case "error": + return 3; + case "success": + return 4; + default: + return 0; + } + } + onSelectionChanged: (index, selected) => { + if (!selected) + return; + const modes = ["primary", "secondary", "primaryContainer", "error", "success"]; + SettingsData.set("appsDockActiveColorMode", modes[index]); + } + } + } + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: enlargeOnHoverArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: "zoom_in" + size: 16 + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Enlarge on Hover") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankToggle { + id: enlargeOnHoverToggle + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + width: 40 + height: 20 + checked: SettingsData.appsDockEnlargeOnHover + onToggled: { + SettingsData.set("appsDockEnlargeOnHover", toggled); + } + } + + MouseArea { + id: enlargeOnHoverArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onPressed: { + enlargeOnHoverToggle.checked = !enlargeOnHoverToggle.checked; + SettingsData.set("appsDockEnlargeOnHover", enlargeOnHoverToggle.checked); + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingS + visible: SettingsData.appsDockEnlargeOnHover + + StyledText { + text: I18n.tr("Enlargement %") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + width: 120 + } + + Row { + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + DankActionButton { + buttonSize: 24 + iconName: "remove" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = SettingsData.appsDockEnlargePercentage; + var newVal = Math.max(100, current - 5); + SettingsData.set("appsDockEnlargePercentage", newVal); + } + } + + StyledText { + text: SettingsData.appsDockEnlargePercentage + "%" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + width: 50 + } + + DankActionButton { + buttonSize: 24 + iconName: "add" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = SettingsData.appsDockEnlargePercentage; + var newVal = Math.min(150, current + 5); + SettingsData.set("appsDockEnlargePercentage", newVal); + } + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Icon Size %") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + width: 120 + } + + Row { + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + DankActionButton { + buttonSize: 24 + iconName: "remove" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = SettingsData.appsDockIconSizePercentage; + var newVal = Math.max(50, current - 5); + SettingsData.set("appsDockIconSizePercentage", newVal); + } + } + + StyledText { + text: SettingsData.appsDockIconSizePercentage + "%" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignHCenter + width: 50 + } + + DankActionButton { + buttonSize: 24 + iconName: "add" + iconSize: 14 + iconColor: Theme.outline + onClicked: { + var current = SettingsData.appsDockIconSizePercentage; + var newVal = Math.min(200, current + 5); + SettingsData.set("appsDockIconSizePercentage", newVal); + } + } + } + } + } + } + } + } +} -- cgit v1.3