diff options
| author | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
|---|---|---|
| committer | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
| commit | 5d94c0a7d44a2255b81815a52a7056a94a39842d (patch) | |
| tree | 759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml | |
| parent | e79cdf210b267f21a186255ce1a4d50029439d54 (diff) | |
| download | RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip | |
update Raveos themes
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml')
| -rw-r--r-- | raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml new file mode 100644 index 0000000..5fb2794 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DesktopWidgetsTab.qml @@ -0,0 +1,708 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import qs.Common +import qs.Services +import qs.Widgets +import qs.Modules.Settings.Widgets + +Item { + id: root + + LayoutMirroring.enabled: I18n.isRtl + LayoutMirroring.childrenInherit: true + + property var expandedStates: ({}) + property var groupCollapsedStates: ({}) + property var parentModal: null + property string editingGroupId: "" + property string newGroupName: "" + + readonly property var allInstances: SettingsData.desktopWidgetInstances || [] + readonly property var allGroups: SettingsData.desktopWidgetGroups || [] + + function showWidgetBrowser() { + widgetBrowserLoader.active = true; + if (widgetBrowserLoader.item) + widgetBrowserLoader.item.show(); + } + + function showDesktopPluginBrowser() { + desktopPluginBrowserLoader.active = true; + if (desktopPluginBrowserLoader.item) + desktopPluginBrowserLoader.item.show(); + } + + LazyLoader { + id: widgetBrowserLoader + active: false + + DesktopWidgetBrowser { + parentModal: root.parentModal + onWidgetAdded: widgetType => { + ToastService.showInfo(I18n.tr("Widget added")); + } + } + } + + LazyLoader { + id: desktopPluginBrowserLoader + active: false + + PluginBrowser { + parentModal: root.parentModal + typeFilter: "desktop-widget" + } + } + + 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 + + SettingsCard { + width: parent.width + iconName: "widgets" + title: I18n.tr("Desktop Widgets") + + Column { + width: parent.width - Theme.spacingM * 2 + x: Theme.spacingM + spacing: Theme.spacingM + + StyledText { + width: parent.width + text: I18n.tr("Add and configure widgets that appear on your desktop") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignLeft + } + + Row { + spacing: Theme.spacingM + + DankButton { + text: I18n.tr("Add Widget") + iconName: "add" + onClicked: root.showWidgetBrowser() + } + + DankButton { + text: I18n.tr("Browse Plugins") + iconName: "store" + onClicked: root.showDesktopPluginBrowser() + } + } + } + } + + SettingsCard { + width: parent.width + iconName: "folder" + title: I18n.tr("Groups") + collapsible: true + expanded: root.allGroups.length > 0 + + Column { + width: parent.width - Theme.spacingM * 2 + x: Theme.spacingM + spacing: Theme.spacingM + + StyledText { + width: parent.width + text: I18n.tr("Organize widgets into collapsible groups") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignLeft + } + + Row { + spacing: Theme.spacingS + width: parent.width + + DankTextField { + id: newGroupField + width: parent.width - addGroupBtn.width - Theme.spacingS + placeholderText: I18n.tr("New group name...") + text: root.newGroupName + onTextChanged: root.newGroupName = text + onAccepted: { + if (!text.trim()) + return; + SettingsData.createDesktopWidgetGroup(text.trim()); + root.newGroupName = ""; + text = ""; + } + } + + DankButton { + id: addGroupBtn + iconName: "add" + text: I18n.tr("Add") + enabled: root.newGroupName.trim().length > 0 + onClicked: { + SettingsData.createDesktopWidgetGroup(root.newGroupName.trim()); + root.newGroupName = ""; + newGroupField.text = ""; + } + } + } + + Column { + width: parent.width + spacing: Theme.spacingXS + visible: root.allGroups.length > 0 + + Repeater { + model: root.allGroups + + Rectangle { + id: groupItem + required property var modelData + required property int index + + width: parent.width + height: 40 + radius: Theme.cornerRadius + color: groupMouseArea.containsMouse ? Theme.surfaceHover : Theme.surfaceContainer + + Row { + anchors.fill: parent + anchors.leftMargin: Theme.spacingS + anchors.rightMargin: Theme.spacingS + spacing: Theme.spacingS + + DankIcon { + name: "folder" + size: Theme.iconSizeSmall + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + Loader { + active: root.editingGroupId === groupItem.modelData.id + width: active ? parent.width - Theme.iconSizeSmall - deleteGroupBtn.width - Theme.spacingS * 3 : 0 + height: active ? 32 : 0 + anchors.verticalCenter: parent.verticalCenter + + sourceComponent: DankTextField { + text: groupItem.modelData.name + onAccepted: { + if (!text.trim()) + return; + SettingsData.updateDesktopWidgetGroup(groupItem.modelData.id, { + name: text.trim() + }); + root.editingGroupId = ""; + } + onEditingFinished: { + if (!text.trim()) + return; + SettingsData.updateDesktopWidgetGroup(groupItem.modelData.id, { + name: text.trim() + }); + root.editingGroupId = ""; + } + Component.onCompleted: forceActiveFocus() + } + } + + StyledText { + visible: root.editingGroupId !== groupItem.modelData.id + text: groupItem.modelData.name + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + elide: Text.ElideRight + width: parent.width - Theme.iconSizeSmall - deleteGroupBtn.width - Theme.spacingS * 3 + } + + DankActionButton { + id: deleteGroupBtn + iconName: "delete" + anchors.verticalCenter: parent.verticalCenter + onClicked: { + SettingsData.removeDesktopWidgetGroup(groupItem.modelData.id); + ToastService.showInfo(I18n.tr("Group removed")); + } + } + } + + MouseArea { + id: groupMouseArea + anchors.fill: parent + hoverEnabled: true + onDoubleClicked: root.editingGroupId = groupItem.modelData.id + } + } + } + } + } + } + + Repeater { + model: root.allGroups + + Column { + id: groupSection + required property var modelData + required property int index + + readonly property string groupId: modelData.id + readonly property var groupInstances: root.allInstances.filter(inst => inst.group === groupId) + + width: mainColumn.width + spacing: Theme.spacingM + visible: groupInstances.length > 0 + + Rectangle { + width: parent.width + height: 44 + radius: Theme.cornerRadius + color: Theme.surfaceContainer + + Row { + anchors.fill: parent + anchors.leftMargin: Theme.spacingM + anchors.rightMargin: Theme.spacingM + spacing: Theme.spacingS + + DankIcon { + name: (root.groupCollapsedStates[groupSection.groupId] ?? false) ? "expand_more" : "expand_less" + size: Theme.iconSize + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + DankIcon { + name: "folder" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: groupSection.modelData.name + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: "(" + groupSection.groupInstances.length + ")" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + anchors.verticalCenter: parent.verticalCenter + } + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + var states = Object.assign({}, root.groupCollapsedStates); + states[groupSection.groupId] = !(states[groupSection.groupId] ?? false); + root.groupCollapsedStates = states; + } + } + } + + Column { + width: parent.width + spacing: Theme.spacingM + visible: !(root.groupCollapsedStates[groupSection.groupId] ?? false) + leftPadding: Theme.spacingM + + Repeater { + model: ScriptModel { + objectProp: "id" + values: groupSection.groupInstances + } + + Item { + id: groupDelegateItem + required property var modelData + required property int index + + property bool held: groupDragArea.pressed + property real originalY: y + + readonly property string instanceIdRef: modelData.id + readonly property var liveInstanceData: { + const instances = root.allInstances; + return instances.find(inst => inst.id === instanceIdRef) ?? modelData; + } + + width: groupSection.width - Theme.spacingM + height: groupCard.height + z: held ? 2 : 1 + + DesktopWidgetInstanceCard { + id: groupCard + width: parent.width + headerLeftPadding: 20 + instanceData: groupDelegateItem.liveInstanceData + isExpanded: root.expandedStates[groupDelegateItem.instanceIdRef] ?? false + + onExpandedChanged: { + if (expanded === (root.expandedStates[groupDelegateItem.instanceIdRef] ?? false)) + return; + var states = Object.assign({}, root.expandedStates); + states[groupDelegateItem.instanceIdRef] = expanded; + root.expandedStates = states; + } + + onDuplicateRequested: SettingsData.duplicateDesktopWidgetInstance(groupDelegateItem.instanceIdRef) + + onDeleteRequested: { + SettingsData.removeDesktopWidgetInstance(groupDelegateItem.instanceIdRef); + ToastService.showInfo(I18n.tr("Widget removed")); + } + } + + MouseArea { + id: groupDragArea + anchors.left: parent.left + anchors.top: parent.top + width: 40 + height: 50 + hoverEnabled: true + cursorShape: Qt.SizeVerCursor + drag.target: groupDelegateItem.held ? groupDelegateItem : undefined + drag.axis: Drag.YAxis + preventStealing: true + + onPressed: { + groupDelegateItem.z = 2; + groupDelegateItem.originalY = groupDelegateItem.y; + } + onReleased: { + groupDelegateItem.z = 1; + if (!drag.active) { + groupDelegateItem.y = groupDelegateItem.originalY; + return; + } + const spacing = Theme.spacingM; + const itemH = groupDelegateItem.height + spacing; + var newIndex = Math.round(groupDelegateItem.y / itemH); + newIndex = Math.max(0, Math.min(newIndex, groupSection.groupInstances.length - 1)); + if (newIndex !== groupDelegateItem.index) + SettingsData.reorderDesktopWidgetInstanceInGroup(groupDelegateItem.instanceIdRef, groupSection.groupId, newIndex); + groupDelegateItem.y = groupDelegateItem.originalY; + } + } + + DankIcon { + x: Theme.spacingL - 2 + y: Theme.spacingL + (Theme.iconSize / 2) - (size / 2) + name: "drag_indicator" + size: 18 + color: Theme.outline + opacity: groupDragArea.containsMouse || groupDragArea.pressed ? 1 : 0.5 + } + + Behavior on y { + enabled: !groupDragArea.pressed && !groupDragArea.drag.active + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + } + } + } + + Column { + id: ungroupedSection + width: parent.width + spacing: Theme.spacingM + visible: ungroupedInstances.length > 0 + + readonly property var ungroupedInstances: root.allInstances.filter(inst => { + if (!inst.group) + return true; + return !root.allGroups.some(g => g.id === inst.group); + }) + + Rectangle { + width: parent.width + height: 44 + radius: Theme.cornerRadius + color: Theme.surfaceContainer + visible: root.allGroups.length > 0 + + Row { + anchors.fill: parent + anchors.leftMargin: Theme.spacingM + anchors.rightMargin: Theme.spacingM + spacing: Theme.spacingS + + DankIcon { + name: (root.groupCollapsedStates["_ungrouped"] ?? false) ? "expand_more" : "expand_less" + size: Theme.iconSize + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + DankIcon { + name: "widgets" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Ungrouped") + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: "(" + ungroupedSection.ungroupedInstances.length + ")" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + anchors.verticalCenter: parent.verticalCenter + } + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + var states = Object.assign({}, root.groupCollapsedStates); + states["_ungrouped"] = !(states["_ungrouped"] ?? false); + root.groupCollapsedStates = states; + } + } + } + + Column { + width: parent.width + spacing: Theme.spacingM + visible: !(root.groupCollapsedStates["_ungrouped"] ?? false) + leftPadding: root.allGroups.length > 0 ? Theme.spacingM : 0 + + Repeater { + model: ScriptModel { + objectProp: "id" + values: ungroupedSection.ungroupedInstances + } + + Item { + id: ungroupedDelegateItem + required property var modelData + required property int index + + property bool held: ungroupedDragArea.pressed + property real originalY: y + + readonly property string instanceIdRef: modelData.id + readonly property var liveInstanceData: { + const instances = root.allInstances; + return instances.find(inst => inst.id === instanceIdRef) ?? modelData; + } + + width: ungroupedSection.width - (root.allGroups.length > 0 ? Theme.spacingM : 0) + height: ungroupedCard.height + z: held ? 2 : 1 + + DesktopWidgetInstanceCard { + id: ungroupedCard + width: parent.width + headerLeftPadding: 20 + instanceData: ungroupedDelegateItem.liveInstanceData + isExpanded: root.expandedStates[ungroupedDelegateItem.instanceIdRef] ?? false + + onExpandedChanged: { + if (expanded === (root.expandedStates[ungroupedDelegateItem.instanceIdRef] ?? false)) + return; + var states = Object.assign({}, root.expandedStates); + states[ungroupedDelegateItem.instanceIdRef] = expanded; + root.expandedStates = states; + } + + onDuplicateRequested: SettingsData.duplicateDesktopWidgetInstance(ungroupedDelegateItem.instanceIdRef) + + onDeleteRequested: { + SettingsData.removeDesktopWidgetInstance(ungroupedDelegateItem.instanceIdRef); + ToastService.showInfo(I18n.tr("Widget removed")); + } + } + + MouseArea { + id: ungroupedDragArea + anchors.left: parent.left + anchors.top: parent.top + width: 40 + height: 50 + hoverEnabled: true + cursorShape: Qt.SizeVerCursor + drag.target: ungroupedDelegateItem.held ? ungroupedDelegateItem : undefined + drag.axis: Drag.YAxis + preventStealing: true + + onPressed: { + ungroupedDelegateItem.z = 2; + ungroupedDelegateItem.originalY = ungroupedDelegateItem.y; + } + onReleased: { + ungroupedDelegateItem.z = 1; + if (!drag.active) { + ungroupedDelegateItem.y = ungroupedDelegateItem.originalY; + return; + } + const spacing = Theme.spacingM; + const itemH = ungroupedDelegateItem.height + spacing; + var newIndex = Math.round(ungroupedDelegateItem.y / itemH); + newIndex = Math.max(0, Math.min(newIndex, ungroupedSection.ungroupedInstances.length - 1)); + if (newIndex !== ungroupedDelegateItem.index) + SettingsData.reorderDesktopWidgetInstanceInGroup(ungroupedDelegateItem.instanceIdRef, null, newIndex); + ungroupedDelegateItem.y = ungroupedDelegateItem.originalY; + } + } + + DankIcon { + x: Theme.spacingL - 2 + y: Theme.spacingL + (Theme.iconSize / 2) - (size / 2) + name: "drag_indicator" + size: 18 + color: Theme.outline + opacity: ungroupedDragArea.containsMouse || ungroupedDragArea.pressed ? 1 : 0.5 + } + + Behavior on y { + enabled: !ungroupedDragArea.pressed && !ungroupedDragArea.drag.active + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + } + } + + StyledText { + visible: root.allInstances.length === 0 + text: I18n.tr("No widgets added. Click \"Add Widget\" to get started.") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceVariantText + width: parent.width + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignLeft + } + + SettingsCard { + width: parent.width + iconName: "info" + title: I18n.tr("Help") + + Column { + width: parent.width - Theme.spacingM * 2 + x: Theme.spacingM + spacing: Theme.spacingM + + Row { + width: parent.width + spacing: Theme.spacingM + + Rectangle { + width: 40 + height: 40 + radius: 20 + color: Theme.primarySelected + + DankIcon { + anchors.centerIn: parent + name: "drag_pan" + size: Theme.iconSize + color: Theme.primary + } + } + + Column { + spacing: 2 + anchors.verticalCenter: parent.verticalCenter + width: parent.width - 40 - Theme.spacingM + + StyledText { + text: I18n.tr("Move Widget") + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + width: parent.width + horizontalAlignment: Text.AlignLeft + } + + StyledText { + text: I18n.tr("Right-click and drag anywhere on the widget") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + width: parent.width + horizontalAlignment: Text.AlignLeft + } + } + } + + Row { + width: parent.width + spacing: Theme.spacingM + + Rectangle { + width: 40 + height: 40 + radius: 20 + color: Theme.primarySelected + + DankIcon { + anchors.centerIn: parent + name: "open_in_full" + size: Theme.iconSize + color: Theme.primary + } + } + + Column { + spacing: 2 + anchors.verticalCenter: parent.verticalCenter + width: parent.width - 40 - Theme.spacingM + + StyledText { + text: I18n.tr("Resize Widget") + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + width: parent.width + horizontalAlignment: Text.AlignLeft + } + + StyledText { + text: I18n.tr("Right-click and drag the bottom-right corner") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + width: parent.width + horizontalAlignment: Text.AlignLeft + } + } + } + } + } + } + } +} |