diff options
| author | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
|---|---|---|
| committer | Nippy <nippy@rp1.hu> | 2026-05-09 13:33:09 +0200 |
| commit | a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 (patch) | |
| tree | 1a8769217f84bfe9d6216fafaadaf8cdd876d457 /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals | |
| parent | 34b9c34f982b2596cfa9e368a2d7f74e9a17477c (diff) | |
| download | RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.tar.gz RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.zip | |
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals')
73 files changed, 0 insertions, 23391 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml deleted file mode 100644 index 2188111..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/AppPickerModal.qml +++ /dev/null @@ -1,471 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Modals.Common -import qs.Widgets -import qs.Services - -DankModal { - id: root - - property string title: I18n.tr("Select Application") - property string targetData: "" - property string targetDataLabel: "" - property string searchQuery: "" - property int selectedIndex: 0 - property int gridColumns: SettingsData.appLauncherGridColumns - property bool keyboardNavigationActive: false - property string viewMode: "grid" - property var categoryFilter: [] - property var usageHistoryKey: "" - property bool showTargetData: true - - signal applicationSelected(var app, string targetData) - - shouldBeVisible: false - allowStacking: true - modalWidth: 520 - modalHeight: 500 - - onBackgroundClicked: close() - - onDialogClosed: { - searchQuery = "" - selectedIndex = 0 - keyboardNavigationActive = false - } - - onOpened: { - searchQuery = "" - updateApplicationList() - selectedIndex = 0 - Qt.callLater(() => { - if (contentLoader.item && contentLoader.item.searchField) { - contentLoader.item.searchField.text = "" - contentLoader.item.searchField.forceActiveFocus() - } - }) - } - - function updateApplicationList() { - applicationsModel.clear() - const apps = AppSearchService.applications - const usageHistory = usageHistoryKey && SettingsData[usageHistoryKey] ? SettingsData[usageHistoryKey] : {} - let filteredApps = [] - - for (const app of apps) { - if (!app || !app.categories) continue - - let matchesCategory = categoryFilter.length === 0 - - if (categoryFilter.length > 0) { - try { - for (const cat of app.categories) { - if (categoryFilter.includes(cat)) { - matchesCategory = true - break - } - } - } catch (e) { - console.warn("AppPicker: Error iterating categories for", app.name, ":", e) - continue - } - } - - if (matchesCategory) { - const name = app.name || "" - const lowerName = name.toLowerCase() - const lowerQuery = searchQuery.toLowerCase() - - if (searchQuery === "" || lowerName.includes(lowerQuery)) { - filteredApps.push({ - name: name, - icon: app.icon || "application-x-executable", - exec: app.exec || app.execString || "", - startupClass: app.startupWMClass || "", - appData: app - }) - } - } - } - - filteredApps.sort((a, b) => { - const aId = a.appData.id || a.appData.execString || a.appData.exec || "" - const bId = b.appData.id || b.appData.execString || b.appData.exec || "" - const aUsage = usageHistory[aId] ? usageHistory[aId].count : 0 - const bUsage = usageHistory[bId] ? usageHistory[bId].count : 0 - if (aUsage !== bUsage) { - return bUsage - aUsage - } - return (a.name || "").localeCompare(b.name || "") - }) - - filteredApps.forEach(app => { - applicationsModel.append({ - name: app.name, - icon: app.icon, - exec: app.exec, - startupClass: app.startupClass, - appId: app.appData.id || app.appData.execString || app.appData.exec || "" - }) - }) - - console.log("AppPicker: Found " + filteredApps.length + " applications") - } - - onSearchQueryChanged: updateApplicationList() - - ListModel { - id: applicationsModel - } - - content: Component { - FocusScope { - id: appContent - - property alias searchField: searchField - - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - root.close() - event.accepted = true - } - - Keys.onPressed: event => { - if (applicationsModel.count === 0) return - - // Toggle view mode with Tab key - if (event.key === Qt.Key_Tab) { - root.viewMode = root.viewMode === "grid" ? "list" : "grid" - event.accepted = true - return - } - - if (root.viewMode === "grid") { - if (event.key === Qt.Key_Left) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.max(0, root.selectedIndex - 1) - event.accepted = true - } else if (event.key === Qt.Key_Right) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + 1) - event.accepted = true - } else if (event.key === Qt.Key_Up) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.max(0, root.selectedIndex - root.gridColumns) - event.accepted = true - } else if (event.key === Qt.Key_Down) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + root.gridColumns) - event.accepted = true - } - } else { - if (event.key === Qt.Key_Up) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.max(0, root.selectedIndex - 1) - event.accepted = true - } else if (event.key === Qt.Key_Down) { - root.keyboardNavigationActive = true - root.selectedIndex = Math.min(applicationsModel.count - 1, root.selectedIndex + 1) - event.accepted = true - } - } - - if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { - if (root.selectedIndex >= 0 && root.selectedIndex < applicationsModel.count) { - const app = applicationsModel.get(root.selectedIndex) - launchApplication(app) - } - event.accepted = true - } - } - - Column { - width: parent.width - Theme.spacingS * 2 - height: parent.height - Theme.spacingS * 2 - x: Theme.spacingS - y: Theme.spacingS - spacing: Theme.spacingS - - Item { - width: parent.width - height: 40 - - StyledText { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - text: root.title - font.pixelSize: Theme.fontSizeLarge + 4 - font.weight: Font.Bold - color: Theme.surfaceText - } - - Row { - spacing: 4 - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - - DankActionButton { - buttonSize: 36 - circular: false - iconName: "view_list" - iconSize: 20 - iconColor: root.viewMode === "list" ? Theme.primary : Theme.surfaceText - backgroundColor: root.viewMode === "list" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" - onClicked: { - root.viewMode = "list" - } - } - - DankActionButton { - buttonSize: 36 - circular: false - iconName: "grid_view" - iconSize: 20 - iconColor: root.viewMode === "grid" ? Theme.primary : Theme.surfaceText - backgroundColor: root.viewMode === "grid" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" - onClicked: { - root.viewMode = "grid" - } - } - } - } - - DankTextField { - id: searchField - - width: parent.width - Theme.spacingS * 2 - anchors.horizontalCenter: parent.horizontalCenter - height: 52 - cornerRadius: Theme.cornerRadius - backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: "search" - leftIconSize: Theme.iconSize - leftIconColor: Theme.surfaceVariantText - leftIconFocusedColor: Theme.primary - showClearButton: true - font.pixelSize: Theme.fontSizeLarge - enabled: root.shouldBeVisible - ignoreLeftRightKeys: root.viewMode !== "list" - ignoreTabKeys: true - keyForwardTargets: [appContent] - - onTextEdited: { - root.searchQuery = text - } - - Keys.onPressed: function (event) { - if (event.key === Qt.Key_Escape) { - root.close() - event.accepted = true - return - } - - const isEnterKey = [Qt.Key_Return, Qt.Key_Enter].includes(event.key) - const hasText = text.length > 0 - - if (isEnterKey && hasText) { - if (root.keyboardNavigationActive && applicationsModel.count > 0) { - const app = applicationsModel.get(root.selectedIndex) - launchApplication(app) - } else if (applicationsModel.count > 0) { - const app = applicationsModel.get(0) - launchApplication(app) - } - event.accepted = true - return - } - - const navigationKeys = [Qt.Key_Down, Qt.Key_Up, Qt.Key_Left, Qt.Key_Right, Qt.Key_Tab, Qt.Key_Backtab] - const isNavigationKey = navigationKeys.includes(event.key) - const isEmptyEnter = isEnterKey && !hasText - - event.accepted = !(isNavigationKey || isEmptyEnter) - } - - Connections { - function onShouldBeVisibleChanged() { - if (!root.shouldBeVisible) { - searchField.focus = false - } - } - - target: root - } - } - - Rectangle { - width: parent.width - height: { - let usedHeight = 40 + Theme.spacingS - usedHeight += 52 + Theme.spacingS - if (root.showTargetData) { - usedHeight += 36 + Theme.spacingS - } - return parent.height - usedHeight - } - radius: Theme.cornerRadius - color: "transparent" - - DankListView { - id: appList - - property int itemHeight: 60 - property int itemSpacing: Theme.spacingS - - function ensureVisible(index) { - if (index < 0 || index >= count) return - - const itemY = index * (itemHeight + itemSpacing) - const itemBottom = itemY + itemHeight - if (itemY < contentY) { - contentY = itemY - } else if (itemBottom > contentY + height) { - contentY = itemBottom - height - } - } - - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS - - visible: root.viewMode === "list" - model: applicationsModel - currentIndex: root.selectedIndex - clip: true - spacing: itemSpacing - - onCurrentIndexChanged: { - root.selectedIndex = currentIndex - if (root.keyboardNavigationActive) { - ensureVisible(currentIndex) - } - } - - delegate: AppLauncherListDelegate { - listView: appList - itemHeight: 60 - iconSize: 40 - showDescription: false - - isCurrentItem: index === root.selectedIndex - keyboardNavigationActive: root.keyboardNavigationActive - hoverUpdatesSelection: true - - onItemClicked: (idx, modelData) => { - launchApplication(modelData) - } - - onKeyboardNavigationReset: { - root.keyboardNavigationActive = false - } - } - } - - DankGridView { - id: appGrid - - function ensureVisible(index) { - if (index < 0 || index >= count) return - - const itemY = Math.floor(index / root.gridColumns) * cellHeight - const itemBottom = itemY + cellHeight - if (itemY < contentY) { - contentY = itemY - } else if (itemBottom > contentY + height) { - contentY = itemBottom - height - } - } - - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS - - visible: root.viewMode === "grid" - model: applicationsModel - cellWidth: width / root.gridColumns - cellHeight: 120 - clip: true - currentIndex: root.selectedIndex - - onCurrentIndexChanged: { - root.selectedIndex = currentIndex - if (root.keyboardNavigationActive) { - ensureVisible(currentIndex) - } - } - - delegate: AppLauncherGridDelegate { - gridView: appGrid - cellWidth: appGrid.cellWidth - cellHeight: appGrid.cellHeight - - currentIndex: root.selectedIndex - keyboardNavigationActive: root.keyboardNavigationActive - hoverUpdatesSelection: true - - onItemClicked: (idx, modelData) => { - launchApplication(modelData) - } - - onKeyboardNavigationReset: { - root.keyboardNavigationActive = false - } - } - } - } - - Rectangle { - width: parent.width - height: 36 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, 0.5) - border.color: Theme.outlineMedium - border.width: 1 - visible: root.showTargetData && root.targetData.length > 0 - - StyledText { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - text: root.targetDataLabel.length > 0 ? root.targetDataLabel + ": " + root.targetData : root.targetData - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - elide: Text.ElideMiddle - wrapMode: Text.NoWrap - maximumLineCount: 1 - } - } - } - - function launchApplication(app) { - if (!app) return - - root.applicationSelected(app, root.targetData) - - if (usageHistoryKey && app.appId) { - const usageHistory = SettingsData[usageHistoryKey] || {} - const currentCount = usageHistory[app.appId] ? usageHistory[app.appId].count : 0 - usageHistory[app.appId] = { - count: currentCount + 1, - lastUsed: Date.now(), - name: app.name - } - SettingsData.set(usageHistoryKey, usageHistory) - } - - root.close() - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml deleted file mode 100644 index cd3c9b7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BluetoothPairingModal.qml +++ /dev/null @@ -1,409 +0,0 @@ -import QtQuick -import Quickshell.Hyprland -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:bluetooth-pairing" - - HyprlandFocusGrab { - windows: [root.contentWindow] - active: root.useHyprlandFocusGrab && root.shouldHaveFocus - } - - property string deviceName: "" - property string deviceAddress: "" - property string requestType: "" - property string token: "" - property int passkey: 0 - property string pinInput: "" - property string passkeyInput: "" - - function show(pairingData) { - console.log("BluetoothPairingModal.show() called:", JSON.stringify(pairingData)); - token = pairingData.token || ""; - deviceName = pairingData.deviceName || ""; - deviceAddress = pairingData.deviceAddr || ""; - requestType = pairingData.requestType || ""; - passkey = pairingData.passkey || 0; - pinInput = ""; - passkeyInput = ""; - - console.log("BluetoothPairingModal: Calling open()"); - open(); - Qt.callLater(() => { - if (contentLoader.item) { - if (requestType === "pin" && contentLoader.item.pinInputField) { - contentLoader.item.pinInputField.forceActiveFocus(); - } else if (requestType === "passkey" && contentLoader.item.passkeyInputField) { - contentLoader.item.passkeyInputField.forceActiveFocus(); - } - } - }); - } - - shouldBeVisible: false - allowStacking: true - keepPopoutsOpen: true - modalWidth: 420 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 240 - - onShouldBeVisibleChanged: () => { - if (!shouldBeVisible) { - pinInput = ""; - passkeyInput = ""; - } - } - - onOpened: { - Qt.callLater(() => { - if (contentLoader.item) { - if (requestType === "pin" && contentLoader.item.pinInputField) { - contentLoader.item.pinInputField.forceActiveFocus(); - } else if (requestType === "passkey" && contentLoader.item.passkeyInputField) { - contentLoader.item.passkeyInputField.forceActiveFocus(); - } - } - }); - } - - onBackgroundClicked: () => { - if (token) { - DMSService.bluetoothCancelPairing(token); - } - close(); - token = ""; - pinInput = ""; - passkeyInput = ""; - } - - content: Component { - FocusScope { - id: pairingContent - - property alias pinInputField: pinInputField - property alias passkeyInputField: passkeyInputField - - anchors.fill: parent - focus: true - implicitHeight: mainColumn.implicitHeight - - Keys.onEscapePressed: event => { - if (token) { - DMSService.bluetoothCancelPairing(token); - } - close(); - token = ""; - pinInput = ""; - passkeyInput = ""; - event.accepted = true; - } - - Column { - id: mainColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingM - spacing: requestType === "pin" || requestType === "passkey" ? Theme.spacingM : Theme.spacingS - - Column { - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Pair Bluetooth Device") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: { - switch (requestType) { - case "confirm": - return I18n.tr("Confirm passkey for ") + deviceName; - case "display-passkey": - return I18n.tr("Enter this passkey on ") + deviceName; - case "authorize": - return I18n.tr("Authorize pairing with ") + deviceName; - case "pin": - return I18n.tr("Enter PIN for ") + deviceName; - case "passkey": - return I18n.tr("Enter passkey for ") + deviceName; - default: - if (requestType.startsWith("authorize-service")) - return I18n.tr("Authorize service for ") + deviceName; - return deviceName; - } - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - 40 - elide: Text.ElideRight - } - } - - Rectangle { - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: pinInputField.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: pinInputField.activeFocus ? 2 : 1 - visible: requestType === "pin" - - MouseArea { - anchors.fill: parent - onClicked: () => { - pinInputField.forceActiveFocus(); - } - } - - DankTextField { - id: pinInputField - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: pinInput - placeholderText: I18n.tr("Enter PIN") - backgroundColor: "transparent" - enabled: root.shouldBeVisible - onTextEdited: () => { - pinInput = text; - } - onAccepted: () => { - submitPairing(); - } - } - } - - Rectangle { - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: passkeyInputField.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: passkeyInputField.activeFocus ? 2 : 1 - visible: requestType === "passkey" - - MouseArea { - anchors.fill: parent - onClicked: () => { - passkeyInputField.forceActiveFocus(); - } - } - - DankTextField { - id: passkeyInputField - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: passkeyInput - placeholderText: I18n.tr("Enter 6-digit passkey") - backgroundColor: "transparent" - enabled: root.shouldBeVisible - onTextEdited: () => { - passkeyInput = text; - } - onAccepted: () => { - submitPairing(); - } - } - } - - Rectangle { - width: parent.width - height: 56 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - visible: requestType === "confirm" || requestType === "display-passkey" - - Column { - anchors.centerIn: parent - spacing: 2 - - StyledText { - text: I18n.tr("Passkey:") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: String(passkey).padStart(6, "0") - font.pixelSize: Theme.fontSizeXLarge - color: Theme.surfaceText - font.weight: Font.Bold - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Item { - width: parent.width - height: 36 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Rectangle { - width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - - StyledText { - id: cancelText - - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: () => { - if (token) { - DMSService.bluetoothCancelPairing(token); - } - close(); - token = ""; - pinInput = ""; - passkeyInput = ""; - } - } - } - - Rectangle { - width: Math.max(80, pairText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: pairArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - enabled: { - if (requestType === "pin") - return pinInput.length > 0; - if (requestType === "passkey") - return passkeyInput.length === 6; - return true; - } - opacity: enabled ? 1 : 0.5 - - StyledText { - id: pairText - - anchors.centerIn: parent - text: { - switch (requestType) { - case "confirm": - case "display-passkey": - return I18n.tr("Confirm"); - case "authorize": - return I18n.tr("Authorize"); - default: - if (requestType.startsWith("authorize-service")) - return I18n.tr("Authorize"); - return I18n.tr("Pair"); - } - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: pairArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: parent.enabled - onClicked: () => { - submitPairing(); - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - - DankActionButton { - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: () => { - if (token) { - DMSService.bluetoothCancelPairing(token); - } - close(); - token = ""; - pinInput = ""; - passkeyInput = ""; - } - } - } - } - - function submitPairing() { - const secrets = {}; - - switch (requestType) { - case "pin": - secrets["pin"] = pinInput; - break; - case "passkey": - secrets["passkey"] = passkeyInput; - break; - case "confirm": - case "display-passkey": - case "authorize": - secrets["decision"] = "yes"; - break; - default: - if (requestType.startsWith("authorize-service")) { - secrets["decision"] = "yes"; - } - break; - } - - DMSService.bluetoothSubmitPairing(token, secrets, true, response => { - if (response.error) { - ToastService.showError(I18n.tr("Pairing failed"), response.error); - } - }); - - close(); - token = ""; - pinInput = ""; - passkeyInput = ""; - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml deleted file mode 100644 index e4afcb8..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/BrowserPickerModal.qml +++ /dev/null @@ -1,51 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Modals - -AppPickerModal { - id: root - - property string url: "" - - title: I18n.tr("Open with...") - targetData: url - targetDataLabel: "" - categoryFilter: ["WebBrowser", "X-WebBrowser"] - viewMode: SettingsData.browserPickerViewMode || "grid" - usageHistoryKey: "browserUsageHistory" - showTargetData: true - - function shellEscape(str) { - return "'" + str.replace(/'/g, "'\\''") + "'" - } - - onApplicationSelected: (app, url) => { - if (!app) return - - let cmd = app.exec || "" - const escapedUrl = shellEscape(url) - - let hasField = false - if (cmd.includes("%u")) { cmd = cmd.replace("%u", escapedUrl); hasField = true } - else if (cmd.includes("%U")) { cmd = cmd.replace("%U", escapedUrl); hasField = true } - else if (cmd.includes("%f")) { cmd = cmd.replace("%f", escapedUrl); hasField = true } - else if (cmd.includes("%F")) { cmd = cmd.replace("%F", escapedUrl); hasField = true } - - cmd = cmd.replace(/%[ikc]/g, "") - - if (!hasField) { - cmd += " " + escapedUrl - } - - console.log("BrowserPicker: Launching", cmd) - - Quickshell.execDetached({ - command: ["sh", "-c", cmd] - }) - } - - onViewModeChanged: { - SettingsData.set("browserPickerViewMode", viewMode) - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml deleted file mode 100644 index 8fd3129..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogContent.qml +++ /dev/null @@ -1,250 +0,0 @@ -import QtQuick -import QtQuick.Effects -import qs.Common -import qs.Services -import qs.Widgets - -Column { - id: root - - readonly property real logoSize: Math.round(Theme.iconSize * 2.8) - readonly property real badgeHeight: Math.round(Theme.fontSizeSmall * 1.7) - - topPadding: Theme.spacingL - spacing: Theme.spacingL - - Column { - width: parent.width - spacing: Theme.spacingM - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Image { - width: root.logoSize - height: width * (569.94629 / 506.50931) - anchors.verticalCenter: parent.verticalCenter - fillMode: Image.PreserveAspectFit - smooth: true - mipmap: true - asynchronous: true - source: "file://" + Theme.shellDir + "/assets/danklogonormal.svg" - layer.enabled: true - layer.smooth: true - layer.mipmap: true - layer.effect: MultiEffect { - saturation: 0 - colorization: 1 - colorizationColor: Theme.primary - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - Row { - spacing: Theme.spacingS - - StyledText { - text: "DMS " + ChangelogService.currentVersion - font.pixelSize: Theme.fontSizeXLarge + 2 - font.weight: Font.Bold - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Rectangle { - width: codenameText.implicitWidth + Theme.spacingM * 2 - height: root.badgeHeight - radius: root.badgeHeight / 2 - color: Theme.primaryContainer - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: codenameText - anchors.centerIn: parent - text: "Saffron Bloom" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.primary - } - } - } - - StyledText { - text: "New launcher, enhanced plugin system, KDE Connect, & more" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - } - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.3 - } - - Column { - width: parent.width - spacing: Theme.spacingM - - StyledText { - text: "What's New" - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - } - - Grid { - width: parent.width - columns: 2 - rowSpacing: Theme.spacingS - columnSpacing: Theme.spacingS - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "space_dashboard" - title: "Dank Launcher V2" - description: "New capabilities & plugins" - onClicked: PopoutService.openDankLauncherV2() - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "smartphone" - title: "Phone Connect" - description: "KDE Connect & Valent" - onClicked: Qt.openUrlExternally("https://github.com/AvengeMedia/dms-plugins/tree/master/DankKDEConnect") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "monitor_heart" - title: "System Monitor" - description: "Redesigned process list" - onClicked: PopoutService.showProcessListModal() - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "window" - title: "Window Rules" - description: "niri window rule manager" - visible: CompositorService.isNiri - onClicked: PopoutService.openSettingsWithTab("window_rules") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "notifications_active" - title: "Enhanced Notifications" - description: "Configurable rules & styling" - visible: !CompositorService.isNiri - onClicked: PopoutService.openSettingsWithTab("notifications") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "dock_to_bottom" - title: "Dock Enhancements" - description: "Bar dock widget & more" - onClicked: PopoutService.openSettingsWithTab("dock") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "volume_up" - title: "Audio Aliases" - description: "Custom device names" - onClicked: PopoutService.openSettingsWithTab("audio") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "extension" - title: "Enhanced Plugin System" - description: "Enables new types of plugins" - onClicked: PopoutService.openSettingsWithTab("plugins") - } - - ChangelogFeatureCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "light_mode" - title: "Auto Light/Dark" - description: "Automatic mode switching" - onClicked: PopoutService.openSettingsWithTab("theme") - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.3 - } - - Column { - width: parent.width - spacing: Theme.spacingS - - Row { - spacing: Theme.spacingS - - DankIcon { - name: "warning" - size: Theme.iconSizeSmall - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: "Upgrade Notes" - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - width: parent.width - height: upgradeNotesColumn.height + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.warning, 0.08) - border.width: 1 - border.color: Theme.withAlpha(Theme.warning, 0.2) - - Column { - id: upgradeNotesColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - - ChangelogUpgradeNote { - width: parent.width - text: "Spotlight replaced by Dank Launcher V2 — check settings for new options" - } - - ChangelogUpgradeNote { - width: parent.width - text: "Plugin API updated — third-party plugins may need updates" - } - } - } - - // StyledText { - // text: "See full release notes for migration steps" - // font.pixelSize: Theme.fontSizeSmall - // color: Theme.surfaceVariantText - // width: parent.width - // } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml deleted file mode 100644 index eab4f70..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogFeatureCard.qml +++ /dev/null @@ -1,78 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property string iconName: "" - property string title: "" - property string description: "" - - signal clicked - - readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.3) - - height: Math.round(Theme.fontSizeMedium * 4.2) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: Theme.primary - opacity: mouseArea.containsMouse ? 0.12 : 0 - } - - Row { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - - Rectangle { - width: root.iconContainerSize - height: root.iconContainerSize - radius: Math.round(root.iconContainerSize * 0.28) - color: Theme.primaryContainer - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: root.iconName - size: Theme.iconSize - 6 - color: Theme.primary - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - width: parent.width - root.iconContainerSize - Theme.spacingS - - StyledText { - text: root.title - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceText - } - - StyledText { - text: root.description - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - width: parent.width - elide: Text.ElideRight - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.clicked() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml deleted file mode 100644 index 524298b..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogModal.qml +++ /dev/null @@ -1,156 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - readonly property int modalWidth: 680 - readonly property int modalHeight: screen ? Math.min(720, screen.height - 80) : 720 - - signal changelogDismissed - - function show() { - visible = true; - } - - objectName: "changelogModal" - title: i18n("What's New") - minimumSize: Qt.size(modalWidth, modalHeight) - maximumSize: Qt.size(modalWidth, modalHeight) - color: Theme.surfaceContainer - visible: false - - FocusScope { - id: contentFocusScope - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - root.dismiss(); - event.accepted = true; - } - - Keys.onPressed: event => { - switch (event.key) { - case Qt.Key_Return: - case Qt.Key_Enter: - root.dismiss(); - event.accepted = true; - break; - } - } - - MouseArea { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: headerRow.height + Theme.spacingM - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - Item { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - height: Math.round(Theme.fontSizeMedium * 2.85) - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported && windowControls.canMaximize - iconName: root.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.dismiss() - - DankTooltip { - text: i18n("Close") - } - } - } - } - - DankFlickable { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerRow.bottom - anchors.bottom: footerRow.top - anchors.topMargin: Theme.spacingS - clip: true - contentHeight: mainColumn.height + Theme.spacingL * 2 - contentWidth: width - - ChangelogContent { - id: mainColumn - anchors.horizontalCenter: parent.horizontalCenter - width: Math.min(600, parent.width - Theme.spacingXL * 2) - } - } - - Rectangle { - id: footerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Math.round(Theme.fontSizeMedium * 4.5) - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.top: parent.top - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.5 - } - - Row { - anchors.centerIn: parent - spacing: Theme.spacingM - - DankButton { - text: i18n("Read Full Release Notes") - iconName: "open_in_new" - backgroundColor: Theme.surfaceContainerHighest - textColor: Theme.surfaceText - onClicked: Qt.openUrlExternally("https://danklinux.com/blog/v1-4-release") - } - - DankButton { - text: i18n("Got It") - iconName: "check" - backgroundColor: Theme.primary - textColor: Theme.primaryText - onClicked: root.dismiss() - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } - - function dismiss() { - ChangelogService.dismissChangelog(); - changelogDismissed(); - visible = false; - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml deleted file mode 100644 index 545eb9a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Changelog/ChangelogUpgradeNote.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Row { - id: root - - property alias text: noteText.text - - spacing: Theme.spacingS - - DankIcon { - name: "arrow_right" - size: Theme.iconSizeSmall - 2 - color: Theme.surfaceVariantText - anchors.top: parent.top - anchors.topMargin: 2 - } - - StyledText { - id: noteText - width: root.width - Theme.iconSizeSmall - Theme.spacingS - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - wrapMode: Text.WordWrap - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml deleted file mode 100644 index f796ffe..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardConstants.qml +++ /dev/null @@ -1,21 +0,0 @@ -pragma Singleton - -import QtQuick -import Quickshell - -Singleton { - id: root - readonly property int previewLength: 100 - readonly property int longTextThreshold: 200 - readonly property int modalWidth: 650 - readonly property int modalHeight: 550 - readonly property int popoutWidth: 550 - readonly property int popoutHeight: 500 - readonly property int itemHeight: 72 - readonly property int thumbnailSize: 100 - readonly property int retryInterval: 50 - readonly property int viewportBuffer: 100 - readonly property int extendedBuffer: 200 - readonly property int keyboardHintsHeight: 80 - readonly property int headerHeight: 32 -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml deleted file mode 100644 index e00bc22..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardContent.qml +++ /dev/null @@ -1,260 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Widgets - -Item { - id: clipboardContent - - required property var modal - required property var clearConfirmDialog - - property alias searchField: searchField - property alias clipboardListView: clipboardListView - - anchors.fill: parent - - Column { - id: headerColumn - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingM - spacing: Theme.spacingM - focus: false - - ClipboardHeader { - id: header - width: parent.width - totalCount: modal.totalCount - showKeyboardHints: modal.showKeyboardHints - activeTab: modal.activeTab - pinnedCount: modal.pinnedCount - onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints - onTabChanged: tabName => modal.activeTab = tabName - onClearAllClicked: { - const hasPinned = modal.pinnedCount > 0; - const message = hasPinned ? I18n.tr("This will delete all unpinned entries. %1 pinned entries will be kept.").arg(modal.pinnedCount) : I18n.tr("This will permanently delete all clipboard history."); - clearConfirmDialog.show(I18n.tr("Clear History?"), message, function () { - modal.clearAll(); - modal.hide(); - }, function () {}); - } - onCloseClicked: modal.hide() - } - - DankTextField { - id: searchField - width: parent.width - placeholderText: "" - leftIconName: "search" - showClearButton: true - focus: true - ignoreTabKeys: true - keyForwardTargets: [modal.modalFocusScope] - onTextChanged: { - modal.searchText = text; - modal.updateFilteredModel(); - } - Keys.onEscapePressed: function (event) { - modal.hide(); - event.accepted = true; - } - Component.onCompleted: { - Qt.callLater(function () { - forceActiveFocus(); - }); - } - - Connections { - target: modal - function onOpened() { - Qt.callLater(function () { - searchField.forceActiveFocus(); - }); - } - } - } - } - - Item { - id: listContainer - anchors.top: headerColumn.bottom - anchors.topMargin: Theme.spacingM - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.bottomMargin: (modal.showKeyboardHints ? (ClipboardConstants.keyboardHintsHeight + Theme.spacingM * 2) : 0) + Theme.spacingXS - clip: true - - DankListView { - id: clipboardListView - anchors.fill: parent - model: ScriptModel { - values: clipboardContent.modal.unpinnedEntries - objectProp: "id" - } - visible: modal.activeTab === "recents" - - currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0 - spacing: Theme.spacingXS - interactive: true - flickDeceleration: 1500 - maximumFlickVelocity: 2000 - boundsBehavior: Flickable.DragAndOvershootBounds - boundsMovement: Flickable.FollowBoundsBehavior - pressDelay: 0 - flickableDirection: Flickable.VerticalFlick - - function ensureVisible(index) { - if (index < 0 || index >= count) { - return; - } - positionViewAtIndex(index, ListView.Contain); - } - - onCurrentIndexChanged: { - if (clipboardContent.modal?.keyboardNavigationActive && currentIndex >= 0) { - ensureVisible(currentIndex); - } - } - - StyledText { - text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No recent clipboard entries found") : I18n.tr("Connecting to clipboard service…") - anchors.centerIn: parent - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - visible: clipboardContent.modal.unpinnedEntries.length === 0 - } - - delegate: ClipboardEntry { - required property int index - required property var modelData - - width: clipboardListView.width - height: ClipboardConstants.itemHeight - entry: modelData - entryIndex: index + 1 - itemIndex: index - isSelected: clipboardContent.modal?.keyboardNavigationActive && index === clipboardContent.modal.selectedIndex - modal: clipboardContent.modal - listView: clipboardListView - onCopyRequested: clipboardContent.modal.copyEntry(modelData) - onDeleteRequested: clipboardContent.modal.deleteEntry(modelData) - onPinRequested: clipboardContent.modal.pinEntry(modelData) - onUnpinRequested: clipboardContent.modal.unpinEntry(modelData) - } - } - - DankListView { - id: savedListView - anchors.fill: parent - model: ScriptModel { - values: clipboardContent.modal.pinnedEntries - objectProp: "id" - } - visible: modal.activeTab === "saved" - - currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0 - spacing: Theme.spacingXS - interactive: true - flickDeceleration: 1500 - maximumFlickVelocity: 2000 - boundsBehavior: Flickable.DragAndOvershootBounds - boundsMovement: Flickable.FollowBoundsBehavior - pressDelay: 0 - flickableDirection: Flickable.VerticalFlick - - function ensureVisible(index) { - if (index < 0 || index >= count) { - return; - } - positionViewAtIndex(index, ListView.Contain); - } - - onCurrentIndexChanged: { - if (clipboardContent.modal?.keyboardNavigationActive && currentIndex >= 0) { - ensureVisible(currentIndex); - } - } - - StyledText { - text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No saved clipboard entries") : I18n.tr("Connecting to clipboard service…") - anchors.centerIn: parent - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - visible: clipboardContent.modal.pinnedEntries.length === 0 - } - - delegate: ClipboardEntry { - required property int index - required property var modelData - - width: savedListView.width - height: ClipboardConstants.itemHeight - entry: modelData - entryIndex: index + 1 - itemIndex: index - isSelected: clipboardContent.modal?.keyboardNavigationActive && index === clipboardContent.modal.selectedIndex - modal: clipboardContent.modal - listView: savedListView - onCopyRequested: clipboardContent.modal.copyEntry(modelData) - onDeleteRequested: clipboardContent.modal.deletePinnedEntry(modelData) - onPinRequested: clipboardContent.modal.pinEntry(modelData) - onUnpinRequested: clipboardContent.modal.unpinEntry(modelData) - } - } - - Rectangle { - id: bottomFade - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 24 - z: 100 - visible: { - const listView = modal.activeTab === "recents" ? clipboardListView : savedListView; - if (listView.contentHeight <= listView.height) - return false; - const atBottom = listView.contentY >= listView.contentHeight - listView.height - 5; - return !atBottom; - } - gradient: Gradient { - GradientStop { - position: 0.0 - color: "transparent" - } - GradientStop { - position: 1.0 - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - } - } - } - } - - Loader { - id: keyboardHintsLoader - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.bottomMargin: active ? Theme.spacingM : 0 - active: modal.showKeyboardHints - height: active ? ClipboardConstants.keyboardHintsHeight : 0 - - Behavior on height { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - sourceComponent: ClipboardKeyboardHints { - wtypeAvailable: modal.wtypeAvailable - enterToPaste: SettingsData.clipboardEnterToPaste - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml deleted file mode 100644 index 53a2ece..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardEntry.qml +++ /dev/null @@ -1,155 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - required property var entry - required property int entryIndex - required property int itemIndex - required property bool isSelected - required property var modal - required property var listView - - signal copyRequested - signal deleteRequested - signal pinRequested - signal unpinRequested - - readonly property string entryType: modal ? modal.getEntryType(entry) : "text" - readonly property string entryPreview: modal ? modal.getEntryPreview(entry) : "" - readonly property bool hasPinnedDuplicate: !entry.pinned && ClipboardService.hashedPinnedEntry(entry.hash) - - radius: Theme.cornerRadius - color: { - if (isSelected) { - return Theme.primaryPressed; - } - return mouseArea.containsMouse ? Theme.primaryHoverLight : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency); - } - - DankRipple { - id: rippleLayer - rippleColor: Theme.surfaceText - cornerRadius: root.radius - } - - Rectangle { - id: indexBadge - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - width: 24 - height: 24 - radius: 12 - color: Theme.primarySelected - - StyledText { - anchors.centerIn: parent - text: entryIndex.toString() - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Bold - color: Theme.primary - } - } - - Row { - id: actionButtons - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - DankActionButton { - iconName: "push_pin" - iconSize: Theme.iconSize - 6 - iconColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primary : Theme.surfaceText - backgroundColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primarySelected : "transparent" - onClicked: entry.pinned ? unpinRequested() : pinRequested() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 6 - iconColor: Theme.surfaceText - onClicked: deleteRequested() - } - } - - Item { - anchors.left: indexBadge.right - anchors.leftMargin: Theme.spacingM - anchors.right: actionButtons.left - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - // height: contentColumn.implicitHeight - height: ClipboardConstants.itemHeight - clip: true - - ClipboardThumbnail { - id: thumbnail - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - width: entryType === "image" ? ClipboardConstants.thumbnailSize : Theme.iconSize - height: entryType === "image" ? ClipboardConstants.itemHeight - 4 : Theme.iconSize // 100 - 4 = 96, 96:72 = 4:3 - entry: root.entry - entryType: root.entryType - modal: root.modal - listView: root.listView - itemIndex: root.itemIndex - } - - Column { - id: contentColumn - anchors.left: thumbnail.right - anchors.leftMargin: Theme.spacingM - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - StyledText { - text: { - switch (entryType) { - case "image": - return I18n.tr("Image") + " • " + entryPreview; - case "long_text": - return I18n.tr("Long Text"); - default: - return I18n.tr("Text"); - } - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.primary - font.weight: Font.Medium - width: parent.width - elide: Text.ElideRight - } - - StyledText { - text: entryPreview - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - wrapMode: Text.WordWrap - maximumLineCount: entryType === "long_text" ? 3 : 1 - elide: Text.ElideRight - textFormat: Text.PlainText - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - anchors.rightMargin: 80 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => { - const pos = mouseArea.mapToItem(root, mouse.x, mouse.y); - rippleLayer.trigger(pos.x, pos.y); - } - onClicked: copyRequested() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml deleted file mode 100644 index fedba15..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHeader.qml +++ /dev/null @@ -1,87 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets -import qs.Modals.Clipboard - -Item { - id: header - - property int totalCount: 0 - property bool showKeyboardHints: false - property string activeTab: "recents" - property int pinnedCount: 0 - - signal keyboardHintsToggled - signal clearAllClicked - signal closeClicked - signal tabChanged(string tabName) - - height: ClipboardConstants.headerHeight - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: "content_paste" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Clipboard History") + ` (${totalCount})` - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - DankActionButton { - iconName: "push_pin" - iconSize: Theme.iconSize - 4 - iconColor: header.activeTab === "saved" ? Theme.primary : Theme.surfaceText - visible: header.pinnedCount > 0 - tooltipText: I18n.tr("Saved") - onClicked: tabChanged("saved") - } - - DankActionButton { - iconName: "history" - iconSize: Theme.iconSize - 4 - iconColor: header.activeTab === "recents" ? Theme.primary : Theme.surfaceText - tooltipText: I18n.tr("History") - onClicked: tabChanged("recents") - } - - DankActionButton { - iconName: "info" - iconSize: Theme.iconSize - 4 - iconColor: showKeyboardHints ? Theme.primary : Theme.surfaceText - tooltipText: I18n.tr("Keyboard Shortcuts") - onClicked: keyboardHintsToggled() - } - - DankActionButton { - iconName: "delete_sweep" - iconSize: Theme.iconSize - iconColor: Theme.surfaceText - tooltipText: I18n.tr("Clear All") - onClicked: clearAllClicked() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: closeClicked() - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml deleted file mode 100644 index 2f76cc7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryModal.qml +++ /dev/null @@ -1,174 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell.Hyprland -import qs.Common -import qs.Modals.Clipboard -import qs.Modals.Common -import qs.Services - -DankModal { - id: clipboardHistoryModal - - layerNamespace: "dms:clipboard" - - HyprlandFocusGrab { - windows: [clipboardHistoryModal.contentWindow] - active: clipboardHistoryModal.useHyprlandFocusGrab && clipboardHistoryModal.shouldHaveFocus - } - - property string activeTab: "recents" - onActiveTabChanged: { - ClipboardService.selectedIndex = 0; - ClipboardService.keyboardNavigationActive = false; - } - property bool showKeyboardHints: false - property Component clipboardContent - property int activeImageLoads: 0 - readonly property int maxConcurrentLoads: 3 - - readonly property bool clipboardAvailable: ClipboardService.clipboardAvailable - readonly property bool wtypeAvailable: ClipboardService.wtypeAvailable - readonly property int totalCount: ClipboardService.totalCount - readonly property var clipboardEntries: ClipboardService.clipboardEntries - readonly property var pinnedEntries: ClipboardService.pinnedEntries - readonly property int pinnedCount: ClipboardService.pinnedCount - readonly property var unpinnedEntries: ClipboardService.unpinnedEntries - readonly property int selectedIndex: ClipboardService.selectedIndex - readonly property bool keyboardNavigationActive: ClipboardService.keyboardNavigationActive - property string searchText: ClipboardService.searchText - onSearchTextChanged: ClipboardService.searchText = searchText - - Ref { - service: ClipboardService - } - - function updateFilteredModel() { - ClipboardService.updateFilteredModel(); - } - - function pasteSelected() { - ClipboardService.pasteSelected(instantClose); - } - - function toggle() { - if (shouldBeVisible) { - hide(); - } else { - show(); - } - } - - function show() { - open(); - activeImageLoads = 0; - shouldHaveFocus = true; - ClipboardService.reset(); - if (clipboardAvailable) - ClipboardService.refresh(); - keyboardController.reset(); - - Qt.callLater(function () { - if (contentLoader.item?.searchField) { - contentLoader.item.searchField.text = ""; - contentLoader.item.searchField.forceActiveFocus(); - } - }); - } - - function hide() { - close(); - } - - onDialogClosed: { - activeImageLoads = 0; - ClipboardService.reset(); - keyboardController.reset(); - } - - function refreshClipboard() { - ClipboardService.refresh(); - } - - function copyEntry(entry) { - ClipboardService.copyEntry(entry, hide); - } - - function deleteEntry(entry) { - ClipboardService.deleteEntry(entry); - } - - function deletePinnedEntry(entry) { - ClipboardService.deletePinnedEntry(entry, clearConfirmDialog); - } - - function pinEntry(entry) { - ClipboardService.pinEntry(entry); - } - - function unpinEntry(entry) { - ClipboardService.unpinEntry(entry); - } - - function clearAll() { - ClipboardService.clearAll(); - } - - function getEntryPreview(entry) { - return ClipboardService.getEntryPreview(entry); - } - - function getEntryType(entry) { - return ClipboardService.getEntryType(entry); - } - - visible: false - modalWidth: ClipboardConstants.modalWidth - modalHeight: ClipboardConstants.modalHeight - backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - cornerRadius: Theme.cornerRadius - borderColor: Theme.outlineMedium - borderWidth: 1 - enableShadow: true - onBackgroundClicked: hide() - modalFocusScope.Keys.onPressed: function (event) { - keyboardController.handleKey(event); - } - content: clipboardContent - - ClipboardKeyboardController { - id: keyboardController - modal: clipboardHistoryModal - } - - ConfirmModal { - id: clearConfirmDialog - confirmButtonText: I18n.tr("Clear All") - confirmButtonColor: Theme.primary - onVisibleChanged: { - if (visible) { - clipboardHistoryModal.shouldHaveFocus = false; - return; - } - Qt.callLater(function () { - if (!clipboardHistoryModal.shouldBeVisible) { - return; - } - clipboardHistoryModal.shouldHaveFocus = true; - clipboardHistoryModal.modalFocusScope.forceActiveFocus(); - if (clipboardHistoryModal.contentLoader.item?.searchField) { - clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus(); - } - }); - } - } - - property var confirmDialog: clearConfirmDialog - - clipboardContent: Component { - ClipboardContent { - modal: clipboardHistoryModal - clearConfirmDialog: clipboardHistoryModal.confirmDialog - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml deleted file mode 100644 index c4f0296..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardHistoryPopout.qml +++ /dev/null @@ -1,197 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Modals.Clipboard -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankPopout { - id: root - - layerNamespace: "dms:clipboard-popout" - - property var parentWidget: null - property var triggerScreen: null - property string activeTab: "recents" - property bool showKeyboardHints: false - property int activeImageLoads: 0 - readonly property int maxConcurrentLoads: 3 - - readonly property bool clipboardAvailable: ClipboardService.clipboardAvailable - readonly property bool wtypeAvailable: ClipboardService.wtypeAvailable - readonly property int totalCount: ClipboardService.totalCount - readonly property var clipboardEntries: ClipboardService.clipboardEntries - readonly property var pinnedEntries: ClipboardService.pinnedEntries - readonly property int pinnedCount: ClipboardService.pinnedCount - readonly property var unpinnedEntries: ClipboardService.unpinnedEntries - readonly property int selectedIndex: ClipboardService.selectedIndex - readonly property bool keyboardNavigationActive: ClipboardService.keyboardNavigationActive - property string searchText: ClipboardService.searchText - onSearchTextChanged: ClipboardService.searchText = searchText - - readonly property var modalFocusScope: contentLoader.item ?? null - - Ref { - service: ClipboardService - } - - function updateFilteredModel() { - ClipboardService.updateFilteredModel(); - } - - function pasteSelected() { - ClipboardService.pasteSelected(instantClose); - } - - function instantClose() { - close(); - } - - function show() { - open(); - activeImageLoads = 0; - ClipboardService.reset(); - if (clipboardAvailable) - ClipboardService.refresh(); - keyboardController.reset(); - - Qt.callLater(function () { - if (contentLoader.item?.searchField) { - contentLoader.item.searchField.text = ""; - contentLoader.item.searchField.forceActiveFocus(); - } - }); - } - - function hide() { - close(); - activeImageLoads = 0; - ClipboardService.reset(); - keyboardController.reset(); - } - - function refreshClipboard() { - ClipboardService.refresh(); - } - - function copyEntry(entry) { - ClipboardService.copyEntry(entry, hide); - } - - function deleteEntry(entry) { - ClipboardService.deleteEntry(entry); - } - - function deletePinnedEntry(entry) { - ClipboardService.deletePinnedEntry(entry, clearConfirmDialog); - } - - function pinEntry(entry) { - ClipboardService.pinEntry(entry); - } - - function unpinEntry(entry) { - ClipboardService.unpinEntry(entry); - } - - function clearAll() { - ClipboardService.clearAll(); - } - - function getEntryPreview(entry) { - return ClipboardService.getEntryPreview(entry); - } - - function getEntryType(entry) { - return ClipboardService.getEntryType(entry); - } - - popupWidth: ClipboardConstants.popoutWidth - popupHeight: ClipboardConstants.popoutHeight - triggerWidth: 55 - positioning: "" - screen: triggerScreen - shouldBeVisible: false - contentHandlesKeys: true - - onBackgroundClicked: hide() - - onShouldBeVisibleChanged: { - if (!shouldBeVisible) - return; - if (clipboardAvailable) - ClipboardService.refresh(); - keyboardController.reset(); - Qt.callLater(function () { - if (contentLoader.item?.searchField) { - contentLoader.item.searchField.text = ""; - contentLoader.item.searchField.forceActiveFocus(); - } - }); - } - - onPopoutClosed: { - activeImageLoads = 0; - ClipboardService.reset(); - keyboardController.reset(); - } - - ClipboardKeyboardController { - id: keyboardController - modal: root - } - - ConfirmModal { - id: clearConfirmDialog - confirmButtonText: I18n.tr("Clear All") - confirmButtonColor: Theme.primary - } - - property var confirmDialog: clearConfirmDialog - - content: Component { - FocusScope { - id: contentFocusScope - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - focus: true - - property alias searchField: clipboardContentItem.searchField - - Keys.onPressed: function (event) { - keyboardController.handleKey(event); - } - - Component.onCompleted: { - if (root.shouldBeVisible) - forceActiveFocus(); - } - - Connections { - target: root - function onShouldBeVisibleChanged() { - if (root.shouldBeVisible) { - Qt.callLater(() => contentFocusScope.forceActiveFocus()); - } - } - function onOpened() { - Qt.callLater(() => { - if (clipboardContentItem.searchField) { - clipboardContentItem.searchField.forceActiveFocus(); - } - }); - } - } - - ClipboardContent { - id: clipboardContentItem - modal: root - clearConfirmDialog: root.confirmDialog - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml deleted file mode 100644 index f2a457e..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardController.qml +++ /dev/null @@ -1,166 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services - -QtObject { - id: keyboardController - - required property var modal - - function reset() { - ClipboardService.selectedIndex = 0; - ClipboardService.keyboardNavigationActive = false; - modal.showKeyboardHints = false; - } - - function selectNext() { - const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries; - if (!entries || entries.length === 0) { - return; - } - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = Math.min(ClipboardService.selectedIndex + 1, entries.length - 1); - } - - function selectPrevious() { - const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries; - if (!entries || entries.length === 0) { - return; - } - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = Math.max(ClipboardService.selectedIndex - 1, 0); - } - - function copySelected() { - const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries; - if (!entries || entries.length === 0 || ClipboardService.selectedIndex < 0 || ClipboardService.selectedIndex >= entries.length) { - return; - } - const selectedEntry = entries[ClipboardService.selectedIndex]; - modal.copyEntry(selectedEntry); - } - - function deleteSelected() { - const entries = modal.activeTab === "saved" ? ClipboardService.pinnedEntries : ClipboardService.unpinnedEntries; - if (!entries || entries.length === 0 || ClipboardService.selectedIndex < 0 || ClipboardService.selectedIndex >= entries.length) { - return; - } - const selectedEntry = entries[ClipboardService.selectedIndex]; - if (modal.activeTab === "saved") { - modal.deletePinnedEntry(selectedEntry); - } else { - modal.deleteEntry(selectedEntry); - } - } - - function handleKey(event) { - switch (event.key) { - case Qt.Key_Escape: - if (ClipboardService.keyboardNavigationActive) { - ClipboardService.keyboardNavigationActive = false; - } else { - modal.hide(); - } - event.accepted = true; - return; - case Qt.Key_Down: - case Qt.Key_Tab: - if (!ClipboardService.keyboardNavigationActive) { - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = 0; - } else { - selectNext(); - } - event.accepted = true; - return; - case Qt.Key_Up: - case Qt.Key_Backtab: - if (!ClipboardService.keyboardNavigationActive) { - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = 0; - } else if (ClipboardService.selectedIndex === 0) { - ClipboardService.keyboardNavigationActive = false; - } else { - selectPrevious(); - } - event.accepted = true; - return; - case Qt.Key_F10: - modal.showKeyboardHints = !modal.showKeyboardHints; - event.accepted = true; - return; - } - - if (event.modifiers & Qt.ControlModifier) { - switch (event.key) { - case Qt.Key_N: - case Qt.Key_J: - if (!ClipboardService.keyboardNavigationActive) { - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = 0; - } else { - selectNext(); - } - event.accepted = true; - return; - case Qt.Key_P: - case Qt.Key_K: - if (!ClipboardService.keyboardNavigationActive) { - ClipboardService.keyboardNavigationActive = true; - ClipboardService.selectedIndex = 0; - } else if (ClipboardService.selectedIndex === 0) { - ClipboardService.keyboardNavigationActive = false; - } else { - selectPrevious(); - } - event.accepted = true; - return; - case Qt.Key_C: - if (ClipboardService.keyboardNavigationActive) { - copySelected(); - event.accepted = true; - } - return; - } - } - - if (event.modifiers & Qt.ShiftModifier) { - switch (event.key) { - case Qt.Key_Delete: - modal.clearAll(); - modal.hide(); - event.accepted = true; - return; - case Qt.Key_Return: - case Qt.Key_Enter: - if (ClipboardService.keyboardNavigationActive) { - if (SettingsData.clipboardEnterToPaste) { - copySelected(); - } else { - modal.pasteSelected(); - } - event.accepted = true; - } - return; - } - } - - if (ClipboardService.keyboardNavigationActive) { - switch (event.key) { - case Qt.Key_Return: - case Qt.Key_Enter: - if (SettingsData.clipboardEnterToPaste) { - modal.pasteSelected(); - } else { - copySelected(); - } - event.accepted = true; - return; - case Qt.Key_Delete: - deleteSelected(); - event.accepted = true; - return; - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml deleted file mode 100644 index 0285952..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardKeyboardHints.qml +++ /dev/null @@ -1,51 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: keyboardHints - - property bool wtypeAvailable: false - property bool enterToPaste: false - readonly property string hintsText: { - if (!wtypeAvailable) - return I18n.tr("Shift+Del: Clear All • Esc: Close"); - return enterToPaste ? I18n.tr("Shift+Enter: Copy • Shift+Del: Clear All • Esc: Close", "Keyboard hints when enter-to-paste is enabled") : I18n.tr("Shift+Enter: Paste • Shift+Del: Clear All • Esc: Close"); - } - - height: ClipboardConstants.keyboardHintsHeight - radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) - border.color: Theme.primary - border.width: 2 - opacity: visible ? 1 : 0 - z: 100 - - Column { - anchors.centerIn: parent - spacing: 2 - - StyledText { - text: keyboardHints.enterToPaste - ? I18n.tr("↑/↓: Navigate • Enter: Paste • Del: Delete • F10: Help", "Keyboard hints when enter-to-paste is enabled") - : I18n.tr("↑/↓: Navigate • Enter/Ctrl+C: Copy • Del: Delete • F10: Help") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: keyboardHints.hintsText - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml deleted file mode 100644 index 26a9210..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Clipboard/ClipboardThumbnail.qml +++ /dev/null @@ -1,178 +0,0 @@ -import QtQuick -import QtQuick.Effects -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: thumbnail - - required property var entry - required property string entryType - required property var modal - required property var listView - required property int itemIndex - - Image { - id: thumbnailImage - - property bool isVisible: false - property string cachedImageData: "" - property bool loadQueued: false - - anchors.fill: parent - source: cachedImageData ? `data:image/png;base64,${cachedImageData}` : "" - fillMode: Image.PreserveAspectCrop - smooth: true - cache: false - visible: false - asynchronous: true - sourceSize.width: 128 - sourceSize.height: 128 - - function tryLoadImage() { - if (thumbnailImage.loadQueued || entryType !== "image" || thumbnailImage.cachedImageData) { - return; - } - thumbnailImage.loadQueued = true; - if (modal.activeImageLoads < modal.maxConcurrentLoads) { - modal.activeImageLoads++; - thumbnailImage.loadImage(); - } else { - retryTimer.restart(); - } - } - - function loadImage() { - DMSService.sendRequest("clipboard.getEntry", { - "id": entry.id - }, function (response) { - thumbnailImage.loadQueued = false; - if (modal.activeImageLoads > 0) { - modal.activeImageLoads--; - } - if (response.error) { - console.warn("ClipboardThumbnail: Failed to load image:", entry.id); - return; - } - const data = response.result?.data; - if (data) { - thumbnailImage.cachedImageData = data; - } - }); - } - - Timer { - id: retryTimer - interval: ClipboardConstants.retryInterval - onTriggered: { - if (!thumbnailImage.loadQueued) { - return; - } - if (modal.activeImageLoads < modal.maxConcurrentLoads) { - modal.activeImageLoads++; - thumbnailImage.loadImage(); - } else { - retryTimer.restart(); - } - } - } - - Component.onCompleted: { - if (entryType !== "image" || listView.height <= 0) { - return; - } - - const itemY = itemIndex * (ClipboardConstants.itemHeight + listView.spacing); - const viewTop = listView.contentY; - const viewBottom = viewTop + listView.height; - isVisible = (itemY + ClipboardConstants.itemHeight >= viewTop && itemY <= viewBottom); - - if (isVisible) { - tryLoadImage(); - } - } - - Timer { - id: visibilityTimer - interval: 100 - onTriggered: thumbnailImage.checkVisibility() - } - - function checkVisibility() { - if (entryType !== "image" || listView.height <= 0 || isVisible) { - return; - } - const itemY = itemIndex * (ClipboardConstants.itemHeight + listView.spacing); - const viewTop = listView.contentY - ClipboardConstants.viewportBuffer; - const viewBottom = viewTop + listView.height + ClipboardConstants.extendedBuffer; - const nowVisible = (itemY + ClipboardConstants.itemHeight >= viewTop && itemY <= viewBottom); - if (nowVisible) { - isVisible = true; - tryLoadImage(); - } - } - - Connections { - target: listView - - function onContentYChanged() { - if (thumbnailImage.isVisible || entryType !== "image") { - return; - } - visibilityTimer.restart(); - } - - function onHeightChanged() { - if (thumbnailImage.isVisible || entryType !== "image") { - return; - } - visibilityTimer.restart(); - } - } - } - - MultiEffect { - anchors.fill: parent - anchors.margins: 2 - source: thumbnailImage - maskEnabled: true - maskSource: clipboardRoundedRectangularMask - visible: entryType === "image" && thumbnailImage.status === Image.Ready && thumbnailImage.source != "" - maskThresholdMin: 0.5 - maskSpreadAtMin: 1 - } - - Item { - id: clipboardRoundedRectangularMask - width: ClipboardConstants.thumbnailSize - height: ClipboardConstants.itemHeight - 4 - layer.enabled: true - layer.smooth: true - visible: false - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius / 2 // Thumbnail corner radius is divided by 2 so it doesnt look weird on large corner radius (eg: 32px) - color: "black" - antialiasing: true - } - } - - DankIcon { - visible: !(entryType === "image" && thumbnailImage.status === Image.Ready && thumbnailImage.source != "") - name: { - switch (entryType) { - case "image": - return "image"; - case "long_text": - return "subject"; - default: - return "content_copy"; - } - } - size: Theme.iconSize - color: Theme.primary - anchors.centerIn: parent - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml deleted file mode 100644 index b9c9b90..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/ConfirmModal.qml +++ /dev/null @@ -1,291 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modals.Common -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:confirm-modal" - keepPopoutsOpen: true - - property string confirmTitle: "" - property string confirmMessage: "" - property string confirmButtonText: "Confirm" - property string cancelButtonText: "Cancel" - property color confirmButtonColor: Theme.primary - property var onConfirm: function () {} - property var onCancel: function () {} - property int selectedButton: -1 - property bool keyboardNavigation: false - - function show(title, message, onConfirmCallback, onCancelCallback) { - confirmTitle = title || ""; - confirmMessage = message || ""; - confirmButtonText = "Confirm"; - cancelButtonText = "Cancel"; - confirmButtonColor = Theme.primary; - onConfirm = onConfirmCallback || (() => {}); - onCancel = onCancelCallback || (() => {}); - selectedButton = -1; - keyboardNavigation = false; - open(); - } - - function showWithOptions(options) { - confirmTitle = options.title || ""; - confirmMessage = options.message || ""; - confirmButtonText = options.confirmText || "Confirm"; - cancelButtonText = options.cancelText || "Cancel"; - confirmButtonColor = options.confirmColor || Theme.primary; - onConfirm = options.onConfirm || (() => {}); - onCancel = options.onCancel || (() => {}); - selectedButton = -1; - keyboardNavigation = false; - open(); - } - - function selectButton() { - close(); - if (selectedButton === 0) { - if (onCancel) { - onCancel(); - } - } else { - if (onConfirm) { - onConfirm(); - } - } - } - - shouldBeVisible: false - allowStacking: true - modalWidth: 350 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 160 - enableShadow: true - shouldHaveFocus: true - onBackgroundClicked: { - close(); - if (onCancel) { - onCancel(); - } - } - onOpened: { - Qt.callLater(function () { - modalFocusScope.forceActiveFocus(); - modalFocusScope.focus = true; - shouldHaveFocus = true; - }); - } - modalFocusScope.Keys.onPressed: function (event) { - switch (event.key) { - case Qt.Key_Escape: - close(); - if (onCancel) { - onCancel(); - } - event.accepted = true; - break; - case Qt.Key_Left: - case Qt.Key_Up: - keyboardNavigation = true; - selectedButton = 0; - event.accepted = true; - break; - case Qt.Key_Right: - case Qt.Key_Down: - keyboardNavigation = true; - selectedButton = 1; - event.accepted = true; - break; - case Qt.Key_N: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = (selectedButton + 1) % 2; - event.accepted = true; - } - break; - case Qt.Key_P: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = selectedButton === -1 ? 1 : (selectedButton - 1 + 2) % 2; - event.accepted = true; - } - break; - case Qt.Key_J: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = 1; - event.accepted = true; - } - break; - case Qt.Key_K: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = 0; - event.accepted = true; - } - break; - case Qt.Key_H: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = 0; - event.accepted = true; - } - break; - case Qt.Key_L: - if (event.modifiers & Qt.ControlModifier) { - keyboardNavigation = true; - selectedButton = 1; - event.accepted = true; - } - break; - case Qt.Key_Tab: - keyboardNavigation = true; - selectedButton = selectedButton === -1 ? 0 : (selectedButton + 1) % 2; - event.accepted = true; - break; - case Qt.Key_Return: - case Qt.Key_Enter: - if (selectedButton !== -1) { - selectButton(); - } else { - selectedButton = 1; - selectButton(); - } - event.accepted = true; - break; - } - } - - content: Component { - Item { - anchors.fill: parent - implicitHeight: mainColumn.implicitHeight - - Column { - id: mainColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingL - anchors.rightMargin: Theme.spacingL - anchors.topMargin: Theme.spacingL - spacing: 0 - - StyledText { - text: confirmTitle - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - width: parent.width - horizontalAlignment: Text.AlignHCenter - } - - Item { - width: 1 - height: Theme.spacingL - } - - StyledText { - text: confirmMessage - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - } - - Item { - width: 1 - height: Theme.spacingL * 1.5 - } - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Rectangle { - width: 120 - height: 40 - radius: Theme.cornerRadius - color: { - if (keyboardNavigation && selectedButton === 0) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); - } else if (cancelButton.containsMouse) { - return Theme.surfacePressed; - } else { - return Theme.surfaceVariantAlpha; - } - } - border.color: (keyboardNavigation && selectedButton === 0) ? Theme.primary : "transparent" - border.width: (keyboardNavigation && selectedButton === 0) ? 1 : 0 - - StyledText { - text: cancelButtonText - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: cancelButton - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - selectedButton = 0; - selectButton(); - } - } - } - - Rectangle { - width: 120 - height: 40 - radius: Theme.cornerRadius - color: { - const baseColor = confirmButtonColor; - if (keyboardNavigation && selectedButton === 1) { - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 1); - } else if (confirmButton.containsMouse) { - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 0.9); - } else { - return baseColor; - } - } - border.color: (keyboardNavigation && selectedButton === 1) ? "white" : "transparent" - border.width: (keyboardNavigation && selectedButton === 1) ? 1 : 0 - - StyledText { - text: confirmButtonText - font.pixelSize: Theme.fontSizeMedium - color: Theme.primaryText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: confirmButton - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - selectedButton = 1; - selectButton(); - } - } - } - } - - Item { - width: 1 - height: Theme.spacingL - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml deleted file mode 100644 index cafa133..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/DankModal.qml +++ /dev/null @@ -1,496 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Wayland -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - property string layerNamespace: "dms:modal" - property alias content: contentLoader.sourceComponent - property alias contentLoader: contentLoader - property Item directContent: null - property real modalWidth: 400 - property real modalHeight: 300 - property var targetScreen - readonly property var effectiveScreen: contentWindow.screen ?? targetScreen - readonly property real screenWidth: effectiveScreen?.width ?? 1920 - readonly property real screenHeight: effectiveScreen?.height ?? 1080 - readonly property real dpr: effectiveScreen ? CompositorService.getScreenScale(effectiveScreen) : 1 - property bool showBackground: true - property real backgroundOpacity: 0.5 - property string positioning: "center" - property point customPosition: Qt.point(0, 0) - property bool closeOnEscapeKey: true - property bool closeOnBackgroundClick: true - property string animationType: "scale" - property int animationDuration: Theme.modalAnimationDuration - property real animationScaleCollapsed: 0.96 - property real animationOffset: Theme.spacingL - property list<real> animationEnterCurve: Theme.expressiveCurves.expressiveDefaultSpatial - property list<real> animationExitCurve: Theme.expressiveCurves.emphasized - property color backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - property color borderColor: Theme.outlineMedium - property real borderWidth: 0 - property real cornerRadius: Theme.cornerRadius - property bool enableShadow: true - property alias modalFocusScope: focusScope - property bool shouldBeVisible: false - property bool shouldHaveFocus: shouldBeVisible - property bool allowFocusOverride: false - property bool allowStacking: false - property bool keepContentLoaded: false - property bool keepPopoutsOpen: false - property var customKeyboardFocus: null - property bool useOverlayLayer: false - readonly property alias contentWindow: contentWindow - readonly property alias clickCatcher: clickCatcher - readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab - readonly property bool useBackground: showBackground && SettingsData.modalDarkenBackground - readonly property bool useSingleWindow: CompositorService.isHyprland || useBackground - - signal opened - signal dialogClosed - signal backgroundClicked - - property bool animationsEnabled: true - - function open() { - closeTimer.stop(); - const focusedScreen = CompositorService.getFocusedScreen(); - const screenChanged = focusedScreen && contentWindow.screen !== focusedScreen; - if (focusedScreen) { - if (screenChanged) - contentWindow.visible = false; - contentWindow.screen = focusedScreen; - if (!useSingleWindow) { - if (screenChanged) - clickCatcher.visible = false; - clickCatcher.screen = focusedScreen; - } - } - if (screenChanged) { - Qt.callLater(() => root._finishOpen()); - } else { - _finishOpen(); - } - } - - function _finishOpen() { - ModalManager.openModal(root); - shouldBeVisible = true; - if (!useSingleWindow) - clickCatcher.visible = true; - contentWindow.visible = true; - shouldHaveFocus = false; - Qt.callLater(() => shouldHaveFocus = Qt.binding(() => shouldBeVisible)); - } - - function close() { - shouldBeVisible = false; - shouldHaveFocus = false; - ModalManager.closeModal(root); - closeTimer.restart(); - } - - function instantClose() { - animationsEnabled = false; - shouldBeVisible = false; - shouldHaveFocus = false; - ModalManager.closeModal(root); - closeTimer.stop(); - contentWindow.visible = false; - if (!useSingleWindow) - clickCatcher.visible = false; - dialogClosed(); - Qt.callLater(() => animationsEnabled = true); - } - - function toggle() { - shouldBeVisible ? close() : open(); - } - - Connections { - target: ModalManager - function onCloseAllModalsExcept(excludedModal) { - if (excludedModal !== root && !allowStacking && shouldBeVisible) - close(); - } - } - - Connections { - target: Quickshell - function onScreensChanged() { - if (!contentWindow.screen) - return; - const currentScreenName = contentWindow.screen.name; - let screenStillExists = false; - for (let i = 0; i < Quickshell.screens.length; i++) { - if (Quickshell.screens[i].name === currentScreenName) { - screenStillExists = true; - break; - } - } - if (screenStillExists) - return; - const newScreen = CompositorService.getFocusedScreen(); - if (newScreen) { - contentWindow.screen = newScreen; - if (!useSingleWindow) - clickCatcher.screen = newScreen; - } - } - } - - Timer { - id: closeTimer - interval: animationDuration + 50 - onTriggered: { - if (shouldBeVisible) - return; - contentWindow.visible = false; - if (!useSingleWindow) - clickCatcher.visible = false; - dialogClosed(); - } - } - - readonly property var shadowLevel: Theme.elevationLevel3 - readonly property real shadowFallbackOffset: 6 - readonly property real shadowRenderPadding: (root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled) ? Theme.elevationRenderPadding(shadowLevel, Theme.elevationLightDirection, shadowFallbackOffset, 8, 16) : 0 - readonly property real shadowMotionPadding: animationType === "slide" ? 30 : Math.max(0, animationOffset) - readonly property real shadowBuffer: Theme.snap(shadowRenderPadding + shadowMotionPadding, dpr) - readonly property real alignedWidth: Theme.px(modalWidth, dpr) - readonly property real alignedHeight: Theme.px(modalHeight, dpr) - - readonly property real alignedX: Theme.snap((() => { - switch (positioning) { - case "center": - return (screenWidth - alignedWidth) / 2; - case "top-right": - return Math.max(Theme.spacingL, screenWidth - alignedWidth - Theme.spacingL); - case "custom": - return customPosition.x; - default: - return 0; - } - })(), dpr) - - readonly property real alignedY: Theme.snap((() => { - switch (positioning) { - case "center": - return (screenHeight - alignedHeight) / 2; - case "top-right": - return Theme.barHeight + Theme.spacingXS; - case "custom": - return customPosition.y; - default: - return 0; - } - })(), dpr) - - PanelWindow { - id: clickCatcher - visible: false - color: "transparent" - - WlrLayershell.namespace: root.layerNamespace + ":clickcatcher" - WlrLayershell.layer: WlrLayershell.Top - WlrLayershell.exclusiveZone: -1 - WlrLayershell.keyboardFocus: WlrKeyboardFocus.None - - anchors { - top: true - left: true - right: true - bottom: true - } - - mask: Region { - item: Rectangle { - x: root.alignedX - y: root.alignedY - width: root.alignedWidth - height: root.alignedHeight - } - intersection: Intersection.Xor - } - - MouseArea { - anchors.fill: parent - enabled: root.closeOnBackgroundClick && root.shouldBeVisible - onClicked: root.backgroundClicked() - } - } - - PanelWindow { - id: contentWindow - visible: false - color: "transparent" - - WindowBlur { - targetWindow: contentWindow - readonly property real s: Math.min(1, modalContainer.scaleValue) - blurX: modalContainer.x + modalContainer.width * (1 - s) * 0.5 + Theme.snap(modalContainer.animX, root.dpr) - blurY: modalContainer.y + modalContainer.height * (1 - s) * 0.5 + Theme.snap(modalContainer.animY, root.dpr) - blurWidth: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.width * s : 0 - blurHeight: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.height * s : 0 - blurRadius: root.cornerRadius - } - - WlrLayershell.namespace: root.layerNamespace - WlrLayershell.layer: { - if (root.useOverlayLayer) - return WlrLayershell.Overlay; - switch (Quickshell.env("DMS_MODAL_LAYER")) { - case "bottom": - console.error("DankModal: 'bottom' layer is not valid for modals. Defaulting to 'top' layer."); - return WlrLayershell.Top; - case "background": - console.error("DankModal: 'background' layer is not valid for modals. Defaulting to 'top' layer."); - return WlrLayershell.Top; - case "overlay": - return WlrLayershell.Overlay; - default: - return WlrLayershell.Top; - } - } - WlrLayershell.exclusiveZone: -1 - WlrLayershell.keyboardFocus: { - if (customKeyboardFocus !== null) - return customKeyboardFocus; - if (!shouldHaveFocus) - return WlrKeyboardFocus.None; - if (root.useHyprlandFocusGrab) - return WlrKeyboardFocus.OnDemand; - return WlrKeyboardFocus.Exclusive; - } - - anchors { - left: true - top: true - right: root.useSingleWindow - bottom: root.useSingleWindow - } - - WlrLayershell.margins { - left: root.useSingleWindow ? 0 : Math.max(0, Theme.snap(root.alignedX - shadowBuffer, dpr)) - top: root.useSingleWindow ? 0 : Math.max(0, Theme.snap(root.alignedY - shadowBuffer, dpr)) - right: 0 - bottom: 0 - } - - implicitWidth: root.useSingleWindow ? 0 : root.alignedWidth + (shadowBuffer * 2) - implicitHeight: root.useSingleWindow ? 0 : root.alignedHeight + (shadowBuffer * 2) - - onVisibleChanged: { - if (visible) { - opened(); - } else { - if (Qt.inputMethod) { - Qt.inputMethod.hide(); - Qt.inputMethod.reset(); - } - } - } - - MouseArea { - anchors.fill: parent - enabled: root.useSingleWindow && root.closeOnBackgroundClick && root.shouldBeVisible - z: -2 - onClicked: root.backgroundClicked() - } - - Rectangle { - anchors.fill: parent - z: -1 - color: "black" - opacity: root.useBackground ? (root.shouldBeVisible ? root.backgroundOpacity : 0) : 0 - visible: root.useBackground - - Behavior on opacity { - enabled: root.animationsEnabled - DankAnim { - duration: root.animationDuration - easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve - } - } - } - - Item { - id: modalContainer - x: root.useSingleWindow ? root.alignedX : shadowBuffer - y: root.useSingleWindow ? root.alignedY : shadowBuffer - - width: root.alignedWidth - height: root.alignedHeight - - MouseArea { - anchors.fill: parent - enabled: root.useSingleWindow && root.shouldBeVisible - hoverEnabled: false - acceptedButtons: Qt.AllButtons - onPressed: mouse.accepted = true - onClicked: mouse.accepted = true - z: -1 - } - - readonly property bool slide: root.animationType === "slide" - readonly property real offsetX: slide ? 15 : 0 - readonly property real offsetY: slide ? -30 : root.animationOffset - - property real animX: 0 - property real animY: 0 - property real scaleValue: root.animationScaleCollapsed - - onOffsetXChanged: animX = Theme.snap(root.shouldBeVisible ? 0 : offsetX, root.dpr) - onOffsetYChanged: animY = Theme.snap(root.shouldBeVisible ? 0 : offsetY, root.dpr) - - Connections { - target: root - function onShouldBeVisibleChanged() { - modalContainer.animX = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetX, root.dpr); - modalContainer.animY = Theme.snap(root.shouldBeVisible ? 0 : modalContainer.offsetY, root.dpr); - modalContainer.scaleValue = root.shouldBeVisible ? 1.0 : root.animationScaleCollapsed; - } - } - - Behavior on animX { - enabled: root.animationsEnabled - DankAnim { - duration: root.animationDuration - easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve - } - } - - Behavior on animY { - enabled: root.animationsEnabled - DankAnim { - duration: root.animationDuration - easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve - } - } - - Behavior on scaleValue { - enabled: root.animationsEnabled - DankAnim { - duration: root.animationDuration - easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve - } - } - - Item { - id: contentContainer - anchors.centerIn: parent - width: parent.width - height: parent.height - clip: false - - Item { - id: animatedContent - anchors.fill: parent - clip: false - opacity: root.shouldBeVisible ? 1 : 0 - scale: modalContainer.scaleValue - x: Theme.snap(modalContainer.animX, root.dpr) + (parent.width - width) * (1 - modalContainer.scaleValue) * 0.5 - y: Theme.snap(modalContainer.animY, root.dpr) + (parent.height - height) * (1 - modalContainer.scaleValue) * 0.5 - - Behavior on opacity { - enabled: root.animationsEnabled - NumberAnimation { - duration: animationDuration - easing.type: Easing.BezierSpline - easing.bezierCurve: root.shouldBeVisible ? root.animationEnterCurve : root.animationExitCurve - } - } - - ElevationShadow { - id: modalShadowLayer - anchors.fill: parent - level: root.shadowLevel - fallbackOffset: root.shadowFallbackOffset - targetRadius: root.cornerRadius - targetColor: root.backgroundColor - borderColor: root.borderColor - borderWidth: root.borderWidth - shadowEnabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - } - - Rectangle { - anchors.fill: parent - radius: root.cornerRadius - color: "transparent" - border.color: BlurService.borderColor - border.width: BlurService.borderWidth - z: 100 - } - - FocusScope { - anchors.fill: parent - focus: root.shouldBeVisible - clip: false - - Item { - id: directContentWrapper - anchors.fill: parent - visible: root.directContent !== null - focus: true - clip: false - - Component.onCompleted: { - if (root.directContent) { - root.directContent.parent = directContentWrapper; - root.directContent.anchors.fill = directContentWrapper; - Qt.callLater(() => root.directContent.forceActiveFocus()); - } - } - - Connections { - target: root - function onDirectContentChanged() { - if (root.directContent) { - root.directContent.parent = directContentWrapper; - root.directContent.anchors.fill = directContentWrapper; - Qt.callLater(() => root.directContent.forceActiveFocus()); - } - } - } - } - - Loader { - id: contentLoader - anchors.fill: parent - active: root.directContent === null && (root.keepContentLoaded || root.shouldBeVisible || contentWindow.visible) - asynchronous: false - focus: true - clip: false - visible: root.directContent === null - - onLoaded: { - if (item) { - Qt.callLater(() => item.forceActiveFocus()); - } - } - } - } - } - } - } - - FocusScope { - id: focusScope - objectName: "modalFocusScope" - anchors.fill: parent - visible: root.shouldBeVisible || contentWindow.visible - focus: root.shouldBeVisible - Keys.onEscapePressed: event => { - if (root.closeOnEscapeKey && shouldHaveFocus) { - root.close(); - event.accepted = true; - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml deleted file mode 100644 index c65f3e0..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Common/InputModal.qml +++ /dev/null @@ -1,312 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modals.Common -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:input-modal" - keepPopoutsOpen: true - - property string inputTitle: "" - property string inputMessage: "" - property string inputPlaceholder: "" - property string inputText: "" - property string confirmButtonText: "Confirm" - property string cancelButtonText: "Cancel" - property color confirmButtonColor: Theme.primary - property var onConfirm: function (text) {} - property var onCancel: function () {} - property int selectedButton: -1 - property bool keyboardNavigation: false - - function show(title, message, onConfirmCallback, onCancelCallback) { - inputTitle = title || ""; - inputMessage = message || ""; - inputPlaceholder = ""; - inputText = ""; - confirmButtonText = "Confirm"; - cancelButtonText = "Cancel"; - confirmButtonColor = Theme.primary; - onConfirm = onConfirmCallback || ((text) => {}); - onCancel = onCancelCallback || (() => {}); - selectedButton = -1; - keyboardNavigation = false; - open(); - } - - function showWithOptions(options) { - inputTitle = options.title || ""; - inputMessage = options.message || ""; - inputPlaceholder = options.placeholder || ""; - inputText = options.initialText || ""; - confirmButtonText = options.confirmText || "Confirm"; - cancelButtonText = options.cancelText || "Cancel"; - confirmButtonColor = options.confirmColor || Theme.primary; - onConfirm = options.onConfirm || ((text) => {}); - onCancel = options.onCancel || (() => {}); - selectedButton = -1; - keyboardNavigation = false; - open(); - } - - function confirmAndClose() { - const text = inputText; - close(); - if (onConfirm) { - onConfirm(text); - } - } - - function cancelAndClose() { - close(); - if (onCancel) { - onCancel(); - } - } - - function selectButton() { - if (selectedButton === 0) { - cancelAndClose(); - } else { - confirmAndClose(); - } - } - - shouldBeVisible: false - allowStacking: true - modalWidth: 350 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 200 - enableShadow: true - shouldHaveFocus: true - onBackgroundClicked: cancelAndClose() - onOpened: { - Qt.callLater(function () { - if (contentLoader.item && contentLoader.item.textInputRef) { - contentLoader.item.textInputRef.forceActiveFocus(); - } - }); - } - - content: Component { - FocusScope { - anchors.fill: parent - implicitHeight: mainColumn.implicitHeight - focus: true - - property alias textInputRef: textInput - - Keys.onPressed: function (event) { - const textFieldFocused = textInput.activeFocus; - - switch (event.key) { - case Qt.Key_Escape: - root.cancelAndClose(); - event.accepted = true; - break; - case Qt.Key_Tab: - if (textFieldFocused) { - root.keyboardNavigation = true; - root.selectedButton = 0; - textInput.focus = false; - } else { - root.keyboardNavigation = true; - if (root.selectedButton === -1) { - root.selectedButton = 0; - } else if (root.selectedButton === 0) { - root.selectedButton = 1; - } else { - root.selectedButton = -1; - textInput.forceActiveFocus(); - } - } - event.accepted = true; - break; - case Qt.Key_Left: - if (!textFieldFocused) { - root.keyboardNavigation = true; - root.selectedButton = 0; - event.accepted = true; - } - break; - case Qt.Key_Right: - if (!textFieldFocused) { - root.keyboardNavigation = true; - root.selectedButton = 1; - event.accepted = true; - } - break; - case Qt.Key_Return: - case Qt.Key_Enter: - if (root.selectedButton !== -1) { - root.selectButton(); - } else { - root.confirmAndClose(); - } - event.accepted = true; - break; - } - } - - Column { - id: mainColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingL - anchors.rightMargin: Theme.spacingL - anchors.topMargin: Theme.spacingL - spacing: 0 - - StyledText { - text: root.inputTitle - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - width: parent.width - horizontalAlignment: Text.AlignHCenter - } - - Item { - width: 1 - height: Theme.spacingL - } - - StyledText { - text: root.inputMessage - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - visible: root.inputMessage !== "" - } - - Item { - width: 1 - height: root.inputMessage !== "" ? Theme.spacingL : 0 - visible: root.inputMessage !== "" - } - - Rectangle { - width: parent.width - height: 40 - radius: Theme.cornerRadius - color: Theme.surfaceVariantAlpha - border.color: textInput.activeFocus ? Theme.primary : "transparent" - border.width: textInput.activeFocus ? 1 : 0 - - TextInput { - id: textInput - - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - verticalAlignment: TextInput.AlignVCenter - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - selectionColor: Theme.primary - selectedTextColor: Theme.primaryText - clip: true - text: root.inputText - onTextChanged: root.inputText = text - - StyledText { - anchors.fill: parent - verticalAlignment: Text.AlignVCenter - font.pixelSize: Theme.fontSizeMedium - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4) - text: root.inputPlaceholder - visible: textInput.text === "" && !textInput.activeFocus - } - } - } - - Item { - width: 1 - height: Theme.spacingL * 1.5 - } - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Rectangle { - width: 120 - height: 40 - radius: Theme.cornerRadius - color: { - if (root.keyboardNavigation && root.selectedButton === 0) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); - } else if (cancelButton.containsMouse) { - return Theme.surfacePressed; - } else { - return Theme.surfaceVariantAlpha; - } - } - border.color: (root.keyboardNavigation && root.selectedButton === 0) ? Theme.primary : "transparent" - border.width: (root.keyboardNavigation && root.selectedButton === 0) ? 1 : 0 - - StyledText { - text: root.cancelButtonText - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: cancelButton - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.cancelAndClose() - } - } - - Rectangle { - width: 120 - height: 40 - radius: Theme.cornerRadius - color: { - const baseColor = root.confirmButtonColor; - if (root.keyboardNavigation && root.selectedButton === 1) { - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 1); - } else if (confirmButton.containsMouse) { - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 0.9); - } else { - return baseColor; - } - } - border.color: (root.keyboardNavigation && root.selectedButton === 1) ? "white" : "transparent" - border.width: (root.keyboardNavigation && root.selectedButton === 1) ? 1 : 0 - - StyledText { - text: root.confirmButtonText - font.pixelSize: Theme.fontSizeMedium - color: Theme.primaryText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: confirmButton - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.confirmAndClose() - } - } - } - - Item { - width: 1 - height: Theme.spacingL - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml deleted file mode 100644 index 8a33878..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankColorPickerModal.qml +++ /dev/null @@ -1,771 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Hyprland -import Quickshell.Io -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:color-picker" - - HyprlandFocusGrab { - windows: [root.contentWindow] - active: root.useHyprlandFocusGrab && root.shouldHaveFocus - } - - property string pickerTitle: I18n.tr("Choose Color") - property color selectedColor: SessionData.recentColors.length > 0 ? SessionData.recentColors[0] : Theme.primary - property var onColorSelectedCallback: null - - signal colorSelected(color selectedColor) - - property color currentColor: Theme.primary - property real hue: 0 - property real saturation: 1 - property real value: 1 - property real alpha: 1 - property real gradientX: 0 - property real gradientY: 0 - - readonly property var standardColors: ["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#d32f2f", "#c2185b", "#7b1fa2", "#512da8", "#303f9f", "#1976d2", "#0288d1", "#0097a7", "#00796b", "#388e3c", "#689f38", "#afb42b", "#fbc02d", "#ffa000", "#f57c00", "#e64a19", "#c62828", "#ad1457", "#6a1b9a", "#4527a0", "#283593", "#1565c0", "#0277bd", "#00838f", "#00695c", "#2e7d32", "#558b2f", "#9e9d24", "#f9a825", "#ff8f00", "#ef6c00", "#d84315", "#ffffff", "#9e9e9e", "#212121"] - - function show() { - currentColor = selectedColor; - updateFromColor(currentColor); - open(); - } - - function hide() { - onColorSelectedCallback = null; - close(); - } - - function hideInstant() { - instantClose(); - } - - function toggle() { - if (shouldBeVisible) { - hide(); - } else { - show(); - } - } - - function toggleInstant() { - if (shouldBeVisible) { - hideInstant(); - } else { - show(); - } - } - - onColorSelected: color => { - if (onColorSelectedCallback) { - onColorSelectedCallback(color); - } - } - - function copyColorToClipboard(colorValue) { - Quickshell.execDetached(["dms", "cl", "copy", colorValue]); - ToastService.showInfo(`Color ${colorValue} copied`); - SessionData.addRecentColor(currentColor); - } - - function updateFromColor(color) { - hue = color.hsvHue; - saturation = color.hsvSaturation; - value = color.hsvValue; - alpha = color.a; - gradientX = saturation; - gradientY = 1 - value; - } - - function updateColor() { - currentColor = Qt.hsva(hue, saturation, value, alpha); - } - - function updateColorFromGradient(x, y) { - saturation = Math.max(0, Math.min(1, x)); - value = Math.max(0, Math.min(1, 1 - y)); - updateColor(); - selectedColor = currentColor; - } - - function applyPickedColor(colorStr) { - if (colorStr.length < 7 || !colorStr.startsWith('#')) - return; - const pickedColor = Qt.color(colorStr); - root.selectedColor = pickedColor; - root.currentColor = pickedColor; - root.updateFromColor(pickedColor); - copyColorToClipboard(colorStr); - root.show(); - } - - function pickColorFromScreen() { - hideInstant(); - Proc.runCommand("dms-color-pick", ["dms", "color", "pick", "--json"], (output, exitCode) => { - if (exitCode !== 0) { - console.warn("dms color pick exited with code:", exitCode); - root.show(); - return; - } - try { - const result = JSON.parse(output); - if (result.hex) { - applyPickedColor(result.hex); - } else { - console.warn("Failed to parse dms color pick output: missing hex"); - root.show(); - } - } catch (e) { - console.warn("Failed to parse dms color pick JSON:", e); - root.show(); - } - }, 0, Proc.noTimeout); - } - - modalWidth: 680 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 680 - backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - cornerRadius: Theme.cornerRadius - borderColor: Theme.outlineMedium - borderWidth: 1 - keepContentLoaded: true - allowStacking: true - - onBackgroundClicked: hide() - - IpcHandler { - function open(): string { - root.show(); - return "COLOR_PICKER_MODAL_OPEN_SUCCESS"; - } - - function openColor(color: string): string { - root.selectedColor = Qt.color(color); - root.currentColor = Qt.color(color); - root.updateFromColor(Qt.color(color)); - return open(); - } - - function close(): string { - root.hide(); - return "COLOR_PICKER_MODAL_CLOSE_SUCCESS"; - } - - function closeInstant(): string { - root.hideInstant(); - return "COLOR_PICKER_MODAL_CLOSE_INSTANT_SUCCESS"; - } - - function toggle(): string { - root.toggle(); - return "COLOR_PICKER_MODAL_TOGGLE_SUCCESS"; - } - - function toggleInstant(): string { - root.toggleInstant(); - return "COLOR_PICKER_MODAL_TOGGLE_INSTANT_SUCCESS"; - } - - target: "color-picker" - } - - content: Component { - FocusScope { - id: colorContent - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property alias hexInput: hexInput - - anchors.fill: parent - implicitHeight: mainColumn.implicitHeight - focus: true - - Keys.onEscapePressed: event => { - root.hide(); - event.accepted = true; - } - - Column { - id: mainColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - spacing: Theme.spacingM - - Row { - width: parent.width - spacing: Theme.spacingS - - Column { - width: parent.width - 90 - spacing: Theme.spacingXS - - StyledText { - text: root.pickerTitle - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.left: parent.left - } - - StyledText { - text: I18n.tr("Select a color from the palette or use custom sliders") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - anchors.left: parent.left - } - } - - DankActionButton { - iconName: "colorize" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: () => { - root.pickColorFromScreen(); - } - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: () => { - root.hide(); - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - - Rectangle { - id: gradientPicker - width: parent.width - 70 - height: 280 - radius: Theme.cornerRadius - border.color: Theme.outlineStrong - border.width: 1 - clip: true - - Rectangle { - anchors.fill: parent - color: Qt.hsva(root.hue, 1, 1, 1) - - Rectangle { - anchors.fill: parent - gradient: Gradient { - orientation: Gradient.Horizontal - GradientStop { - position: 0.0 - color: "#ffffff" - } - GradientStop { - position: 1.0 - color: "transparent" - } - } - } - - Rectangle { - anchors.fill: parent - gradient: Gradient { - orientation: Gradient.Vertical - GradientStop { - position: 0.0 - color: "transparent" - } - GradientStop { - position: 1.0 - color: "#000000" - } - } - } - } - - Rectangle { - id: pickerCircle - width: 16 - height: 16 - radius: 8 - border.color: "white" - border.width: 2 - color: "transparent" - x: root.gradientX * parent.width - width / 2 - y: root.gradientY * parent.height - height / 2 - - Rectangle { - anchors.centerIn: parent - width: parent.width - 4 - height: parent.height - 4 - radius: width / 2 - border.color: "black" - border.width: 1 - color: "transparent" - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.CrossCursor - onPressed: mouse => { - const x = Math.max(0, Math.min(1, mouse.x / width)); - const y = Math.max(0, Math.min(1, mouse.y / height)); - root.gradientX = x; - root.gradientY = y; - root.updateColorFromGradient(x, y); - } - onPositionChanged: mouse => { - if (pressed) { - const x = Math.max(0, Math.min(1, mouse.x / width)); - const y = Math.max(0, Math.min(1, mouse.y / height)); - root.gradientX = x; - root.gradientY = y; - root.updateColorFromGradient(x, y); - } - } - } - } - - Rectangle { - id: hueSlider - width: 50 - height: 280 - radius: Theme.cornerRadius - border.color: Theme.outlineStrong - border.width: 1 - - gradient: Gradient { - orientation: Gradient.Vertical - GradientStop { - position: 0.00 - color: "#ff0000" - } - GradientStop { - position: 0.17 - color: "#ffff00" - } - GradientStop { - position: 0.33 - color: "#00ff00" - } - GradientStop { - position: 0.50 - color: "#00ffff" - } - GradientStop { - position: 0.67 - color: "#0000ff" - } - GradientStop { - position: 0.83 - color: "#ff00ff" - } - GradientStop { - position: 1.00 - color: "#ff0000" - } - } - - Rectangle { - id: hueIndicator - width: parent.width - height: 4 - color: "white" - border.color: "black" - border.width: 1 - y: root.hue * parent.height - height / 2 - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.SizeVerCursor - onPressed: mouse => { - const h = Math.max(0, Math.min(1, mouse.y / height)); - root.hue = h; - root.updateColor(); - root.selectedColor = root.currentColor; - } - onPositionChanged: mouse => { - if (pressed) { - const h = Math.max(0, Math.min(1, mouse.y / height)); - root.hue = h; - root.updateColor(); - root.selectedColor = root.currentColor; - } - } - } - } - } - - Column { - width: parent.width - spacing: Theme.spacingS - - StyledText { - text: I18n.tr("Material Colors") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.left: parent.left - } - - GridView { - width: parent.width - height: 140 - cellWidth: 38 - cellHeight: 38 - clip: true - interactive: false - model: root.standardColors - - delegate: Rectangle { - width: 36 - height: 36 - color: modelData - radius: 4 - border.color: Theme.outlineStrong - border.width: 1 - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: () => { - const pickedColor = Qt.color(modelData); - root.selectedColor = pickedColor; - root.currentColor = pickedColor; - root.updateFromColor(pickedColor); - } - } - } - } - } - - Column { - width: parent.width - spacing: Theme.spacingS - - Row { - width: parent.width - spacing: Theme.spacingS - - Column { - width: 210 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Recent Colors") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.left: parent.left - } - - Row { - width: parent.width - spacing: Theme.spacingXS - - Repeater { - model: 5 - - Rectangle { - width: 36 - height: 36 - radius: 4 - border.color: Theme.outlineStrong - border.width: 1 - - color: { - if (index < SessionData.recentColors.length) { - return SessionData.recentColors[index]; - } - return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency); - } - - opacity: index < SessionData.recentColors.length ? 1.0 : 0.3 - - MouseArea { - anchors.fill: parent - cursorShape: index < SessionData.recentColors.length ? Qt.PointingHandCursor : Qt.ArrowCursor - enabled: index < SessionData.recentColors.length - onClicked: () => { - if (index < SessionData.recentColors.length) { - const pickedColor = SessionData.recentColors[index]; - root.selectedColor = pickedColor; - root.currentColor = pickedColor; - root.updateFromColor(pickedColor); - } - } - } - } - } - } - } - - Column { - width: parent.width - 330 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Opacity") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.left: parent.left - } - - DankSlider { - width: parent.width - value: Math.round(root.alpha * 100) - minimum: 0 - maximum: 100 - showValue: false - onSliderValueChanged: newValue => { - root.alpha = newValue / 100; - root.updateColor(); - root.selectedColor = root.currentColor; - } - } - } - - Rectangle { - width: 100 - height: 50 - radius: Theme.cornerRadius - color: root.currentColor - border.color: Theme.outlineStrong - border.width: 2 - anchors.verticalCenter: parent.verticalCenter - } - } - } - - Column { - width: parent.width - spacing: Theme.spacingS - - Row { - width: parent.width - spacing: Theme.spacingM - - Column { - width: (parent.width - Theme.spacingM * 2) / 3 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Hex") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - anchors.left: parent.left - } - - Row { - width: parent.width - spacing: Theme.spacingXS - - DankTextField { - id: hexInput - width: parent.width - 36 - height: 36 - text: root.currentColor.toString() - font.pixelSize: Theme.fontSizeMedium - textColor: { - if (text.length === 0) - return Theme.surfaceText; - const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/; - return hexPattern.test(text) ? Theme.surfaceText : Theme.error; - } - placeholderText: "#000000" - backgroundColor: Theme.surfaceHover - borderWidth: 1 - focusedBorderWidth: 2 - topPadding: Theme.spacingS - bottomPadding: Theme.spacingS - onAccepted: () => { - const hexPattern = /^#?[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/; - if (!hexPattern.test(text)) - return; - const color = Qt.color(text); - if (color) { - root.selectedColor = color; - root.currentColor = color; - root.updateFromColor(color); - } - } - } - - DankActionButton { - iconName: "content_copy" - iconSize: Theme.iconSize - 6 - iconColor: Theme.surfaceText - buttonSize: 36 - anchors.verticalCenter: parent.verticalCenter - onClicked: () => { - root.copyColorToClipboard(hexInput.text); - } - } - } - } - - Column { - width: (parent.width - Theme.spacingM * 2) / 3 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("RGB") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - anchors.left: parent.left - } - - Row { - width: parent.width - spacing: Theme.spacingXS - - Rectangle { - width: parent.width - 36 - height: 36 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: Theme.outline - border.width: 1 - - StyledText { - anchors.centerIn: parent - text: { - const r = Math.round(root.currentColor.r * 255); - const g = Math.round(root.currentColor.g * 255); - const b = Math.round(root.currentColor.b * 255); - if (root.alpha < 1) { - const a = Math.round(root.alpha * 255); - return `${r}, ${g}, ${b}, ${a}`; - } - return `${r}, ${g}, ${b}`; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - } - } - - DankActionButton { - iconName: "content_copy" - iconSize: Theme.iconSize - 6 - iconColor: Theme.surfaceText - buttonSize: 36 - anchors.verticalCenter: parent.verticalCenter - onClicked: () => { - const r = Math.round(root.currentColor.r * 255); - const g = Math.round(root.currentColor.g * 255); - const b = Math.round(root.currentColor.b * 255); - let rgbString; - if (root.alpha < 1) { - const a = Math.round(root.alpha * 255); - rgbString = `rgba(${r}, ${g}, ${b}, ${a})`; - } else { - rgbString = `rgb(${r}, ${g}, ${b})`; - } - Quickshell.execDetached(["dms", "cl", "copy", rgbString]); - ToastService.showInfo(`${rgbString} copied`); - } - } - } - } - - Column { - width: (parent.width - Theme.spacingM * 2) / 3 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("HSV") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - anchors.left: parent.left - } - - Row { - width: parent.width - spacing: Theme.spacingXS - - Rectangle { - width: parent.width - 36 - height: 36 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: Theme.outline - border.width: 1 - - StyledText { - anchors.centerIn: parent - text: { - const h = Math.round(root.hue * 360); - const s = Math.round(root.saturation * 100); - const v = Math.round(root.value * 100); - if (root.alpha < 1) { - const a = Math.round(root.alpha * 100); - return `${h}°, ${s}%, ${v}%, ${a}%`; - } - return `${h}°, ${s}%, ${v}%`; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - } - } - - DankActionButton { - iconName: "content_copy" - iconSize: Theme.iconSize - 6 - iconColor: Theme.surfaceText - buttonSize: 36 - anchors.verticalCenter: parent.verticalCenter - onClicked: () => { - const h = Math.round(root.hue * 360); - const s = Math.round(root.saturation * 100); - const v = Math.round(root.value * 100); - let hsvString; - if (root.alpha < 1) { - const a = Math.round(root.alpha * 100); - hsvString = `${h}, ${s}, ${v}, ${a}`; - } else { - hsvString = `${h}, ${s}, ${v}`; - } - Quickshell.execDetached(["dms", "cl", "copy", hsvString]); - ToastService.showInfo(`HSV ${hsvString} copied`); - } - } - } - } - } - - DankButton { - visible: root.onColorSelectedCallback !== null && root.onColorSelectedCallback !== undefined - width: 70 - buttonHeight: 36 - text: I18n.tr("Save") - backgroundColor: Theme.primary - textColor: Theme.background - anchors.right: parent.right - onClicked: { - SessionData.addRecentColor(root.currentColor); - root.colorSelected(root.currentColor); - root.hide(); - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml deleted file mode 100644 index 31ada32..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ActionPanel.qml +++ /dev/null @@ -1,256 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - property var selectedItem: null - property var controller: null - property bool expanded: false - property int selectedActionIndex: 0 - - function getPluginContextMenuActions() { - if (selectedItem?.type !== "plugin" || !selectedItem?.pluginId) - return []; - var instance = PluginService.pluginInstances[selectedItem.pluginId]; - if (!instance) - return []; - if (typeof instance.getContextMenuActions !== "function") - return []; - var actions = instance.getContextMenuActions(selectedItem.data); - if (!Array.isArray(actions)) - return []; - return actions; - } - - readonly property var actions: { - var result = []; - if (selectedItem?.primaryAction) { - result.push(selectedItem.primaryAction); - } - - switch (selectedItem?.type) { - case "plugin": - var pluginActions = getPluginContextMenuActions(); - for (var i = 0; i < pluginActions.length; i++) { - var act = pluginActions[i]; - result.push({ - name: act.text || act.name || "", - icon: act.icon || "play_arrow", - action: "plugin_action", - pluginAction: act.action - }); - } - break; - case "plugin_browse": - if (selectedItem?.actions) { - for (var i = 0; i < selectedItem.actions.length; i++) { - result.push(selectedItem.actions[i]); - } - } - break; - case "app": - if (selectedItem?.isCore) - break; - if (SessionService.nvidiaCommand) { - result.push({ - name: I18n.tr("Launch on dGPU"), - icon: "memory", - action: "launch_dgpu" - }); - } - if (selectedItem?.actions) { - for (var i = 0; i < selectedItem.actions.length; i++) { - result.push(selectedItem.actions[i]); - } - } - break; - } - return result; - } - - readonly property bool hasActions: { - switch (selectedItem?.type) { - case "app": - return !selectedItem?.isCore; - case "plugin": - return getPluginContextMenuActions().length > 0; - case "plugin_browse": - return selectedItem?.actions?.length > 0; - default: - return actions.length > 1; - } - } - - width: parent?.width ?? 200 - height: expanded && hasActions ? 52 : 0 - color: Theme.surfaceContainerHigh - radius: Theme.cornerRadius - - clip: true - - Behavior on height { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - Rectangle { - anchors.top: parent.top - width: parent.width - height: 1 - color: Theme.outlineMedium - } - - Item { - anchors.fill: parent - anchors.margins: Theme.spacingS - - Flickable { - id: actionsFlickable - anchors.left: parent.left - anchors.right: tabHint.left - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - height: parent.height - contentWidth: actionsRow.width - contentHeight: height - clip: true - boundsBehavior: Flickable.StopAtBounds - flickableDirection: Flickable.HorizontalFlick - - Row { - id: actionsRow - height: parent.height - spacing: Theme.spacingS - - Repeater { - model: root.actions - - Rectangle { - id: actionButton - - required property var modelData - required property int index - - width: actionContent.implicitWidth + Theme.spacingM * 2 - height: actionsRow.height - radius: Theme.cornerRadius - color: index === root.selectedActionIndex ? Theme.primaryHover : actionArea.containsMouse ? Theme.surfaceHover : "transparent" - - Row { - id: actionContent - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: actionButton.modelData?.icon ?? "play_arrow" - size: 16 - color: actionButton.index === root.selectedActionIndex ? Theme.primary : Theme.surfaceText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: actionButton.modelData?.name ?? "" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: actionButton.index === root.selectedActionIndex ? Theme.primary : Theme.surfaceText - } - } - - MouseArea { - id: actionArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (root.controller && root.selectedItem) { - root.controller.executeAction(root.selectedItem, actionButton.modelData); - } - } - onEntered: root.selectedActionIndex = actionButton.index - } - } - } - } - } - - StyledText { - id: tabHint - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - visible: root.hasActions - text: "Tab" - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.outlineButton - } - } - - function toggle() { - expanded = !expanded; - selectedActionIndex = 0; - } - - function show() { - expanded = true; - selectedActionIndex = actions.length > 1 ? 1 : 0; - } - - function hide() { - expanded = false; - selectedActionIndex = 0; - } - - function cycleAction(reverse = false) { - if (actions.length > 0) { - if (! reverse) - selectedActionIndex = (selectedActionIndex + 1) % actions.length; - else - selectedActionIndex = (selectedActionIndex - 1) % actions.length; - ensureSelectedVisible(); - } - } - - function ensureSelectedVisible() { - if (selectedActionIndex < 0 || !actionsRow.children || selectedActionIndex >= actionsRow.children.length) - return; - var buttonX = 0; - for (var i = 0; i < selectedActionIndex; i++) { - var child = actionsRow.children[i]; - if (child) - buttonX += child.width + actionsRow.spacing; - } - - var button = actionsRow.children[selectedActionIndex]; - if (!button) - return; - var buttonRight = buttonX + button.width; - var viewLeft = actionsFlickable.contentX; - var viewRight = viewLeft + actionsFlickable.width; - - if (buttonX < viewLeft) { - actionsFlickable.contentX = Math.max(0, buttonX - Theme.spacingS); - } else if (buttonRight > viewRight) { - actionsFlickable.contentX = Math.min(actionsFlickable.contentWidth - actionsFlickable.width, buttonRight - actionsFlickable.width + Theme.spacingS); - } - } - - function executeSelectedAction() { - if (!controller || !selectedItem || selectedActionIndex >= actions.length) - return; - var action = actions[selectedActionIndex]; - if (action.action === "plugin_action" && typeof action.pluginAction === "function") { - action.pluginAction(); - controller.performSearch(); - controller.itemExecuted(); - } else { - controller.executeAction(selectedItem, action); - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml deleted file mode 100644 index 67cb606..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Controller.qml +++ /dev/null @@ -1,1894 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Common -import qs.Services -import "Scorer.js" as Scorer -import "ControllerUtils.js" as Utils -import "NavigationHelpers.js" as Nav -import "ItemTransformers.js" as Transform - -Item { - id: root - - property string searchQuery: "" - property string searchMode: "all" - property string previousSearchMode: "all" - property bool autoSwitchedToFiles: false - property bool isFileSearching: false - property var sections: [] - property var flatModel: [] - property int selectedFlatIndex: 0 - property var selectedItem: null - property bool isSearching: false - property string activePluginId: "" - property var collapsedSections: ({}) - property bool keyboardNavigationActive: false - property bool active: false - property var _modeSectionsCache: ({}) - property bool _queryDrivenSearch: false - property bool _diskCacheConsumed: false - property var sectionViewModes: ({}) - property var pluginViewPreferences: ({}) - property int gridColumns: SettingsData.appLauncherGridColumns - property int viewModeVersion: 0 - property string viewModeContext: "spotlight" - - signal itemExecuted - signal searchCompleted - signal modeChanged(string mode) - signal queryChanged(string query) - signal viewModeChanged(string sectionId, string mode) - signal searchQueryRequested(string query) - - onActiveChanged: { - if (!active) { - SessionData.addLauncherHistory(searchQuery); - - sections = []; - flatModel = []; - selectedItem = null; - _clearModeCache(); - } - } - - onSearchModeChanged: { - if (searchMode === "apps") { - _loadAppCategories(); - } else { - appCategory = ""; - appCategories = []; - } - } - - Connections { - target: SettingsData - function onSortAppsAlphabeticallyChanged() { - AppSearchService.invalidateLauncherCache(); - _clearModeCache(); - } - } - - Connections { - target: AppSearchService - function onCacheVersionChanged() { - if (!active) - return; - _clearModeCache(); - if (searchMode === "apps") { - _loadAppCategories(); - performSearch(); - } else if (!searchQuery && searchMode === "all") { - performSearch(); - } - } - } - - Connections { - target: PluginService - function onRequestLauncherUpdate(pluginId) { - if (!active) - return; - if (activePluginId === pluginId) { - if (activePluginCategories.length <= 1) - loadPluginCategories(pluginId); - performSearch(); - return; - } - if (searchQuery) - performSearch(); - } - } - - Process { - id: wtypeProcess - command: ["wtype", "-M", "ctrl", "-P", "v", "-p", "v", "-m", "ctrl"] - running: false - } - - Process { - id: copyProcess - running: false - onExited: pasteTimer.start() - } - - Timer { - id: pasteTimer - interval: 200 - repeat: false - onTriggered: wtypeProcess.running = true - } - - function pasteSelected() { - if (!selectedItem) - return; - if (!SessionService.wtypeAvailable) { - ToastService.showError("wtype not available - install wtype for paste support"); - return; - } - - const pluginId = selectedItem.pluginId; - if (!pluginId) - return; - const pasteArgs = AppSearchService.getPluginPasteArgs(pluginId, selectedItem.data); - if (!pasteArgs) - return; - copyProcess.command = pasteArgs; - copyProcess.running = true; - itemExecuted(); - } - - readonly property var sectionDefinitions: [ - { - id: "favorites", - title: I18n.tr("Pinned"), - icon: "push_pin", - priority: 1, - defaultViewMode: "list" - }, - { - id: "apps", - title: I18n.tr("Applications"), - icon: "apps", - priority: 2, - defaultViewMode: "list" - }, - { - id: "browse_plugins", - title: I18n.tr("Browse"), - icon: "category", - priority: 2.5, - defaultViewMode: "grid" - }, - { - id: "files", - title: I18n.tr("Files"), - icon: "folder", - priority: 4, - defaultViewMode: "list" - }, - { - id: "fallback", - title: I18n.tr("Commands"), - icon: "terminal", - priority: 5, - defaultViewMode: "list" - } - ] - - property int historyIndex: -1 - property string typingBackup: "" - - function navigateHistory(direction) { - let history = SessionData.launcherQueryHistory; - if (history.length === 0) - return; - - if (historyIndex === -1) - typingBackup = searchQuery; - - let nextIndex = historyIndex + (direction === "up" ? 1 : -1); - if (nextIndex >= history.length) - nextIndex = history.length - 1; - if (nextIndex < -1) - nextIndex = -1; - - if (nextIndex === historyIndex) - return; - historyIndex = nextIndex; - - let targetText = (historyIndex === -1) ? typingBackup : history[historyIndex]; - - setSearchQuery(targetText); - searchQueryRequested(targetText); - } - - property string fileSearchType: "all" - property string fileSearchExt: "" - property string fileSearchFolder: "" - property string fileSearchSort: "score" - - property string pluginFilter: "" - property string activePluginName: "" - property var activePluginCategories: [] - property string activePluginCategory: "" - property string appCategory: "" - property var appCategories: [] - - function getSectionViewMode(sectionId) { - if (sectionId === "browse_plugins") - return "list"; - if (pluginViewPreferences[sectionId]?.enforced) - return pluginViewPreferences[sectionId].mode; - if (sectionViewModes[sectionId]) - return sectionViewModes[sectionId]; - - var savedModes = viewModeContext === "appDrawer" ? (SettingsData.appDrawerSectionViewModes || {}) : (SettingsData.spotlightSectionViewModes || {}); - if (savedModes[sectionId]) - return savedModes[sectionId]; - - for (var i = 0; i < sectionDefinitions.length; i++) { - if (sectionDefinitions[i].id === sectionId) - return sectionDefinitions[i].defaultViewMode || "list"; - } - - if (pluginViewPreferences[sectionId]?.mode) - return pluginViewPreferences[sectionId].mode; - - return "list"; - } - - function setSectionViewMode(sectionId, mode) { - if (sectionId === "browse_plugins") - return; - if (pluginViewPreferences[sectionId]?.enforced) - return; - sectionViewModes = Object.assign({}, sectionViewModes, { - [sectionId]: mode - }); - viewModeVersion++; - if (viewModeContext === "appDrawer") { - var savedModes = Object.assign({}, SettingsData.appDrawerSectionViewModes || {}, { - [sectionId]: mode - }); - SettingsData.appDrawerSectionViewModes = savedModes; - } else { - var savedModes = Object.assign({}, SettingsData.spotlightSectionViewModes || {}, { - [sectionId]: mode - }); - SettingsData.spotlightSectionViewModes = savedModes; - } - viewModeChanged(sectionId, mode); - } - - function canChangeSectionViewMode(sectionId) { - if (sectionId === "browse_plugins") - return false; - return !pluginViewPreferences[sectionId]?.enforced; - } - - function canCollapseSection(sectionId) { - return searchMode === "all"; - } - - function setPluginViewPreference(pluginId, mode, enforced) { - var prefs = Object.assign({}, pluginViewPreferences); - prefs[pluginId] = { - mode: mode, - enforced: enforced || false - }; - pluginViewPreferences = prefs; - } - - function applyActivePluginViewPreference(pluginId, isBuiltIn) { - var sectionId = "plugin_" + pluginId; - var pref = null; - if (isBuiltIn) { - var builtIn = AppSearchService.builtInPlugins[pluginId]; - if (builtIn && builtIn.viewMode) { - pref = { - mode: builtIn.viewMode, - enforced: builtIn.viewModeEnforced === true - }; - } - } else { - pref = PluginService.getPluginViewPreference(pluginId); - } - - if (pref && pref.mode) { - setPluginViewPreference(sectionId, pref.mode, pref.enforced); - } else { - var prefs = Object.assign({}, pluginViewPreferences); - delete prefs[sectionId]; - pluginViewPreferences = prefs; - } - } - - function clearActivePluginViewPreference() { - var prefs = {}; - for (var key in pluginViewPreferences) { - if (!key.startsWith("plugin_")) { - prefs[key] = pluginViewPreferences[key]; - } - } - pluginViewPreferences = prefs; - } - - property int _searchVersion: 0 - property bool _pluginPhasePending: false - property bool _pluginPhaseForceFirst: false - property var _phase1Items: [] - - Timer { - id: searchDebounce - interval: 60 - onTriggered: root.performSearch() - } - - Timer { - id: pluginPhaseTimer - interval: 1 - onTriggered: root._performPluginPhase() - } - - Timer { - id: fileSearchDebounce - interval: 200 - onTriggered: root.performFileSearch() - } - - function getOrTransformApp(app) { - return AppSearchService.getOrTransformApp(app, transformApp); - } - - function setSearchQuery(query) { - _searchVersion++; - _queryDrivenSearch = true; - _pluginPhasePending = false; - _phase1Items = []; - pluginPhaseTimer.stop(); - searchQuery = query; - searchDebounce.restart(); - - var filesInAll = searchMode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll); - if (searchMode !== "plugins" && (searchMode === "files" || query.startsWith("/") || filesInAll) && query.length > 0) { - fileSearchDebounce.restart(); - } - } - - function setMode(mode, isAutoSwitch) { - if (searchMode === mode) - return; - if (isAutoSwitch) { - previousSearchMode = searchMode; - autoSwitchedToFiles = true; - } else { - autoSwitchedToFiles = false; - } - searchMode = mode; - modeChanged(mode); - performSearch(); - var filesInAll = mode === "all" && (SettingsData.dankLauncherV2IncludeFilesInAll || SettingsData.dankLauncherV2IncludeFoldersInAll) && searchQuery.length > 0; - if (mode === "files" || filesInAll) { - fileSearchDebounce.restart(); - } - } - - function restorePreviousMode() { - if (!autoSwitchedToFiles) - return; - autoSwitchedToFiles = false; - searchMode = previousSearchMode; - modeChanged(previousSearchMode); - performSearch(); - } - - function cycleMode(reverse = false) { - var modes = ["all", "apps", "files", "plugins"]; - var currentIndex = modes.indexOf(searchMode); - if (!reverse) - var nextIndex = (currentIndex + 1) % modes.length; - else - var nextIndex = (currentIndex - 1 + modes.length) % modes.length; - setMode(modes[nextIndex]); - } - - function reset() { - searchQuery = ""; - searchMode = "all"; - previousSearchMode = "all"; - autoSwitchedToFiles = false; - isFileSearching = false; - fileSearchType = "all"; - fileSearchExt = ""; - fileSearchFolder = ""; - fileSearchSort = "score"; - sections = []; - flatModel = []; - selectedFlatIndex = 0; - selectedItem = null; - isSearching = false; - activePluginId = ""; - activePluginName = ""; - activePluginCategories = []; - activePluginCategory = ""; - appCategory = ""; - appCategories = []; - pluginFilter = ""; - collapsedSections = {}; - _clearModeCache(); - _queryDrivenSearch = false; - _pluginPhasePending = false; - _pluginPhaseForceFirst = false; - _phase1Items = []; - pluginPhaseTimer.stop(); - } - - function loadPluginCategories(pluginId) { - if (!pluginId) { - if (activePluginCategories.length > 0) { - activePluginCategories = []; - activePluginCategory = ""; - } - return; - } - - const categories = AppSearchService.getPluginLauncherCategories(pluginId); - if (categories.length === activePluginCategories.length) { - let same = true; - for (let i = 0; i < categories.length; i++) { - if (categories[i].id !== activePluginCategories[i]?.id) { - same = false; - break; - } - } - if (same) - return; - } - activePluginCategories = categories; - activePluginCategory = ""; - AppSearchService.setPluginLauncherCategory(pluginId, ""); - } - - function setActivePluginCategory(categoryId) { - if (activePluginCategory === categoryId) - return; - activePluginCategory = categoryId; - AppSearchService.setPluginLauncherCategory(activePluginId, categoryId); - performSearch(); - } - - function setAppCategory(category) { - if (appCategory === category) - return; - appCategory = category; - _queryDrivenSearch = true; - _clearModeCache(); - performSearch(); - } - - function _loadAppCategories() { - appCategories = AppSearchService.getAllCategories(); - } - - function setFileSearchType(type) { - if (fileSearchType === type) - return; - fileSearchType = type; - performFileSearch(); - } - - function setFileSearchExt(ext) { - if (fileSearchExt === ext) - return; - fileSearchExt = ext; - performFileSearch(); - } - - function setFileSearchFolder(folder) { - if (fileSearchFolder === folder) - return; - fileSearchFolder = folder; - performFileSearch(); - } - - function setFileSearchSort(sort) { - if (fileSearchSort === sort) - return; - fileSearchSort = sort; - performFileSearch(); - } - - function clearPluginFilter() { - if (pluginFilter) { - pluginFilter = ""; - performSearch(); - return true; - } - return false; - } - - function preserveSelectionAfterUpdate(forceFirst) { - if (forceFirst) - return function () { - return getFirstItemIndex(); - }; - var previousSelectedId = selectedItem?.id || ""; - return function (newFlatModel) { - if (!previousSelectedId) - return getFirstItemIndex(); - for (var i = 0; i < newFlatModel.length; i++) { - if (!newFlatModel[i].isHeader && newFlatModel[i].item?.id === previousSelectedId) - return i; - } - return getFirstItemIndex(); - }; - } - - function performSearch() { - queryChanged(searchQuery); - - var currentVersion = _searchVersion; - isSearching = true; - var shouldResetSelection = _queryDrivenSearch; - _queryDrivenSearch = false; - var restoreSelection = preserveSelectionAfterUpdate(shouldResetSelection); - - var cachedSections = AppSearchService.getCachedDefaultSections(); - if (!cachedSections && !_diskCacheConsumed && !searchQuery && searchMode === "all" && !pluginFilter) { - _diskCacheConsumed = true; - var diskSections = _loadDiskCache(); - if (diskSections) { - activePluginId = ""; - activePluginName = ""; - activePluginCategories = []; - activePluginCategory = ""; - clearActivePluginViewPreference(); - for (var i = 0; i < diskSections.length; i++) { - if (collapsedSections[diskSections[i].id] !== undefined) - diskSections[i].collapsed = collapsedSections[diskSections[i].id]; - } - _applyHighlights(diskSections, ""); - flatModel = Scorer.flattenSections(diskSections); - sections = diskSections; - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - isSearching = false; - searchCompleted(); - return; - } - } - - if (cachedSections && !searchQuery && searchMode === "all" && !pluginFilter) { - activePluginId = ""; - activePluginName = ""; - activePluginCategories = []; - activePluginCategory = ""; - clearActivePluginViewPreference(); - var modeCache = _getCachedModeData("all"); - if (modeCache) { - _applyHighlights(modeCache.sections, ""); - sections = modeCache.sections; - flatModel = modeCache.flatModel; - } else { - var newSections = cachedSections.map(function (s) { - var copy = Object.assign({}, s, { - items: s.items ? s.items.slice() : [] - }); - if (collapsedSections[s.id] !== undefined) - copy.collapsed = collapsedSections[s.id]; - return copy; - }); - _applyHighlights(newSections, ""); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - _setCachedModeData("all", sections, flatModel); - } - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - isSearching = false; - searchCompleted(); - return; - } - - var allItems = []; - - var triggerMatch = detectTrigger(searchQuery); - if (triggerMatch.pluginId) { - var pluginChanged = activePluginId !== triggerMatch.pluginId; - activePluginId = triggerMatch.pluginId; - activePluginName = getPluginName(triggerMatch.pluginId, triggerMatch.isBuiltIn); - applyActivePluginViewPreference(triggerMatch.pluginId, triggerMatch.isBuiltIn); - - if (pluginChanged && !triggerMatch.isBuiltIn) - loadPluginCategories(triggerMatch.pluginId); - - var pluginItems = getPluginItems(triggerMatch.pluginId, triggerMatch.query); - for (var k = 0; k < pluginItems.length; k++) - allItems.push(pluginItems[k]); - - if (triggerMatch.isBuiltIn) { - var builtInItems = AppSearchService.getBuiltInLauncherItems(triggerMatch.pluginId, triggerMatch.query); - for (var j = 0; j < builtInItems.length; j++) { - allItems.push(transformBuiltInLauncherItem(builtInItems[j], triggerMatch.pluginId)); - } - } - - var dynamicDefs = buildDynamicSectionDefs(allItems); - var scoredItems = Scorer.scoreItems(allItems, triggerMatch.query, getFrecencyForItem); - var sortAlpha = !triggerMatch.query && SettingsData.sortAppsAlphabetically; - var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, 500); - - for (var sid in collapsedSections) { - for (var i = 0; i < newSections.length; i++) { - if (newSections[i].id === sid) { - newSections[i].collapsed = collapsedSections[sid]; - } - } - } - - _applyHighlights(newSections, triggerMatch.query); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - - isSearching = false; - searchCompleted(); - return; - } - - activePluginId = ""; - activePluginName = ""; - activePluginCategories = []; - activePluginCategory = ""; - clearActivePluginViewPreference(); - - if (searchMode === "files") { - var fileQuery = searchQuery.startsWith("/") ? searchQuery.substring(1).trim() : searchQuery.trim(); - isFileSearching = fileQuery.length >= 2 && DSearchService.dsearchAvailable; - sections = []; - flatModel = []; - selectedFlatIndex = 0; - selectedItem = null; - isSearching = false; - searchCompleted(); - return; - } - - if (searchMode === "apps") { - var isCategoryFiltered = appCategory && appCategory !== I18n.tr("All"); - var cachedSections = AppSearchService.getCachedDefaultSections(); - if (cachedSections && !searchQuery && !isCategoryFiltered) { - var modeCache = _getCachedModeData("apps"); - if (modeCache) { - _applyHighlights(modeCache.sections, ""); - sections = modeCache.sections; - flatModel = modeCache.flatModel; - } else { - var appSectionIds = ["favorites", "apps"]; - var newSections = cachedSections.filter(function (s) { - return appSectionIds.indexOf(s.id) !== -1; - }).map(function (s) { - var copy = Object.assign({}, s, { - items: s.items ? s.items.slice() : [] - }); - if (collapsedSections[s.id] !== undefined) - copy.collapsed = collapsedSections[s.id]; - return copy; - }); - _applyHighlights(newSections, ""); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - _setCachedModeData("apps", sections, flatModel); - } - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - isSearching = false; - searchCompleted(); - return; - } - - if (isCategoryFiltered) { - var rawApps = AppSearchService.getAppsInCategory(appCategory); - for (var i = 0; i < rawApps.length; i++) { - allItems.push(getOrTransformApp(rawApps[i])); - } - // Also include core apps (DMS Settings etc.) that match this category - var allCoreApps = AppSearchService.getCoreApps(""); - for (var i = 0; i < allCoreApps.length; i++) { - var coreAppCats = AppSearchService.getCategoriesForApp(allCoreApps[i]); - if (coreAppCats.indexOf(appCategory) !== -1) - allItems.push(transformCoreApp(allCoreApps[i])); - } - } else { - var apps = searchApps(searchQuery); - for (var i = 0; i < apps.length; i++) { - allItems.push(apps[i]); - } - } - - var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem); - var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically; - var newSections = Scorer.groupBySection(scoredItems, sectionDefinitions, sortAlpha, searchQuery ? 50 : 500); - - for (var sid in collapsedSections) { - for (var i = 0; i < newSections.length; i++) { - if (newSections[i].id === sid) { - newSections[i].collapsed = collapsedSections[sid]; - } - } - } - - _applyHighlights(newSections, searchQuery); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - - isSearching = false; - searchCompleted(); - return; - } - - if (searchMode === "plugins") { - if (!searchQuery && !pluginFilter) { - var browseItems = getPluginBrowseItems(); - for (var k = 0; k < browseItems.length; k++) - allItems.push(browseItems[k]); - } else if (pluginFilter) { - var isBuiltInFilter = !!AppSearchService.builtInPlugins[pluginFilter]; - applyActivePluginViewPreference(pluginFilter, isBuiltInFilter); - - var filterItems = getPluginItems(pluginFilter, searchQuery); - for (var k = 0; k < filterItems.length; k++) - allItems.push(filterItems[k]); - - var builtInItems = AppSearchService.getBuiltInLauncherItems(pluginFilter, searchQuery); - for (var j = 0; j < builtInItems.length; j++) { - allItems.push(transformBuiltInLauncherItem(builtInItems[j], pluginFilter)); - } - } else { - var emptyTriggerPlugins = getEmptyTriggerPlugins(); - for (var i = 0; i < emptyTriggerPlugins.length; i++) { - var pluginId = emptyTriggerPlugins[i]; - var pItems = getPluginItems(pluginId, searchQuery); - for (var k = 0; k < pItems.length; k++) - allItems.push(pItems[k]); - } - - var builtInLauncherPlugins = getBuiltInEmptyTriggerLaunchers(); - for (var i = 0; i < builtInLauncherPlugins.length; i++) { - var pluginId = builtInLauncherPlugins[i]; - var blItems = AppSearchService.getBuiltInLauncherItems(pluginId, searchQuery); - for (var j = 0; j < blItems.length; j++) { - allItems.push(transformBuiltInLauncherItem(blItems[j], pluginId)); - } - } - } - - var dynamicDefs = buildDynamicSectionDefs(allItems); - var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem); - var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically; - var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, 500); - - for (var sid in collapsedSections) { - for (var i = 0; i < newSections.length; i++) { - if (newSections[i].id === sid) { - newSections[i].collapsed = collapsedSections[sid]; - } - } - } - - _applyHighlights(newSections, searchQuery); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - - isSearching = false; - searchCompleted(); - return; - } - - var apps = searchApps(searchQuery); - for (var i = 0; i < apps.length; i++) { - allItems.push(apps[i]); - } - - if (searchMode === "all") { - if (searchQuery && searchQuery.length >= 2) { - _pluginPhasePending = true; - _phase1Items = allItems.slice(); - _pluginPhaseForceFirst = shouldResetSelection; - pluginPhaseTimer.restart(); - isSearching = true; - searchCompleted(); - return; - } else if (!searchQuery) { - var emptyTriggerOrdered = getEmptyTriggerPluginsOrdered(); - for (var i = 0; i < emptyTriggerOrdered.length; i++) { - var plugin = emptyTriggerOrdered[i]; - if (plugin.isBuiltIn) { - var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery); - for (var j = 0; j < blItems.length; j++) - allItems.push(transformBuiltInLauncherItem(blItems[j], plugin.id)); - } else { - var pItems = getPluginItems(plugin.id, searchQuery); - for (var j = 0; j < pItems.length; j++) - allItems.push(pItems[j]); - } - } - - var browseItems = getPluginBrowseItems(); - for (var i = 0; i < browseItems.length; i++) - allItems.push(browseItems[i]); - } - } - - var dynamicDefs = buildDynamicSectionDefs(allItems); - - if (currentVersion !== _searchVersion) { - isSearching = false; - return; - } - - var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem); - var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically; - var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, searchQuery ? 50 : 500); - - if (currentVersion !== _searchVersion) { - isSearching = false; - return; - } - - for (var i = 0; i < newSections.length; i++) { - var sid = newSections[i].id; - if (collapsedSections[sid] !== undefined) { - newSections[i].collapsed = collapsedSections[sid]; - } - } - - _applyHighlights(newSections, searchQuery); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - - if (!AppSearchService.isCacheValid() && !searchQuery && searchMode === "all" && !pluginFilter) { - AppSearchService.setCachedDefaultSections(sections, flatModel); - _saveDiskCache(sections); - } - - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - - isSearching = _pluginPhasePending; - searchCompleted(); - } - - function _performPluginPhase() { - _pluginPhasePending = false; - if (!searchQuery || searchQuery.length < 2 || searchMode !== "all") - return; - - var currentVersion = _searchVersion; - var restoreSelection = preserveSelectionAfterUpdate(_pluginPhaseForceFirst); - var allItems = _phase1Items; - _phase1Items = []; - - var allPluginsOrdered = getAllVisiblePluginsOrdered(); - var maxPerPlugin = 10; - for (var i = 0; i < allPluginsOrdered.length; i++) { - if (currentVersion !== _searchVersion) - return; - var plugin = allPluginsOrdered[i]; - if (plugin.isBuiltIn) { - var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery); - var blLimit = Math.min(blItems.length, maxPerPlugin); - for (var j = 0; j < blLimit; j++) { - var item = transformBuiltInLauncherItem(blItems[j], plugin.id); - item._preScored = 900 - j; - allItems.push(item); - } - } else { - var pItems = getPluginItems(plugin.id, searchQuery, maxPerPlugin); - for (var j = 0; j < pItems.length; j++) { - pItems[j]._preScored = 900 - j; - allItems.push(pItems[j]); - } - } - } - - if (currentVersion !== _searchVersion) - return; - - var dynamicDefs = buildDynamicSectionDefs(allItems); - var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem); - var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, false, 50); - - if (currentVersion !== _searchVersion) - return; - - for (var i = 0; i < newSections.length; i++) { - var sid = newSections[i].id; - if (collapsedSections[sid] !== undefined) - newSections[i].collapsed = collapsedSections[sid]; - } - - _applyHighlights(newSections, searchQuery); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - selectedFlatIndex = restoreSelection(flatModel); - updateSelectedItem(); - isSearching = false; - searchCompleted(); - } - - function performFileSearch() { - if (!DSearchService.dsearchAvailable) - return; - var fileQuery = ""; - var effectiveType = fileSearchType || "all"; - var includeFiles = SettingsData.dankLauncherV2IncludeFilesInAll; - var includeFolders = SettingsData.dankLauncherV2IncludeFoldersInAll; - - if (searchQuery.startsWith("/")) { - fileQuery = searchQuery.substring(1).trim(); - } else if (searchMode === "files") { - fileQuery = searchQuery.trim(); - } else if (searchMode === "all" && (includeFiles || includeFolders)) { - fileQuery = searchQuery.trim(); - if (includeFiles && !includeFolders) - effectiveType = "file"; - else if (!includeFiles && includeFolders) - effectiveType = "dir"; - else - effectiveType = "all"; - } else { - return; - } - - if (fileQuery.length < 2) { - isFileSearching = false; - return; - } - - isFileSearching = true; - - var splitBothTypes = searchMode === "all" && includeFiles && includeFolders && DSearchService.supportsTypeFilter; - var queryTypes = splitBothTypes ? ["file", "dir"] : [effectiveType]; - var pending = queryTypes.length; - var aggregatedItems = []; - - for (var t = 0; t < queryTypes.length; t++) { - var queryType = queryTypes[t]; - var params = { - limit: 20, - fuzzy: true, - sort: fileSearchSort || "score", - desc: true - }; - - if (DSearchService.supportsTypeFilter) { - params.type = (queryType && queryType !== "all") ? queryType : "all"; - } - if (fileSearchExt) { - params.ext = fileSearchExt; - } - if (fileSearchFolder) { - params.folder = fileSearchFolder; - } - - DSearchService.search(fileQuery, params, function (response) { - pending--; - if (!response.error) { - var hits = response.result?.hits || []; - for (var i = 0; i < hits.length; i++) { - var hit = hits[i]; - var docTypes = hit.locations?.doc_type; - var isDir = docTypes ? !!docTypes["dir"] : false; - aggregatedItems.push(transformFileResult({ - path: hit.id || "", - score: hit.score || 0, - is_dir: isDir - })); - } - } - if (pending > 0) - return; - - isFileSearching = false; - _applyFileSearchResults(aggregatedItems, effectiveType); - }); - } - } - - function _applyFileSearchResults(fileItems, effectiveType) { - var fileSections = []; - var showType = effectiveType; - var order = SettingsData.launcherPluginOrder || []; - var filesOrderIdx = order.indexOf("__files"); - var foldersOrderIdx = order.indexOf("__folders"); - var filesPriority = filesOrderIdx !== -1 ? 2.6 + filesOrderIdx * 0.01 : 4; - var foldersPriority = foldersOrderIdx !== -1 ? 2.6 + foldersOrderIdx * 0.01 : 4.1; - - if (showType === "all" && DSearchService.supportsTypeFilter) { - var onlyFiles = []; - var onlyDirs = []; - for (var j = 0; j < fileItems.length; j++) { - if (fileItems[j].data?.is_dir) - onlyDirs.push(fileItems[j]); - else - onlyFiles.push(fileItems[j]); - } - if (onlyFiles.length > 0) { - fileSections.push({ - id: "files", - title: I18n.tr("Files"), - icon: "insert_drive_file", - priority: filesPriority, - items: onlyFiles, - collapsed: collapsedSections["files"] || false, - flatStartIndex: 0 - }); - } - if (onlyDirs.length > 0) { - fileSections.push({ - id: "folders", - title: I18n.tr("Folders"), - icon: "folder", - priority: foldersPriority, - items: onlyDirs, - collapsed: collapsedSections["folders"] || false, - flatStartIndex: 0 - }); - } - } else { - var filesIcon = showType === "dir" ? "folder" : showType === "file" ? "insert_drive_file" : "folder"; - var filesTitle = showType === "dir" ? I18n.tr("Folders") : I18n.tr("Files"); - var singlePriority = showType === "dir" ? foldersPriority : filesPriority; - if (fileItems.length > 0) { - fileSections.push({ - id: "files", - title: filesTitle, - icon: filesIcon, - priority: singlePriority, - items: fileItems, - collapsed: collapsedSections["files"] || false, - flatStartIndex: 0 - }); - } - } - - var newSections; - if (searchMode === "files") { - newSections = fileSections; - } else { - var existingNonFile = sections.filter(function (s) { - return s.id !== "files" && s.id !== "folders"; - }); - newSections = existingNonFile.concat(fileSections); - } - newSections.sort(function (a, b) { - return a.priority - b.priority; - }); - _applyHighlights(newSections, searchQuery); - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - selectedFlatIndex = getFirstItemIndex(); - updateSelectedItem(); - } - - function searchApps(query) { - var apps = AppSearchService.searchApplications(query); - var items = []; - - for (var i = 0; i < apps.length; i++) { - items.push(getOrTransformApp(apps[i])); - } - - var coreApps = AppSearchService.getCoreApps(query); - for (var i = 0; i < coreApps.length; i++) { - items.push(transformCoreApp(coreApps[i])); - } - - return items; - } - - function transformApp(app) { - var appId = app.id || app.execString || app.exec || ""; - var override = SessionData.getAppOverride(appId); - return Transform.transformApp(app, override, [], I18n.tr("Launch")); - } - - function transformCoreApp(app) { - return Transform.transformCoreApp(app, I18n.tr("Open")); - } - - function transformBuiltInLauncherItem(item, pluginId) { - return Transform.transformBuiltInLauncherItem(item, pluginId, I18n.tr("Open")); - } - - function transformFileResult(file) { - return Transform.transformFileResult(file, I18n.tr("Open"), I18n.tr("Open folder"), I18n.tr("Copy path"), I18n.tr("Open in terminal")); - } - - function detectTrigger(query) { - if (!query || query.length === 0) - return { - pluginId: null, - query: query - }; - - var pluginTriggers = PluginService.getAllPluginTriggers(); - for (var trigger in pluginTriggers) { - if (trigger && query.startsWith(trigger)) { - return { - pluginId: pluginTriggers[trigger], - query: query.substring(trigger.length).trim() - }; - } - } - - var builtInTriggers = AppSearchService.getBuiltInLauncherTriggers(); - for (var trigger in builtInTriggers) { - if (trigger && query.startsWith(trigger)) { - return { - pluginId: builtInTriggers[trigger], - query: query.substring(trigger.length).trim(), - isBuiltIn: true - }; - } - } - - return { - pluginId: null, - query: query - }; - } - - function getEmptyTriggerPlugins() { - var plugins = PluginService.getPluginsWithEmptyTrigger(); - var visible = plugins.filter(function (pluginId) { - return SettingsData.getPluginAllowWithoutTrigger(pluginId); - }); - return sortPluginIdsByOrder(visible); - } - - function getAllLauncherPluginIds() { - var launchers = PluginService.getLauncherPlugins(); - return Object.keys(launchers); - } - - function getVisibleLauncherPluginIds() { - var launchers = PluginService.getLauncherPlugins(); - var visible = Object.keys(launchers).filter(function (pluginId) { - return SettingsData.getPluginAllowWithoutTrigger(pluginId); - }); - return sortPluginIdsByOrder(visible); - } - - function getAllBuiltInLauncherIds() { - var launchers = AppSearchService.getBuiltInLauncherPlugins(); - return Object.keys(launchers); - } - - function getVisibleBuiltInLauncherIds() { - var launchers = AppSearchService.getBuiltInLauncherPlugins(); - var visible = Object.keys(launchers).filter(function (pluginId) { - return SettingsData.getPluginAllowWithoutTrigger(pluginId); - }); - return sortPluginIdsByOrder(visible); - } - - function sortPluginIdsByOrder(pluginIds) { - return Utils.sortPluginIdsByOrder(pluginIds, SettingsData.launcherPluginOrder || []); - } - - function getAllVisiblePluginsOrdered() { - var thirdPartyLaunchers = PluginService.getLauncherPlugins() || {}; - var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins() || {}; - var all = []; - for (var id in thirdPartyLaunchers) { - if (SettingsData.getPluginAllowWithoutTrigger(id)) - all.push({ - id: id, - isBuiltIn: false - }); - } - for (var id in builtInLaunchers) { - if (SettingsData.getPluginAllowWithoutTrigger(id)) - all.push({ - id: id, - isBuiltIn: true - }); - } - return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []); - } - - function getEmptyTriggerPluginsOrdered() { - var thirdParty = PluginService.getPluginsWithEmptyTrigger() || []; - var builtIn = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger() || []; - var all = []; - for (var i = 0; i < thirdParty.length; i++) { - var id = thirdParty[i]; - if (SettingsData.getPluginAllowWithoutTrigger(id)) - all.push({ - id: id, - isBuiltIn: false - }); - } - for (var i = 0; i < builtIn.length; i++) { - var id = builtIn[i]; - if (SettingsData.getPluginAllowWithoutTrigger(id)) - all.push({ - id: id, - isBuiltIn: true - }); - } - return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []); - } - - function getPluginBrowseItems() { - var items = []; - var browseLabel = I18n.tr("Browse"); - var triggerLabel = I18n.tr("Trigger: %1"); - var noTriggerLabel = I18n.tr("No trigger"); - - var launchers = PluginService.getLauncherPlugins(); - for (var pluginId in launchers) { - var trigger = PluginService.getPluginTrigger(pluginId); - var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId); - items.push(Transform.createPluginBrowseItem(pluginId, launchers[pluginId], trigger, false, isAllowed, browseLabel, triggerLabel, noTriggerLabel)); - } - - var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins(); - for (var pluginId in builtInLaunchers) { - var trigger = AppSearchService.getBuiltInPluginTrigger(pluginId); - var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId); - items.push(Transform.createPluginBrowseItem(pluginId, builtInLaunchers[pluginId], trigger, true, isAllowed, browseLabel, triggerLabel, noTriggerLabel)); - } - - return items; - } - - function getBuiltInEmptyTriggerLaunchers() { - var plugins = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger(); - var visible = plugins.filter(function (pluginId) { - return SettingsData.getPluginAllowWithoutTrigger(pluginId); - }); - return sortPluginIdsByOrder(visible); - } - - function getPluginItems(pluginId, query, limit) { - var items = AppSearchService.getPluginItemsForPlugin(pluginId, query); - var count = limit > 0 && limit < items.length ? limit : items.length; - var transformed = []; - - for (var i = 0; i < count; i++) { - transformed.push(transformPluginItem(items[i], pluginId)); - } - - return transformed; - } - - function getPluginName(pluginId, isBuiltIn) { - if (isBuiltIn) { - var plugin = AppSearchService.builtInPlugins[pluginId]; - return plugin ? plugin.name : pluginId; - } - var launchers = PluginService.getLauncherPlugins(); - if (launchers[pluginId]) { - return launchers[pluginId].name || pluginId; - } - return pluginId; - } - - function getPluginMetadata(pluginId) { - var builtIn = AppSearchService.builtInPlugins[pluginId]; - if (builtIn) { - return { - name: builtIn.name || pluginId, - icon: builtIn.cornerIcon || "extension" - }; - } - var launchers = PluginService.getLauncherPlugins(); - if (launchers[pluginId]) { - var rawIcon = launchers[pluginId].icon || "extension"; - return { - name: launchers[pluginId].name || pluginId, - icon: Utils.stripIconPrefix(rawIcon) - }; - } - return { - name: pluginId, - icon: "extension" - }; - } - - function buildDynamicSectionDefs(items) { - var baseDefs = sectionDefinitions.slice(); - var pluginSections = {}; - var order = SettingsData.launcherPluginOrder || []; - var orderMap = {}; - for (var k = 0; k < order.length; k++) - orderMap[order[k]] = k; - var unorderedPriority = 2.6 + order.length * 0.01; - - for (var i = 0; i < items.length; i++) { - var section = items[i].section; - if (!section || !section.startsWith("plugin_")) - continue; - if (pluginSections[section]) - continue; - var pluginId = section.substring(7); - var meta = getPluginMetadata(pluginId); - var viewPref = getPluginViewPref(pluginId); - var orderIdx = orderMap[pluginId]; - var priority; - if (orderIdx !== undefined) { - priority = 2.6 + orderIdx * 0.01; - } else { - priority = unorderedPriority; - unorderedPriority += 0.01; - } - - pluginSections[section] = { - id: section, - title: meta.name, - icon: meta.icon, - priority: priority, - defaultViewMode: viewPref.mode || "list" - }; - - if (viewPref.mode) - setPluginViewPreference(section, viewPref.mode, viewPref.enforced); - } - - for (var sectionId in pluginSections) { - baseDefs.push(pluginSections[sectionId]); - } - - baseDefs.sort(function (a, b) { - return a.priority - b.priority; - }); - return baseDefs; - } - - function getPluginViewPref(pluginId) { - var builtIn = AppSearchService.builtInPlugins[pluginId]; - if (builtIn && builtIn.viewMode) { - return { - mode: builtIn.viewMode, - enforced: builtIn.viewModeEnforced === true - }; - } - - var pref = PluginService.getPluginViewPreference(pluginId); - if (pref && pref.mode) { - return pref; - } - - return { - mode: "list", - enforced: false - }; - } - - function transformPluginItem(item, pluginId) { - return Transform.transformPluginItem(item, pluginId, I18n.tr("Select")); - } - - function getFrecencyForItem(item) { - if (item.type !== "app") - return null; - - var appId = item.id; - var usageRanking = AppUsageHistoryData.appUsageRanking || {}; - - var idVariants = [appId, appId.replace(".desktop", "")]; - var usageData = null; - - for (var i = 0; i < idVariants.length; i++) { - if (usageRanking[idVariants[i]]) { - usageData = usageRanking[idVariants[i]]; - break; - } - } - - return { - usageCount: usageData?.usageCount || 0 - }; - } - - function getFirstItemIndex() { - return Nav.getFirstItemIndex(flatModel); - } - - function _getCachedModeData(mode) { - return _modeSectionsCache[mode] || null; - } - - function _setCachedModeData(mode, sectionsData, flatModelData) { - var cache = Object.assign({}, _modeSectionsCache); - cache[mode] = { - sections: sectionsData, - flatModel: flatModelData - }; - _modeSectionsCache = cache; - } - - function _clearModeCache() { - _modeSectionsCache = {}; - } - - function _saveDiskCache(sectionsData) { - var serializable = []; - for (var i = 0; i < sectionsData.length; i++) { - var s = sectionsData[i]; - var items = []; - var srcItems = s.items || []; - for (var j = 0; j < srcItems.length; j++) { - var it = srcItems[j]; - items.push({ - id: it.id, - type: it.type, - name: it.name || "", - subtitle: it.subtitle || "", - icon: it.icon || "", - iconType: it.iconType || "image", - iconFull: it.iconFull || "", - section: it.section || "", - isCore: it.isCore || false, - isBuiltInLauncher: it.isBuiltInLauncher || false, - pluginId: it.pluginId || "" - }); - } - serializable.push({ - id: s.id, - title: s.title || "", - icon: s.icon || "", - priority: s.priority || 0, - items: items - }); - } - CacheData.saveLauncherCache(serializable); - } - - function _actionsFromDesktopEntry(appId) { - if (!appId) - return []; - var entry = DesktopEntries.heuristicLookup(appId); - if (!entry || !entry.actions || entry.actions.length === 0) - return []; - var result = []; - for (var i = 0; i < entry.actions.length; i++) { - result.push({ - name: entry.actions[i].name, - icon: "play_arrow", - actionData: entry.actions[i] - }); - } - return result; - } - - function _loadDiskCache() { - var cached = CacheData.loadLauncherCache(); - if (!cached || !Array.isArray(cached) || cached.length === 0) - return null; - - var sectionsData = []; - for (var i = 0; i < cached.length; i++) { - var s = cached[i]; - var items = []; - var srcItems = s.items || []; - for (var j = 0; j < srcItems.length; j++) { - var it = srcItems[j]; - items.push({ - id: it.id || "", - type: it.type || "app", - name: it.name || "", - subtitle: it.subtitle || "", - icon: it.icon || "", - iconType: it.iconType || "image", - iconFull: it.iconFull || "", - section: it.section || "", - isCore: it.isCore || false, - isBuiltInLauncher: it.isBuiltInLauncher || false, - pluginId: it.pluginId || "", - data: { - id: it.id - }, - actions: _actionsFromDesktopEntry(it.id), - primaryAction: it.type === "app" && !it.isCore ? { - name: I18n.tr("Launch"), - icon: "open_in_new", - action: "launch" - } : null, - _diskCached: true, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: undefined - }); - } - sectionsData.push({ - id: s.id || "", - title: s.title || "", - icon: s.icon || "", - priority: s.priority || 0, - items: items, - collapsed: false, - flatStartIndex: 0 - }); - } - return sectionsData; - } - - function updateSelectedItem() { - if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) { - var entry = flatModel[selectedFlatIndex]; - selectedItem = entry.isHeader ? null : entry.item; - } else { - selectedItem = null; - } - } - - function _applyHighlights(sectionsData, query) { - if (!query || query.length === 0) { - for (var i = 0; i < sectionsData.length; i++) { - var items = sectionsData[i].items; - for (var j = 0; j < items.length; j++) { - var item = items[j]; - item._hName = item.name || ""; - item._hSub = item.subtitle || ""; - item._hRich = false; - } - } - return; - } - - var highlightColor = Theme.primary; - var nameColor = Theme.surfaceText; - var subColor = Theme.surfaceVariantText; - var lowerQuery = query.toLowerCase(); - - for (var i = 0; i < sectionsData.length; i++) { - var items = sectionsData[i].items; - for (var j = 0; j < items.length; j++) { - var item = items[j]; - item._hName = _highlightField(item.name || "", lowerQuery, query.length, nameColor, highlightColor); - item._hSub = _highlightField(item.subtitle || "", lowerQuery, query.length, subColor, highlightColor); - item._hRich = true; - } - } - } - - function _highlightField(text, lowerQuery, queryLen, baseColor, highlightColor) { - if (!text) - return ""; - var idx = text.toLowerCase().indexOf(lowerQuery); - if (idx === -1) - return text; - var before = text.substring(0, idx); - var match = text.substring(idx, idx + queryLen); - var after = text.substring(idx + queryLen); - return '<span style="color:' + baseColor + '">' + before + '</span><span style="color:' + highlightColor + '; font-weight:600">' + match + '</span><span style="color:' + baseColor + '">' + after + '</span>'; - } - - function getCurrentSectionViewMode() { - if (selectedFlatIndex < 0 || selectedFlatIndex >= flatModel.length) - return "list"; - var entry = flatModel[selectedFlatIndex]; - if (!entry || entry.isHeader) - return "list"; - return getSectionViewMode(entry.sectionId); - } - - function getGridColumns(sectionId) { - return Nav.getGridColumns(getSectionViewMode(sectionId), gridColumns); - } - - function _cancelPendingSelectionReset() { - _queryDrivenSearch = false; - _pluginPhaseForceFirst = false; - } - - function selectNext() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculateNextIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectPrevious() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculatePrevIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectRight() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewMode); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectLeft() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewMode); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectNextSection() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculateNextSectionIndex(flatModel, selectedFlatIndex); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectPreviousSection() { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculatePrevSectionIndex(flatModel, selectedFlatIndex); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectPageDown(visibleItems) { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectPageUp(visibleItems) { - keyboardNavigationActive = true; - _cancelPendingSelectionReset(); - var newIndex = Nav.calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems); - if (newIndex !== selectedFlatIndex) { - selectedFlatIndex = newIndex; - updateSelectedItem(); - } - } - - function selectIndex(index) { - keyboardNavigationActive = false; - if (index >= 0 && index < flatModel.length && !flatModel[index].isHeader) { - selectedFlatIndex = index; - updateSelectedItem(); - } - } - - function toggleSection(sectionId) { - _clearModeCache(); - var newCollapsed = Object.assign({}, collapsedSections); - var currentState = newCollapsed[sectionId]; - - if (currentState === undefined) { - for (var i = 0; i < sections.length; i++) { - if (sections[i].id === sectionId) { - currentState = sections[i].collapsed || false; - break; - } - } - } - - newCollapsed[sectionId] = !currentState; - collapsedSections = newCollapsed; - - var newSections = sections.slice(); - for (var i = 0; i < newSections.length; i++) { - if (newSections[i].id === sectionId) { - newSections[i] = Object.assign({}, newSections[i], { - collapsed: newCollapsed[sectionId] - }); - } - } - flatModel = Scorer.flattenSections(newSections); - sections = newSections; - - if (selectedFlatIndex >= flatModel.length) { - selectedFlatIndex = getFirstItemIndex(); - } - updateSelectedItem(); - } - - function executeSelected() { - if (searchDebounce.running) { - searchDebounce.stop(); - performSearch(); - } - if (!selectedItem) - return; - executeItem(selectedItem); - } - - function executeItem(item) { - if (!item) - return; - - SessionData.addLauncherHistory(searchQuery); - - if (item.type === "plugin_browse") { - var browsePluginId = item.data?.pluginId; - if (!browsePluginId) - return; - var browseTrigger = item.data.isBuiltIn ? AppSearchService.getBuiltInPluginTrigger(browsePluginId) : PluginService.getPluginTrigger(browsePluginId); - - if (browseTrigger && browseTrigger.length > 0) { - searchQueryRequested(browseTrigger); - } else { - setMode("plugins"); - pluginFilter = browsePluginId; - performSearch(); - } - return; - } - - switch (item.type) { - case "app": - if (item.isCore) { - AppSearchService.executeCoreApp(item.data); - } else if (item.data?.isAction) { - launchAppAction(item.data); - } else { - launchApp(item.data); - } - break; - case "plugin": - if (item.isBuiltInLauncher) { - AppSearchService.executeBuiltInLauncherItem(item.data); - } else { - AppSearchService.executePluginItem(item.data, item.pluginId); - } - break; - case "file": - openFile(item.data?.path); - break; - default: - return; - } - - itemExecuted(); - } - - function executeAction(item, action) { - if (!item || !action) - return; - switch (action.action) { - case "launch": - executeItem(item); - break; - case "open": - openFile(item.data.path); - break; - case "open_folder": - openFolder(item.data.path); - break; - case "copy_path": - copyToClipboard(item.data.path); - break; - case "open_terminal": - openTerminal(item.data.path); - break; - case "copy": - copyToClipboard(item.name); - break; - case "execute": - executeItem(item); - break; - case "launch_dgpu": - if (item.type === "app" && item.data) { - launchAppWithNvidia(item.data); - } - break; - case "toggle_all_visibility": - if (item.type === "plugin_browse" && item.data?.pluginId) { - var pluginId = item.data.pluginId; - var currentState = SettingsData.getPluginAllowWithoutTrigger(pluginId); - SettingsData.setPluginAllowWithoutTrigger(pluginId, !currentState); - performSearch(); - } - return; - default: - if (item.type === "app" && action.actionData) { - launchAppAction({ - parentApp: item.data, - actionData: action.actionData - }); - } - } - - itemExecuted(); - } - - function _resolveDesktopEntry(app) { - if (!app) - return null; - if (app.command) - return app; - var id = app.id || app.execString || app.exec || ""; - if (!id) - return null; - return DesktopEntries.heuristicLookup(id); - } - - function launchApp(app) { - var entry = _resolveDesktopEntry(app); - if (!entry) - return; - SessionService.launchDesktopEntry(entry); - AppUsageHistoryData.addAppUsage(entry); - } - - function launchAppWithNvidia(app) { - var entry = _resolveDesktopEntry(app); - if (!entry) - return; - SessionService.launchDesktopEntry(entry, true); - AppUsageHistoryData.addAppUsage(entry); - } - - function launchAppAction(actionItem) { - if (!actionItem || !actionItem.actionData) - return; - var entry = _resolveDesktopEntry(actionItem.parentApp); - if (!entry) - return; - SessionService.launchDesktopAction(entry, actionItem.actionData); - AppUsageHistoryData.addAppUsage(entry); - } - - function openFile(path) { - if (!path) - return; - Qt.openUrlExternally("file://" + path); - } - - function openFolder(path) { - if (!path) - return; - var folder = path.substring(0, path.lastIndexOf("/")); - Qt.openUrlExternally("file://" + folder); - } - - function openTerminal(path) { - if (!path) - return; - var terminal = Quickshell.env("TERMINAL") || "xterm"; - Quickshell.execDetached({ - command: [terminal], - workingDirectory: path - }); - } - - function copyToClipboard(text) { - if (!text) - return; - Quickshell.execDetached(["dms", "cl", "copy", text]); - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js deleted file mode 100644 index a06285f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ControllerUtils.js +++ /dev/null @@ -1,128 +0,0 @@ -.pragma library - -function getFileIcon(filename) { - var ext = filename.lastIndexOf(".") > 0 ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : ""; - - switch (ext) { - case "pdf": - return "picture_as_pdf"; - case "doc": - case "docx": - case "odt": - return "description"; - case "xls": - case "xlsx": - case "ods": - return "table_chart"; - case "ppt": - case "pptx": - case "odp": - return "slideshow"; - case "txt": - case "md": - case "rst": - return "article"; - case "jpg": - case "jpeg": - case "png": - case "gif": - case "svg": - case "webp": - return "image"; - case "mp3": - case "wav": - case "flac": - case "ogg": - return "audio_file"; - case "mp4": - case "mkv": - case "avi": - case "webm": - return "video_file"; - case "zip": - case "tar": - case "gz": - case "7z": - case "rar": - return "folder_zip"; - case "js": - case "ts": - case "py": - case "rs": - case "go": - case "java": - case "c": - case "cpp": - case "h": - return "code"; - case "html": - case "css": - case "htm": - return "web"; - case "json": - case "xml": - case "yaml": - case "yml": - return "data_object"; - case "sh": - case "bash": - case "zsh": - return "terminal"; - default: - return "insert_drive_file"; - } -} - -function stripIconPrefix(iconName) { - if (!iconName) - return "extension"; - if (iconName.startsWith("unicode:")) - return iconName.substring(8); - if (iconName.startsWith("material:")) - return iconName.substring(9); - if (iconName.startsWith("image:")) - return iconName.substring(6); - return iconName; -} - -function detectIconType(iconName) { - if (!iconName) - return "material"; - if (iconName.startsWith("unicode:")) - return "unicode"; - if (iconName.startsWith("material:")) - return "material"; - if (iconName.startsWith("image:")) - return "image"; - if (iconName.indexOf("/") >= 0 || iconName.indexOf(".") >= 0) - return "image"; - if (/^[a-z]+-[a-z]/.test(iconName.toLowerCase())) - return "image"; - return "material"; -} - -function sortPluginIdsByOrder(pluginIds, order) { - if (!order || order.length === 0) - return pluginIds; - var orderMap = {}; - for (var i = 0; i < order.length; i++) - orderMap[order[i]] = i; - return pluginIds.slice().sort(function (a, b) { - var aOrder = orderMap[a] !== undefined ? orderMap[a] : 9999; - var bOrder = orderMap[b] !== undefined ? orderMap[b] : 9999; - return aOrder - bOrder; - }); -} - -function sortPluginsOrdered(plugins, order) { - if (!order || order.length === 0) - return plugins; - var orderMap = {}; - for (var i = 0; i < order.length; i++) - orderMap[order[i]] = i; - return plugins.sort(function (a, b) { - var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999; - var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999; - return aOrder - bOrder; - }); -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml deleted file mode 100644 index 859022c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml +++ /dev/null @@ -1,465 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Wayland -import Quickshell.Hyprland -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - visible: false - - property bool spotlightOpen: false - property bool keyboardActive: false - property bool contentVisible: false - property var spotlightContent: launcherContentLoader.item - property bool openedFromOverview: false - property bool isClosing: false - property bool _pendingInitialize: false - property string _pendingQuery: "" - property string _pendingMode: "" - readonly property bool unloadContentOnClose: SettingsData.dankLauncherV2UnloadOnClose - - readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab - readonly property var effectiveScreen: launcherWindow.screen - readonly property real screenWidth: effectiveScreen?.width ?? 1920 - readonly property real screenHeight: effectiveScreen?.height ?? 1080 - readonly property real dpr: effectiveScreen ? CompositorService.getScreenScale(effectiveScreen) : 1 - - readonly property int baseWidth: { - switch (SettingsData.dankLauncherV2Size) { - case "micro": - return 500; - case "medium": - return 720; - case "large": - return 860; - default: - return 620; - } - } - readonly property int baseHeight: { - switch (SettingsData.dankLauncherV2Size) { - case "micro": - return 480; - case "medium": - return 720; - case "large": - return 860; - default: - return 600; - } - } - readonly property int modalWidth: Math.min(baseWidth, screenWidth - 100) - readonly property int modalHeight: Math.min(baseHeight, screenHeight - 100) - readonly property real modalX: (screenWidth - modalWidth) / 2 - readonly property real modalY: (screenHeight - modalHeight) / 2 - - readonly property color backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - readonly property real cornerRadius: Theme.cornerRadius - readonly property color borderColor: { - if (!SettingsData.dankLauncherV2BorderEnabled) - return Theme.outlineMedium; - switch (SettingsData.dankLauncherV2BorderColor) { - case "primary": - return Theme.primary; - case "secondary": - return Theme.secondary; - case "outline": - return Theme.outline; - case "surfaceText": - return Theme.surfaceText; - default: - return Theme.primary; - } - } - readonly property int borderWidth: SettingsData.dankLauncherV2BorderEnabled ? SettingsData.dankLauncherV2BorderThickness : 0 - - signal dialogClosed - - function _ensureContentLoadedAndInitialize(query, mode) { - _pendingQuery = query || ""; - _pendingMode = mode || ""; - _pendingInitialize = true; - contentVisible = true; - launcherContentLoader.active = true; - - if (spotlightContent) { - _initializeAndShow(_pendingQuery, _pendingMode); - _pendingInitialize = false; - } - } - - function _initializeAndShow(query, mode) { - if (!spotlightContent) - return; - contentVisible = true; - spotlightContent.searchField.forceActiveFocus(); - - var targetQuery = ""; - - if (query) { - targetQuery = query; - } else if (SettingsData.rememberLastQuery) { - targetQuery = SessionData.launcherLastQuery || ""; - } - - if (spotlightContent.searchField) { - spotlightContent.searchField.text = targetQuery; - } - if (spotlightContent.controller) { - var targetMode = mode || SessionData.launcherLastMode || "all"; - spotlightContent.controller.searchMode = targetMode; - spotlightContent.controller.activePluginId = ""; - spotlightContent.controller.activePluginName = ""; - spotlightContent.controller.pluginFilter = ""; - spotlightContent.controller.fileSearchType = "all"; - spotlightContent.controller.fileSearchExt = ""; - spotlightContent.controller.fileSearchFolder = ""; - spotlightContent.controller.fileSearchSort = "score"; - spotlightContent.controller.collapsedSections = {}; - spotlightContent.controller.selectedFlatIndex = 0; - spotlightContent.controller.selectedItem = null; - spotlightContent.controller.historyIndex = -1; - spotlightContent.controller.searchQuery = targetQuery; - - spotlightContent.controller.performSearch(); - } - if (spotlightContent.resetScroll) { - spotlightContent.resetScroll(); - } - if (spotlightContent.actionPanel) { - spotlightContent.actionPanel.hide(); - } - } - - function _finishShow(query, mode) { - spotlightOpen = true; - isClosing = false; - openedFromOverview = false; - - keyboardActive = true; - ModalManager.openModal(root); - if (useHyprlandFocusGrab) - focusGrab.active = true; - - _ensureContentLoadedAndInitialize(query || "", mode || ""); - } - - function show() { - closeCleanupTimer.stop(); - - var focusedScreen = CompositorService.getFocusedScreen(); - if (focusedScreen && launcherWindow.screen !== focusedScreen) { - spotlightOpen = false; - isClosing = false; - launcherWindow.screen = focusedScreen; - Qt.callLater(() => root._finishShow("", "")); - return; - } - - _finishShow("", ""); - } - - function showWithQuery(query) { - closeCleanupTimer.stop(); - - var focusedScreen = CompositorService.getFocusedScreen(); - if (focusedScreen && launcherWindow.screen !== focusedScreen) { - spotlightOpen = false; - isClosing = false; - launcherWindow.screen = focusedScreen; - Qt.callLater(() => root._finishShow(query, "")); - return; - } - - _finishShow(query, ""); - } - - function hide() { - if (!spotlightOpen) - return; - openedFromOverview = false; - isClosing = true; - contentVisible = false; - - keyboardActive = false; - spotlightOpen = false; - focusGrab.active = false; - ModalManager.closeModal(root); - - closeCleanupTimer.start(); - } - - function toggle() { - spotlightOpen ? hide() : show(); - } - - function showWithMode(mode) { - closeCleanupTimer.stop(); - - var focusedScreen = CompositorService.getFocusedScreen(); - if (focusedScreen && launcherWindow.screen !== focusedScreen) { - spotlightOpen = false; - isClosing = false; - launcherWindow.screen = focusedScreen; - Qt.callLater(() => root._finishShow("", mode)); - return; - } - - spotlightOpen = true; - isClosing = false; - openedFromOverview = false; - - keyboardActive = true; - ModalManager.openModal(root); - if (useHyprlandFocusGrab) - focusGrab.active = true; - - _ensureContentLoadedAndInitialize("", mode); - } - - function toggleWithMode(mode) { - if (spotlightOpen) { - hide(); - } else { - showWithMode(mode); - } - } - - function toggleWithQuery(query) { - if (spotlightOpen) { - hide(); - } else { - showWithQuery(query); - } - } - - Timer { - id: closeCleanupTimer - interval: Theme.modalAnimationDuration + 50 - repeat: false - onTriggered: { - isClosing = false; - if (root.unloadContentOnClose) - launcherContentLoader.active = false; - dialogClosed(); - } - } - - Connections { - target: spotlightContent?.controller ?? null - - function onModeChanged(mode) { - if (spotlightContent.controller.autoSwitchedToFiles) - return; - SessionData.setLauncherLastMode(mode); - } - } - - HyprlandFocusGrab { - id: focusGrab - windows: [launcherWindow] - active: false - - onCleared: { - if (spotlightOpen) { - hide(); - } - } - } - - Connections { - target: ModalManager - function onCloseAllModalsExcept(excludedModal) { - if (excludedModal !== root && spotlightOpen) { - hide(); - } - } - } - - Connections { - target: Quickshell - function onScreensChanged() { - if (Quickshell.screens.length === 0) - return; - - const screenName = launcherWindow.screen?.name; - if (screenName) { - for (let i = 0; i < Quickshell.screens.length; i++) { - if (Quickshell.screens[i].name === screenName) - return; - } - } - - if (spotlightOpen) - hide(); - - const newScreen = CompositorService.getFocusedScreen() ?? Quickshell.screens[0]; - if (newScreen) - launcherWindow.screen = newScreen; - } - } - - PanelWindow { - id: launcherWindow - visible: spotlightOpen || isClosing - color: "transparent" - exclusionMode: ExclusionMode.Ignore - - WindowBlur { - targetWindow: launcherWindow - readonly property real s: Math.min(1, modalContainer.scale) - blurX: root.modalX + root.modalWidth * (1 - s) * 0.5 - blurY: root.modalY + root.modalHeight * (1 - s) * 0.5 - blurWidth: (contentVisible && modalContainer.opacity > 0) ? root.modalWidth * s : 0 - blurHeight: (contentVisible && modalContainer.opacity > 0) ? root.modalHeight * s : 0 - blurRadius: root.cornerRadius - } - - WlrLayershell.namespace: "dms:spotlight" - WlrLayershell.layer: { - switch (Quickshell.env("DMS_MODAL_LAYER")) { - case "bottom": - console.error("DankModal: 'bottom' layer is not valid for modals. Defaulting to 'top' layer."); - return WlrLayershell.Top; - case "background": - console.error("DankModal: 'background' layer is not valid for modals. Defaulting to 'top' layer."); - return WlrLayershell.Top; - case "overlay": - return WlrLayershell.Overlay; - default: - return WlrLayershell.Top; - } - } - WlrLayershell.keyboardFocus: keyboardActive ? (root.useHyprlandFocusGrab ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.Exclusive) : WlrKeyboardFocus.None - - anchors { - top: true - bottom: true - left: true - right: true - } - - mask: Region { - item: spotlightOpen ? fullScreenMask : null - } - - Item { - id: fullScreenMask - anchors.fill: parent - } - - Rectangle { - id: backgroundDarken - anchors.fill: parent - color: "black" - opacity: contentVisible && SettingsData.modalDarkenBackground ? 0.5 : 0 - visible: contentVisible || opacity > 0 - - Behavior on opacity { - DankAnim { - duration: Theme.modalAnimationDuration - easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized - } - } - } - - MouseArea { - anchors.fill: parent - enabled: spotlightOpen - onClicked: mouse => { - var contentX = modalContainer.x; - var contentY = modalContainer.y; - var contentW = modalContainer.width; - var contentH = modalContainer.height; - - if (mouse.x < contentX || mouse.x > contentX + contentW || mouse.y < contentY || mouse.y > contentY + contentH) { - root.hide(); - } - } - } - - Item { - id: modalContainer - x: root.modalX - y: root.modalY - width: root.modalWidth - height: root.modalHeight - visible: contentVisible || opacity > 0 - - opacity: contentVisible ? 1 : 0 - scale: contentVisible ? 1 : 0.96 - transformOrigin: Item.Center - - Behavior on opacity { - DankAnim { - duration: Theme.modalAnimationDuration - easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized - } - } - - Behavior on scale { - DankAnim { - duration: Theme.modalAnimationDuration - easing.bezierCurve: contentVisible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized - } - } - - ElevationShadow { - id: launcherShadowLayer - anchors.fill: parent - level: Theme.elevationLevel3 - fallbackOffset: 6 - targetColor: root.backgroundColor - borderColor: root.borderColor - borderWidth: root.borderWidth - targetRadius: root.cornerRadius - shadowEnabled: Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - } - - MouseArea { - anchors.fill: parent - onPressed: mouse => mouse.accepted = true - } - - FocusScope { - anchors.fill: parent - focus: keyboardActive - - Loader { - id: launcherContentLoader - anchors.fill: parent - active: !root.unloadContentOnClose || root.spotlightOpen || root.isClosing || root.contentVisible || root._pendingInitialize - asynchronous: false - sourceComponent: LauncherContent { - focus: true - parentModal: root - } - - onLoaded: { - if (root._pendingInitialize) { - root._initializeAndShow(root._pendingQuery, root._pendingMode); - root._pendingInitialize = false; - } - } - } - - Keys.onEscapePressed: event => { - root.hide(); - event.accepted = true; - } - } - - Rectangle { - anchors.fill: parent - radius: root.cornerRadius - color: "transparent" - border.color: BlurService.borderColor - border.width: BlurService.borderWidth - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml deleted file mode 100644 index a7f39c3..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/GridItem.qml +++ /dev/null @@ -1,105 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property var item: null - property bool isSelected: false - property bool isHovered: itemArea.containsMouse - property var controller: null - property int flatIndex: -1 - - signal clicked - signal rightClicked(real mouseX, real mouseY) - - readonly property string iconValue: { - if (!item) - return ""; - switch (item.iconType) { - case "material": - case "nerd": - return "material:" + (item.icon || "apps"); - case "unicode": - return "unicode:" + (item.icon || ""); - case "composite": - return item.iconFull || ""; - case "image": - default: - return item.icon || ""; - } - } - - readonly property int computedIconSize: Math.min(48, Math.max(32, width * 0.45)) - - radius: Theme.cornerRadius - color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : "transparent" - - DankRipple { - id: rippleLayer - rippleColor: Theme.surfaceText - cornerRadius: root.radius - } - - Column { - anchors.centerIn: parent - anchors.margins: Theme.spacingS - spacing: Theme.spacingS - width: parent.width - Theme.spacingM - - AppIconRenderer { - width: root.computedIconSize - height: root.computedIconSize - anchors.horizontalCenter: parent.horizontalCenter - iconValue: root.iconValue - iconSize: root.computedIconSize - fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?" - iconColor: root.isSelected ? Theme.primary : Theme.surfaceText - materialIconSizeAdjustment: root.computedIconSize * 0.3 - } - - Text { - width: parent.width - text: root.item?._hName ?? root.item?.name ?? "" - textFormat: root.item?._hRich ? Text.RichText : Text.PlainText - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - font.family: Theme.fontFamily - color: root.isSelected ? Theme.primary : Theme.surfaceText - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - maximumLineCount: 2 - wrapMode: Text.Wrap - } - } - - MouseArea { - id: itemArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onPressed: mouse => { - if (mouse.button === Qt.LeftButton) - rippleLayer.trigger(mouse.x, mouse.y); - } - onClicked: mouse => { - if (mouse.button === Qt.RightButton) { - var scenePos = mapToItem(null, mouse.x, mouse.y); - root.rightClicked(scenePos.x, scenePos.y); - } else { - root.clicked(); - } - } - - onPositionChanged: { - if (root.controller) { - root.controller.keyboardNavigationActive = false; - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js deleted file mode 100644 index 61c108c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ItemTransformers.js +++ /dev/null @@ -1,237 +0,0 @@ -.pragma library - - .import "ControllerUtils.js" as Utils - -function transformApp(app, override, defaultActions, primaryActionLabel) { - var appId = app.id || app.execString || app.exec || ""; - - var actions = []; - if (app.actions && app.actions.length > 0) { - for (var i = 0; i < app.actions.length; i++) { - actions.push({ - name: app.actions[i].name, - icon: "play_arrow", - actionData: app.actions[i] - }); - } - } - - return { - id: appId, - type: "app", - name: override?.name || app.name || "", - subtitle: override?.comment || app.comment || "", - icon: override?.icon || app.icon || "application-x-executable", - iconType: "image", - section: "apps", - data: app, - keywords: app.keywords || [], - actions: actions, - primaryAction: { - name: primaryActionLabel, - icon: "open_in_new", - action: "launch" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: undefined - }; -} - -function transformCoreApp(app, openLabel) { - var iconName = "apps"; - var iconType = "material"; - - if (app.icon) { - if (app.icon.startsWith("svg+corner:")) { - iconType = "composite"; - } else if (app.icon.startsWith("material:")) { - iconName = app.icon.substring(9); - } else { - iconName = app.icon; - iconType = "image"; - } - } - - return { - id: app.builtInPluginId || app.action || "", - type: "app", - name: app.name || "", - subtitle: app.comment || "", - icon: iconName, - iconType: iconType, - iconFull: app.icon, - section: "apps", - data: app, - isCore: true, - actions: [], - primaryAction: { - name: openLabel, - icon: "open_in_new", - action: "launch" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: undefined - }; -} - -function transformBuiltInLauncherItem(item, pluginId, openLabel) { - var rawIcon = item.icon || "extension"; - var icon = Utils.stripIconPrefix(rawIcon); - var iconType = item.iconType; - if (!iconType) { - if (rawIcon.startsWith("material:")) - iconType = "material"; - else if (rawIcon.startsWith("unicode:")) - iconType = "unicode"; - else - iconType = "image"; - } - - return { - id: item.action || "", - type: "plugin", - name: item.name || "", - subtitle: item.comment || "", - icon: icon, - iconType: iconType, - section: "plugin_" + pluginId, - data: item, - pluginId: pluginId, - isBuiltInLauncher: true, - keywords: item.keywords || [], - actions: [], - primaryAction: { - name: openLabel, - icon: "open_in_new", - action: "execute" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: item._preScored - }; -} - -function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel, openTerminalLabel) { - var filename = file.path ? file.path.split("/").pop() : ""; - var dirname = file.path ? file.path.substring(0, file.path.lastIndexOf("/")) : ""; - var isDir = file.is_dir || false; - - var actions = []; - if (isDir) { - if (openTerminalLabel) { - actions.push({ - name: openTerminalLabel, - icon: "terminal", - action: "open_terminal" - }); - } - } else { - actions.push({ - name: openFolderLabel, - icon: "folder_open", - action: "open_folder" - }); - } - actions.push({ - name: copyPathLabel, - icon: "content_copy", - action: "copy_path" - }); - - return { - id: file.path || "", - type: "file", - name: filename, - subtitle: dirname, - icon: isDir ? "folder" : Utils.getFileIcon(filename), - iconType: "material", - section: "files", - data: file, - actions: actions, - primaryAction: { - name: openLabel, - icon: "open_in_new", - action: "open" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: undefined - }; -} - -function transformPluginItem(item, pluginId, selectLabel) { - var rawIcon = item.icon || "extension"; - var icon = Utils.stripIconPrefix(rawIcon); - var iconType = item.iconType; - if (!iconType) { - if (rawIcon.startsWith("material:")) - iconType = "material"; - else if (rawIcon.startsWith("unicode:")) - iconType = "unicode"; - else - iconType = "image"; - } - - return { - id: item.id || item.name || "", - type: "plugin", - name: item.name || "", - subtitle: item.comment || item.description || "", - icon: icon, - iconType: iconType, - section: "plugin_" + pluginId, - data: item, - pluginId: pluginId, - keywords: item.keywords || [], - actions: item.actions || [], - primaryAction: item.primaryAction || { - name: selectLabel, - icon: "check", - action: "execute" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: item._preScored - }; -} - -function createPluginBrowseItem(pluginId, plugin, trigger, isBuiltIn, isAllowed, browseLabel, triggerLabel, noTriggerLabel) { - var rawIcon = isBuiltIn ? (plugin.cornerIcon || "extension") : (plugin.icon || "extension"); - return { - id: "browse_" + pluginId, - type: "plugin_browse", - name: plugin.name || pluginId, - subtitle: trigger ? triggerLabel.replace("%1", trigger) : noTriggerLabel, - icon: isBuiltIn ? rawIcon : Utils.stripIconPrefix(rawIcon), - iconType: isBuiltIn ? "material" : Utils.detectIconType(rawIcon), - section: "browse_plugins", - data: { - pluginId: pluginId, - plugin: plugin, - isBuiltIn: isBuiltIn - }, - actions: [ - { - name: "All", - icon: isAllowed ? "visibility" : "visibility_off", - action: "toggle_all_visibility" - } - ], - primaryAction: { - name: browseLabel, - icon: "arrow_forward", - action: "browse_plugin" - }, - _hName: "", - _hSub: "", - _hRich: false, - _preScored: undefined - }; -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml deleted file mode 100644 index 4372515..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContent.qml +++ /dev/null @@ -1,1075 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -FocusScope { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property var parentModal: null - property string viewModeContext: "spotlight" - property alias searchField: searchField - property alias controller: controller - property alias resultsList: resultsList - property alias actionPanel: actionPanel - - property bool editMode: false - property var editingApp: null - property string editAppId: "" - - function resetScroll() { - resultsList.resetScroll(); - } - - function focusSearchField() { - searchField.forceActiveFocus(); - } - - function openEditMode(app) { - if (!app) - return; - editingApp = app; - editAppId = app.id || app.execString || app.exec || ""; - var existing = SessionData.getAppOverride(editAppId); - editNameField.text = existing?.name || ""; - editIconField.text = existing?.icon || ""; - editCommentField.text = existing?.comment || ""; - editEnvVarsField.text = existing?.envVars || ""; - editExtraFlagsField.text = existing?.extraFlags || ""; - editDgpuToggle.checked = existing?.launchOnDgpu || false; - editMode = true; - Qt.callLater(() => editNameField.forceActiveFocus()); - } - - function closeEditMode() { - editMode = false; - editingApp = null; - editAppId = ""; - Qt.callLater(() => searchField.forceActiveFocus()); - } - - function saveAppOverride() { - var override = {}; - if (editNameField.text.trim()) - override.name = editNameField.text.trim(); - if (editIconField.text.trim()) - override.icon = editIconField.text.trim(); - if (editCommentField.text.trim()) - override.comment = editCommentField.text.trim(); - if (editEnvVarsField.text.trim()) - override.envVars = editEnvVarsField.text.trim(); - if (editExtraFlagsField.text.trim()) - override.extraFlags = editExtraFlagsField.text.trim(); - if (editDgpuToggle.checked) - override.launchOnDgpu = true; - SessionData.setAppOverride(editAppId, override); - closeEditMode(); - } - - function resetAppOverride() { - SessionData.clearAppOverride(editAppId); - closeEditMode(); - } - - function showContextMenu(item, x, y, fromKeyboard) { - if (!item) - return; - if (!contextMenu.hasContextMenuActions(item)) - return; - contextMenu.show(x, y, item, fromKeyboard); - } - - anchors.fill: parent - focus: true - - Controller { - id: controller - active: root.parentModal?.spotlightOpen ?? true - viewModeContext: root.viewModeContext - - onItemExecuted: { - if (root.parentModal) { - root.parentModal.hide(); - } - if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) { - NiriService.toggleOverview(); - } - } - } - - LauncherContextMenu { - id: contextMenu - parent: root - controller: root.controller - searchField: root.searchField - parentHandler: root - - onEditAppRequested: app => { - root.openEditMode(app); - } - } - - Keys.onPressed: event => { - if (editMode) { - if (event.key === Qt.Key_Escape) { - closeEditMode(); - event.accepted = true; - } - return; - } - - var hasCtrl = event.modifiers & Qt.ControlModifier; - event.accepted = true; - - switch (event.key) { - case Qt.Key_Escape: - if (actionPanel.expanded) { - actionPanel.hide(); - return; - } - if (controller.clearPluginFilter()) - return; - if (root.parentModal) - root.parentModal.hide(); - return; - case Qt.Key_Backspace: - if (searchField.text.length === 0) { - if (controller.clearPluginFilter()) - return; - if (controller.autoSwitchedToFiles) { - controller.restorePreviousMode(); - return; - } - } - event.accepted = false; - return; - case Qt.Key_Down: - if (hasCtrl) { - controller.navigateHistory("down"); - } else { - controller.selectNext(); - } - return; - case Qt.Key_Up: - if (hasCtrl) { - controller.navigateHistory("up"); - } else { - controller.selectPrevious(); - } - return; - case Qt.Key_PageDown: - controller.selectPageDown(8); - return; - case Qt.Key_PageUp: - controller.selectPageUp(8); - return; - case Qt.Key_Right: - if (hasCtrl) { - controller.cycleMode(); - return; - } - if (controller.getCurrentSectionViewMode() !== "list") { - controller.selectRight(); - return; - } - event.accepted = false; - return; - case Qt.Key_Left: - if (hasCtrl) { - const reverse = true; - controller.cycleMode(reverse); - return; - } - if (controller.getCurrentSectionViewMode() !== "list") { - controller.selectLeft(); - return; - } - event.accepted = false; - return; - case Qt.Key_H: - if (hasCtrl) { - const reverse = true; - controller.cycleMode(reverse); - return; - } - event.accepted = false; - return; - case Qt.Key_J: - if (hasCtrl) { - controller.selectNext(); - return; - } - event.accepted = false; - return; - case Qt.Key_K: - if (hasCtrl) { - controller.selectPrevious(); - return; - } - event.accepted = false; - return; - case Qt.Key_L: - if (hasCtrl) { - controller.cycleMode(); - return; - } - event.accepted = false; - return; - case Qt.Key_N: - if (hasCtrl) { - controller.selectNextSection(); - return; - } - event.accepted = false; - return; - case Qt.Key_P: - if (hasCtrl) { - controller.selectPreviousSection(); - return; - } - event.accepted = false; - return; - case Qt.Key_Tab: - if (hasCtrl && actionPanel.hasActions) { - actionPanel.expanded ? actionPanel.cycleAction() : actionPanel.show(); - return; - } - controller.selectNext(); - return; - case Qt.Key_Backtab: - if (hasCtrl && actionPanel.expanded) { - const reverse = true; - actionPanel.expanded ? actionPanel.cycleAction(reverse) : actionPanel.show(); - return; - } - controller.selectPrevious(); - return; - case Qt.Key_Return: - case Qt.Key_Enter: - if (event.modifiers & Qt.ShiftModifier) { - controller.pasteSelected(); - return; - } - if (actionPanel.expanded && actionPanel.selectedActionIndex > 0) { - actionPanel.executeSelectedAction(); - } else { - controller.executeSelected(); - } - return; - case Qt.Key_Menu: - case Qt.Key_F10: - if (contextMenu.hasContextMenuActions(controller.selectedItem)) { - var scenePos = resultsList.getSelectedItemPosition(); - var localPos = root.mapFromItem(null, scenePos.x, scenePos.y); - showContextMenu(controller.selectedItem, localPos.x, localPos.y, true); - } - return; - case Qt.Key_1: - if (hasCtrl) { - controller.setMode("all"); - return; - } - event.accepted = false; - return; - case Qt.Key_2: - if (hasCtrl) { - controller.setMode("apps"); - return; - } - event.accepted = false; - return; - case Qt.Key_3: - if (hasCtrl) { - controller.setMode("files"); - return; - } - event.accepted = false; - return; - case Qt.Key_4: - if (hasCtrl) { - controller.setMode("plugins"); - return; - } - event.accepted = false; - return; - case Qt.Key_Slash: - if (event.modifiers === Qt.NoModifier && searchField.text.length === 0) { - controller.setMode("files", true); - return; - } - event.accepted = false; - return; - default: - event.accepted = false; - } - } - - Item { - anchors.fill: parent - visible: !editMode && !(root.parentModal?.isClosing ?? false) - - Item { - id: footerBar - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.leftMargin: root.parentModal?.borderWidth ?? 1 - anchors.rightMargin: root.parentModal?.borderWidth ?? 1 - anchors.bottomMargin: root.parentModal?.borderWidth ?? 1 - readonly property bool showFooter: SettingsData.dankLauncherV2Size !== "micro" && SettingsData.dankLauncherV2ShowFooter - height: showFooter ? 36 : 0 - visible: showFooter - clip: true - - Rectangle { - anchors.fill: parent - anchors.topMargin: -Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - radius: Theme.cornerRadius - } - - Row { - id: modeButtonsRow - anchors.left: parent.left - anchors.leftMargin: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - layoutDirection: I18n.isRtl ? Qt.RightToLeft : Qt.LeftToRight - spacing: 2 - - Repeater { - model: [ - { - id: "all", - label: I18n.tr("All"), - icon: "search" - }, - { - id: "apps", - label: I18n.tr("Apps"), - icon: "apps" - }, - { - id: "files", - label: I18n.tr("Files"), - icon: "folder" - }, - { - id: "plugins", - label: I18n.tr("Plugins"), - icon: "extension" - } - ] - - Rectangle { - required property var modelData - required property int index - - width: buttonContent.width + Theme.spacingM * 2 - height: 28 - radius: Theme.cornerRadius - color: controller.searchMode === modelData.id || modeArea.containsMouse ? Theme.primaryContainer : "transparent" - - Row { - id: buttonContent - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: modelData.icon - size: 14 - color: controller.searchMode === modelData.id ? Theme.primary : Theme.surfaceVariantText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: modelData.label - font.pixelSize: Theme.fontSizeSmall - color: controller.searchMode === modelData.id ? Theme.primary : Theme.surfaceText - } - } - - MouseArea { - id: modeArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: controller.setMode(modelData.id) - } - } - } - } - - Row { - id: hintsRow - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - layoutDirection: I18n.isRtl ? Qt.RightToLeft : Qt.LeftToRight - spacing: Theme.spacingM - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: "↑↓ " + I18n.tr("nav") - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: "↵ " + I18n.tr("open") - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: "Ctrl-Tab " + I18n.tr("actions") - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - visible: actionPanel.hasActions - } - } - } - - Column { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: footerBar.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingM - spacing: Theme.spacingXS - clip: false - - Row { - width: parent.width - spacing: Theme.spacingS - - Rectangle { - id: pluginBadge - visible: controller.activePluginName.length > 0 - width: visible ? pluginBadgeContent.implicitWidth + Theme.spacingM : 0 - height: searchField.height - radius: 16 - color: Theme.primary - - Row { - id: pluginBadgeContent - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: "extension" - size: 14 - color: Theme.primaryText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: controller.activePluginName - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.primaryText - } - } - - Behavior on width { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - - DankTextField { - id: searchField - width: parent.width - (pluginBadge.visible ? pluginBadge.width + Theme.spacingS : 0) - cornerRadius: Theme.cornerRadius - backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: controller.activePluginId ? "extension" : controller.searchQuery.startsWith("/") ? "folder" : "search" - leftIconSize: Theme.iconSize - leftIconColor: Theme.surfaceVariantText - leftIconFocusedColor: Theme.primary - showClearButton: true - textColor: Theme.surfaceText - font.pixelSize: Theme.fontSizeLarge - enabled: root.parentModal ? root.parentModal.spotlightOpen : true - placeholderText: "" - ignoreUpDownKeys: true - ignoreTabKeys: true - keyForwardTargets: [root] - - onTextChanged: { - controller.setSearchQuery(text); - if (actionPanel.expanded) { - actionPanel.hide(); - } - } - - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - if (root.parentModal) { - root.parentModal.hide(); - } - event.accepted = true; - } else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)) { - if (actionPanel.expanded && actionPanel.selectedActionIndex > 0) { - actionPanel.executeSelectedAction(); - } else { - controller.executeSelected(); - } - event.accepted = true; - } - } - } - } - - Row { - id: categoryRow - width: parent.width - readonly property bool showPluginCategories: controller.activePluginCategories.length > 0 - height: showPluginCategories ? 36 : 0 - visible: showPluginCategories - spacing: Theme.spacingS - - clip: true - - Behavior on height { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - DankDropdown { - id: categoryDropdown - visible: categoryRow.showPluginCategories - width: Math.min(200, parent.width) - compactMode: true - dropdownWidth: 200 - popupWidth: 240 - maxPopupHeight: 300 - enableFuzzySearch: controller.activePluginCategories.length > 8 - currentValue: { - const cats = controller.activePluginCategories; - const current = controller.activePluginCategory; - if (!current) - return cats.length > 0 ? cats[0].name : ""; - for (let i = 0; i < cats.length; i++) { - if (cats[i].id === current) - return cats[i].name; - } - return cats.length > 0 ? cats[0].name : ""; - } - options: { - const cats = controller.activePluginCategories; - const names = []; - for (let i = 0; i < cats.length; i++) - names.push(cats[i].name); - return names; - } - - onValueChanged: value => { - const cats = controller.activePluginCategories; - for (let i = 0; i < cats.length; i++) { - if (cats[i].name === value) { - controller.setActivePluginCategory(cats[i].id); - return; - } - } - } - } - } - - Item { - id: fileFilterRow - width: parent.width - height: showFileFilters ? fileFilterContent.height : 0 - visible: showFileFilters - - readonly property bool showFileFilters: controller.searchMode === "files" - - Behavior on height { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - Row { - id: fileFilterContent - width: parent.width - spacing: Theme.spacingS - - Row { - id: typeChips - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - visible: DSearchService.supportsTypeFilter - - Repeater { - model: [ - { - id: "all", - label: I18n.tr("All"), - icon: "search" - }, - { - id: "file", - label: I18n.tr("Files"), - icon: "insert_drive_file" - }, - { - id: "dir", - label: I18n.tr("Folders"), - icon: "folder" - } - ] - - Rectangle { - required property var modelData - required property int index - - width: chipContent.width + Theme.spacingM * 2 - height: sortDropdown.height - radius: Theme.cornerRadius - color: controller.fileSearchType === modelData.id || chipArea.containsMouse ? Theme.primaryContainer : "transparent" - - Row { - id: chipContent - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: modelData.icon - size: 14 - color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceVariantText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: modelData.label - font.pixelSize: Theme.fontSizeSmall - color: controller.fileSearchType === modelData.id ? Theme.primary : Theme.surfaceText - } - } - - MouseArea { - id: chipArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: controller.setFileSearchType(modelData.id) - } - } - } - } - - Rectangle { - width: 1 - height: 20 - anchors.verticalCenter: parent.verticalCenter - color: Theme.outlineMedium - visible: typeChips.visible - } - - DankDropdown { - id: sortDropdown - anchors.verticalCenter: parent.verticalCenter - width: Math.min(130, parent.width / 3) - compactMode: true - dropdownWidth: 130 - popupWidth: 150 - maxPopupHeight: 200 - currentValue: { - switch (controller.fileSearchSort) { - case "score": - return I18n.tr("Score"); - case "name": - return I18n.tr("Name"); - case "modified": - return I18n.tr("Modified"); - case "size": - return I18n.tr("Size"); - default: - return I18n.tr("Score"); - } - } - options: [I18n.tr("Score"), I18n.tr("Name"), I18n.tr("Modified"), I18n.tr("Size")] - - onValueChanged: value => { - var sortMap = {}; - sortMap[I18n.tr("Score")] = "score"; - sortMap[I18n.tr("Name")] = "name"; - sortMap[I18n.tr("Modified")] = "modified"; - sortMap[I18n.tr("Size")] = "size"; - controller.setFileSearchSort(sortMap[value] || "score"); - } - } - - DankTextField { - id: extFilterField - anchors.verticalCenter: parent.verticalCenter - width: Math.min(100, parent.width / 4) - height: sortDropdown.height - placeholderText: I18n.tr("ext") - font.pixelSize: Theme.fontSizeSmall - showClearButton: text.length > 0 - - onTextChanged: { - controller.setFileSearchExt(text.trim()); - } - } - } - } - - Item { - width: parent.width - height: parent.height - searchField.height - categoryRow.height - fileFilterRow.height - actionPanel.height - Theme.spacingXS * ((categoryRow.visible ? 1 : 0) + (fileFilterRow.visible ? 1 : 0) + 2) - ResultsList { - id: resultsList - anchors.fill: parent - controller: root.controller - - onItemRightClicked: (index, item, sceneX, sceneY) => { - if (item && contextMenu.hasContextMenuActions(item)) { - var localPos = root.mapFromItem(null, sceneX, sceneY); - root.showContextMenu(item, localPos.x, localPos.y, false); - } - } - } - } - - ActionPanel { - id: actionPanel - width: parent.width - selectedItem: controller.selectedItem - controller: controller - } - } - } - - Connections { - target: controller - function onSelectedItemChanged() { - if (actionPanel.expanded && !actionPanel.hasActions) { - actionPanel.hide(); - } - } - function onSearchQueryRequested(query) { - searchField.text = query; - searchField.cursorPosition = query.length; - } - function onModeChanged() { - extFilterField.text = ""; - } - } - - FocusScope { - id: editView - anchors.fill: parent - anchors.margins: Theme.spacingM - visible: editMode - focus: editMode - - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - closeEditMode(); - event.accepted = true; - } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { - if (event.modifiers & Qt.ControlModifier) { - saveAppOverride(); - event.accepted = true; - } - } else if (event.key === Qt.Key_S && event.modifiers & Qt.ControlModifier) { - saveAppOverride(); - event.accepted = true; - } - } - - Column { - anchors.fill: parent - spacing: Theme.spacingM - - Row { - width: parent.width - spacing: Theme.spacingM - - Rectangle { - width: 40 - height: 40 - radius: Theme.cornerRadius - color: backButtonArea.containsMouse ? Theme.surfaceHover : "transparent" - - DankIcon { - anchors.centerIn: parent - name: "arrow_back" - size: 20 - color: Theme.surfaceText - } - - MouseArea { - id: backButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: closeEditMode() - } - } - - Image { - width: 40 - height: 40 - source: Paths.resolveIconUrl(editingApp?.icon || "application-x-executable") - sourceSize.width: 40 - sourceSize.height: 40 - fillMode: Image.PreserveAspectFit - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: I18n.tr("Edit App") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: editingApp?.name || "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - } - - Flickable { - width: parent.width - height: parent.height - y - buttonsRow.height - Theme.spacingM - contentHeight: editFieldsColumn.height - clip: true - boundsBehavior: Flickable.StopAtBounds - - Column { - id: editFieldsColumn - width: parent.width - spacing: Theme.spacingS - - Column { - width: parent.width - spacing: 4 - - StyledText { - text: I18n.tr("Name") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - - DankTextField { - id: editNameField - width: parent.width - placeholderText: editingApp?.name || "" - keyNavigationTab: editIconField - keyNavigationBacktab: editExtraFlagsField - } - } - - Column { - width: parent.width - spacing: 4 - - StyledText { - text: I18n.tr("Icon") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - - DankTextField { - id: editIconField - width: parent.width - placeholderText: editingApp?.icon || "" - keyNavigationTab: editCommentField - keyNavigationBacktab: editNameField - } - } - - Column { - width: parent.width - spacing: 4 - - StyledText { - text: I18n.tr("Description") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - - DankTextField { - id: editCommentField - width: parent.width - placeholderText: editingApp?.comment || "" - keyNavigationTab: editEnvVarsField - keyNavigationBacktab: editIconField - } - } - - Column { - width: parent.width - spacing: 4 - - StyledText { - text: I18n.tr("Environment Variables") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: "KEY=value KEY2=value2" - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - } - - DankTextField { - id: editEnvVarsField - width: parent.width - placeholderText: "VAR=value" - keyNavigationTab: editExtraFlagsField - keyNavigationBacktab: editCommentField - } - } - - Column { - width: parent.width - spacing: 4 - - StyledText { - text: I18n.tr("Extra Arguments") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - - DankTextField { - id: editExtraFlagsField - width: parent.width - placeholderText: "--flag --option=value" - keyNavigationTab: editNameField - keyNavigationBacktab: editEnvVarsField - } - } - - DankToggle { - id: editDgpuToggle - width: parent.width - text: I18n.tr("Launch on dGPU by default") - visible: SessionService.nvidiaCommand.length > 0 - checked: false - onToggled: checked => editDgpuToggle.checked = checked - } - } - } - - Row { - id: buttonsRow - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Rectangle { - id: resetButton - width: 90 - height: 40 - radius: Theme.cornerRadius - color: resetButtonArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariantAlpha - visible: SessionData.getAppOverride(editAppId) !== null - - StyledText { - text: I18n.tr("Reset") - font.pixelSize: Theme.fontSizeMedium - color: Theme.error - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: resetButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: resetAppOverride() - } - } - - Rectangle { - id: cancelButton - width: 90 - height: 40 - radius: Theme.cornerRadius - color: cancelButtonArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariantAlpha - - StyledText { - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: cancelButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: closeEditMode() - } - } - - Rectangle { - id: saveButton - width: 90 - height: 40 - radius: Theme.cornerRadius - color: saveButtonArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.9) : Theme.primary - - StyledText { - text: I18n.tr("Save") - font.pixelSize: Theme.fontSizeMedium - color: Theme.primaryText - font.weight: Font.Medium - anchors.centerIn: parent - } - - MouseArea { - id: saveButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: saveAppOverride() - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml deleted file mode 100644 index 3c55590..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/LauncherContextMenu.qml +++ /dev/null @@ -1,510 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Controls -import qs.Common -import qs.Services -import qs.Widgets - -Popup { - id: root - - property var item: null - property var controller: null - property var searchField: null - property var parentHandler: null - - signal hideRequested - signal editAppRequested(var app) - - function hasContextMenuActions(spotlightItem) { - if (!spotlightItem) - return false; - if (spotlightItem.type === "app") - return true; - if (spotlightItem.type === "plugin" && spotlightItem.pluginId) { - var instance = PluginService.pluginInstances[spotlightItem.pluginId]; - if (!instance) - return false; - if (typeof instance.getContextMenuActions !== "function") - return false; - var actions = instance.getContextMenuActions(spotlightItem.data); - return Array.isArray(actions) && actions.length > 0; - } - return false; - } - - readonly property bool isCoreApp: item?.type === "app" && !!item?.isCore - readonly property var coreAppData: isCoreApp ? item?.data ?? null : null - readonly property var desktopEntry: !isCoreApp ? (item?.data ?? null) : null - readonly property string appId: { - if (isCoreApp) { - return item?.id || coreAppData?.builtInPluginId || ""; - } - return desktopEntry?.id || desktopEntry?.execString || ""; - } - readonly property bool isPinned: appId ? SessionData.isPinnedApp(appId) : false - readonly property bool isRegularApp: item?.type === "app" && !item.isCore && desktopEntry - readonly property bool isPluginItem: item?.type === "plugin" - - function getPluginContextMenuActions() { - if (!isPluginItem || !item?.pluginId) - return []; - - var instance = PluginService.pluginInstances[item.pluginId]; - if (!instance) - return []; - if (typeof instance.getContextMenuActions !== "function") - return []; - - var actions = instance.getContextMenuActions(item.data); - if (!Array.isArray(actions)) - return []; - - return actions; - } - - function executePluginAction(actionOrObj) { - var actionFunc = typeof actionOrObj === "function" ? actionOrObj : actionOrObj?.action; - var closeLauncher = typeof actionOrObj === "object" && actionOrObj?.closeLauncher; - - if (typeof actionFunc === "function") - actionFunc(); - - if (closeLauncher) { - controller?.itemExecuted(); - } else { - controller?.performSearch(); - } - hide(); - } - - readonly property var menuItems: { - var items = []; - - if (isPluginItem) { - var pluginActions = getPluginContextMenuActions(); - for (var i = 0; i < pluginActions.length; i++) { - var act = pluginActions[i]; - items.push({ - type: "item", - icon: act.icon || "play_arrow", - text: act.text || act.name || "", - pluginAction: act - }); - } - return items; - } - - if (item?.type === "app") { - items.push({ - type: "item", - icon: isPinned ? "keep_off" : "push_pin", - text: isPinned ? I18n.tr("Unpin from Dock") : I18n.tr("Pin to Dock"), - action: togglePin - }); - } - - if (isRegularApp) { - items.push({ - type: "item", - icon: "visibility_off", - text: I18n.tr("Hide App"), - action: hideCurrentApp - }); - items.push({ - type: "item", - icon: "edit", - text: I18n.tr("Edit App"), - action: editCurrentApp - }); - } - - if (item?.actions && item.actions.length > 0) { - items.push({ - type: "separator" - }); - for (var i = 0; i < item.actions.length; i++) { - var act = item.actions[i]; - items.push({ - type: "item", - icon: act.icon || "play_arrow", - text: act.name || "", - actionData: act - }); - } - } - - items.push({ - type: "separator" - }); - - if (isRegularApp && SessionService.nvidiaCommand) { - items.push({ - type: "item", - icon: "memory", - text: I18n.tr("Launch on dGPU"), - action: launchWithNvidia - }); - } - - items.push({ - type: "item", - icon: "launch", - text: I18n.tr("Launch"), - action: launchApp - }); - - return items; - } - - function show(x, y, spotlightItem, fromKeyboard) { - if (!spotlightItem?.data) - return; - item = spotlightItem; - selectedMenuIndex = fromKeyboard ? 0 : -1; - keyboardNavigation = fromKeyboard; - - if (parentHandler) - parentHandler.enabled = false; - - Qt.callLater(() => { - var parentW = parent?.width ?? 500; - var parentH = parent?.height ?? 600; - var menuW = width > 0 ? width : 200; - var menuH = height > 0 ? height : 200; - var margin = 8; - - var posX = x + 4; - var posY = y + 4; - - if (posX + menuW > parentW - margin) { - posX = Math.max(margin, parentW - menuW - margin); - } - if (posY + menuH > parentH - margin) { - posY = Math.max(margin, parentH - menuH - margin); - } - - root.x = posX; - root.y = posY; - open(); - }); - } - - function hide() { - if (parentHandler) - parentHandler.enabled = true; - close(); - } - - function togglePin() { - if (!appId) - return; - if (isPinned) - SessionData.removePinnedApp(appId); - else - SessionData.addPinnedApp(appId); - hide(); - } - - function hideCurrentApp() { - if (!appId) - return; - SessionData.hideApp(appId); - controller?.performSearch(); - hide(); - } - - function editCurrentApp() { - if (!desktopEntry) - return; - editAppRequested(desktopEntry); - hide(); - } - - function launchApp() { - if (isCoreApp) { - if (!coreAppData) - return; - AppSearchService.executeCoreApp(coreAppData); - controller?.itemExecuted(); - hide(); - return; - } - if (!desktopEntry) - return; - SessionService.launchDesktopEntry(desktopEntry); - AppUsageHistoryData.addAppUsage(desktopEntry); - controller?.itemExecuted(); - hide(); - } - - function launchWithNvidia() { - if (!desktopEntry) - return; - SessionService.launchDesktopEntry(desktopEntry, true); - AppUsageHistoryData.addAppUsage(desktopEntry); - controller?.itemExecuted(); - hide(); - } - - function executeDesktopAction(actionData) { - if (!desktopEntry || !actionData) - return; - SessionService.launchDesktopAction(desktopEntry, actionData.actionData || actionData); - AppUsageHistoryData.addAppUsage(desktopEntry); - controller?.itemExecuted(); - hide(); - } - - property int selectedMenuIndex: 0 - property bool keyboardNavigation: false - - readonly property int visibleItemCount: { - var count = 0; - for (var i = 0; i < menuItems.length; i++) { - if (menuItems[i].type === "item") - count++; - } - return count; - } - - function selectNext() { - if (visibleItemCount > 0) - selectedMenuIndex = (selectedMenuIndex + 1) % visibleItemCount; - } - - function selectPrevious() { - if (visibleItemCount > 0) - selectedMenuIndex = (selectedMenuIndex - 1 + visibleItemCount) % visibleItemCount; - } - - function activateSelected() { - var itemIndex = 0; - for (var i = 0; i < menuItems.length; i++) { - if (menuItems[i].type !== "item") - continue; - if (itemIndex === selectedMenuIndex) { - var menuItem = menuItems[i]; - if (menuItem.action) - menuItem.action(); - else if (menuItem.pluginAction) - executePluginAction(menuItem.pluginAction); - else if (menuItem.actionData) - executeDesktopAction(menuItem.actionData); - return; - } - itemIndex++; - } - } - - width: menuContainer.implicitWidth - height: menuContainer.implicitHeight - padding: 0 - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - modal: true - dim: false - background: Item {} - - onOpened: { - Qt.callLater(() => keyboardHandler.forceActiveFocus()); - } - - onClosed: { - if (parentHandler) - parentHandler.enabled = true; - if (searchField?.visible) { - Qt.callLater(() => searchField.forceActiveFocus()); - } - } - - enter: Transition { - NumberAnimation { - property: "opacity" - from: 0 - to: 1 - duration: Theme.shortDuration - easing.type: Theme.emphasizedEasing - } - } - - exit: Transition { - NumberAnimation { - property: "opacity" - from: 1 - to: 0 - duration: Theme.shortDuration - easing.type: Theme.emphasizedEasing - } - } - - contentItem: Item { - id: keyboardHandler - focus: true - implicitWidth: menuContainer.implicitWidth - implicitHeight: menuContainer.implicitHeight - - Keys.onPressed: event => { - switch (event.key) { - case Qt.Key_Down: - root.selectNext(); - event.accepted = true; - return; - case Qt.Key_Up: - root.selectPrevious(); - event.accepted = true; - return; - case Qt.Key_Return: - case Qt.Key_Enter: - root.activateSelected(); - event.accepted = true; - return; - case Qt.Key_Escape: - case Qt.Key_Left: - root.hide(); - event.accepted = true; - return; - } - } - - Rectangle { - id: menuContainer - anchors.fill: parent - implicitWidth: Math.max(180, menuColumn.implicitWidth + Theme.spacingS * 2) - implicitHeight: menuColumn.implicitHeight + Theme.spacingS * 2 - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - radius: Theme.cornerRadius - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 1 - - Rectangle { - anchors.fill: parent - anchors.topMargin: 4 - anchors.leftMargin: 2 - anchors.rightMargin: -2 - anchors.bottomMargin: -4 - radius: parent.radius - color: Qt.rgba(0, 0, 0, 0.15) - z: -1 - } - - Column { - id: menuColumn - anchors.fill: parent - anchors.margins: Theme.spacingS - spacing: 1 - - Repeater { - model: root.menuItems - - Item { - id: menuItemDelegate - required property var modelData - required property int index - - width: menuColumn.width - height: modelData.type === "separator" ? 5 : 32 - - readonly property int itemIndex: { - var count = 0; - for (var i = 0; i < index; i++) { - if (root.menuItems[i].type === "item") - count++; - } - return count; - } - - Rectangle { - visible: menuItemDelegate.modelData.type === "separator" - width: parent.width - Theme.spacingS * 2 - height: parent.height - anchors.horizontalCenter: parent.horizontalCenter - color: "transparent" - - Rectangle { - anchors.centerIn: parent - width: parent.width - height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) - } - } - - Rectangle { - visible: menuItemDelegate.modelData.type === "item" - width: parent.width - height: parent.height - radius: Theme.cornerRadius - color: { - if (root.keyboardNavigation && root.selectedMenuIndex === menuItemDelegate.itemIndex) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2); - } - return itemMouseArea.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.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Item { - width: Theme.iconSize - 2 - height: Theme.iconSize - 2 - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - visible: (menuItemDelegate.modelData?.icon ?? "").length > 0 - name: menuItemDelegate.modelData?.icon ?? "" - size: Theme.iconSize - 2 - color: Theme.surfaceText - opacity: 0.7 - anchors.verticalCenter: parent.verticalCenter - } - } - - StyledText { - text: menuItemDelegate.modelData.text || "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Normal - anchors.verticalCenter: parent.verticalCenter - elide: Text.ElideRight - width: parent.width - (Theme.iconSize - 2) - Theme.spacingS - } - } - - DankRipple { - id: menuItemRipple - rippleColor: Theme.surfaceText - cornerRadius: Theme.cornerRadius - } - - MouseArea { - id: itemMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onEntered: { - root.keyboardNavigation = false; - root.selectedMenuIndex = menuItemDelegate.itemIndex; - } - onPressed: mouse => menuItemRipple.trigger(mouse.x, mouse.y) - onClicked: { - var menuItem = menuItemDelegate.modelData; - if (menuItem.action) - menuItem.action(); - else if (menuItem.pluginAction) - root.executePluginAction(menuItem.pluginAction); - else if (menuItem.actionData) - root.executeDesktopAction(menuItem.actionData); - } - } - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js deleted file mode 100644 index 1e78b11..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/NavigationHelpers.js +++ /dev/null @@ -1,254 +0,0 @@ -.pragma library - -function getFirstItemIndex(flatModel) { - for (var i = 0; i < flatModel.length; i++) { - if (!flatModel[i].isHeader) - return i; - } - return 0; -} - -function findNextNonHeaderIndex(flatModel, startIndex) { - for (var i = startIndex; i < flatModel.length; i++) { - if (!flatModel[i].isHeader) - return i; - } - return -1; -} - -function findPrevNonHeaderIndex(flatModel, startIndex) { - for (var i = startIndex; i >= 0; i--) { - if (!flatModel[i].isHeader) - return i; - } - return -1; -} - -function getSectionBounds(flatModel, sectionId) { - if (flatModel._sectionBounds && flatModel._sectionBounds[sectionId]) - return flatModel._sectionBounds[sectionId]; - - var start = -1, end = -1; - for (var i = 0; i < flatModel.length; i++) { - if (flatModel[i].isHeader && flatModel[i].section?.id === sectionId) { - start = i + 1; - } else if (start >= 0 && !flatModel[i].isHeader && flatModel[i].sectionId === sectionId) { - end = i; - } else if (start >= 0 && end >= 0 && flatModel[i].sectionId !== sectionId) { - break; - } - } - return { - start: start, - end: end, - count: end >= start ? end - start + 1 : 0 - }; -} - -function getGridColumns(viewMode, gridColumns) { - switch (viewMode) { - case "tile": - return 3; - case "grid": - return gridColumns; - default: - return 1; - } -} - -function calculateNextIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var entry = flatModel[selectedFlatIndex]; - if (!entry || entry.isHeader) { - var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1); - return next !== -1 ? next : selectedFlatIndex; - } - - var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId); - if (actualViewMode === "list") { - var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1); - return next !== -1 ? next : selectedFlatIndex; - } - - var bounds = getSectionBounds(flatModel, entry.sectionId); - var cols = getGridColumns(actualViewMode, gridColumns); - var posInSection = selectedFlatIndex - bounds.start; - var newPosInSection = posInSection + cols; - - if (newPosInSection < bounds.count) { - return bounds.start + newPosInSection; - } - - var currentRow = Math.floor(posInSection / cols); - var lastRow = Math.floor((bounds.count - 1) / cols); - if (currentRow < lastRow) { - return bounds.start + bounds.count - 1; - } - - var nextSection = findNextNonHeaderIndex(flatModel, bounds.end + 1); - return nextSection !== -1 ? nextSection : selectedFlatIndex; -} - -function calculatePrevIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var entry = flatModel[selectedFlatIndex]; - if (!entry || entry.isHeader) { - var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1); - return prev !== -1 ? prev : selectedFlatIndex; - } - - var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId); - if (actualViewMode === "list") { - var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1); - return prev !== -1 ? prev : selectedFlatIndex; - } - - var bounds = getSectionBounds(flatModel, entry.sectionId); - var cols = getGridColumns(actualViewMode, gridColumns); - var posInSection = selectedFlatIndex - bounds.start; - var newPosInSection = posInSection - cols; - - if (newPosInSection >= 0) { - return bounds.start + newPosInSection; - } - - var prevItem = findPrevNonHeaderIndex(flatModel, bounds.start - 1); - return prevItem !== -1 ? prevItem : selectedFlatIndex; -} - -function calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var entry = flatModel[selectedFlatIndex]; - if (!entry || entry.isHeader) { - var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1); - return next !== -1 ? next : selectedFlatIndex; - } - - var viewMode = getSectionViewModeFn(entry.sectionId); - if (viewMode === "list") { - var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1); - return next !== -1 ? next : selectedFlatIndex; - } - - var bounds = getSectionBounds(flatModel, entry.sectionId); - var posInSection = selectedFlatIndex - bounds.start; - if (posInSection + 1 < bounds.count) { - return bounds.start + posInSection + 1; - } - return selectedFlatIndex; -} - -function calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var entry = flatModel[selectedFlatIndex]; - if (!entry || entry.isHeader) { - var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1); - return prev !== -1 ? prev : selectedFlatIndex; - } - - var viewMode = getSectionViewModeFn(entry.sectionId); - if (viewMode === "list") { - var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1); - return prev !== -1 ? prev : selectedFlatIndex; - } - - var bounds = getSectionBounds(flatModel, entry.sectionId); - var posInSection = selectedFlatIndex - bounds.start; - if (posInSection > 0) { - return bounds.start + posInSection - 1; - } - return selectedFlatIndex; -} - -function calculateNextSectionIndex(flatModel, selectedFlatIndex) { - var currentSection = null; - if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) { - currentSection = flatModel[selectedFlatIndex].sectionId; - } - - var foundCurrent = false; - for (var i = 0; i < flatModel.length; i++) { - if (flatModel[i].isHeader) { - if (foundCurrent) { - for (var j = i + 1; j < flatModel.length; j++) { - if (!flatModel[j].isHeader) - return j; - } - } - if (flatModel[i].section.id === currentSection) { - foundCurrent = true; - } - } - } - return selectedFlatIndex; -} - -function calculatePrevSectionIndex(flatModel, selectedFlatIndex) { - var currentSection = null; - if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) { - currentSection = flatModel[selectedFlatIndex].sectionId; - } - - var lastSectionStart = -1; - var prevSectionStart = -1; - - for (var i = 0; i < flatModel.length; i++) { - if (flatModel[i].isHeader) { - if (flatModel[i].section.id === currentSection) { - break; - } - prevSectionStart = lastSectionStart; - lastSectionStart = i; - } - } - - if (prevSectionStart >= 0) { - for (var j = prevSectionStart + 1; j < flatModel.length; j++) { - if (!flatModel[j].isHeader) - return j; - } - } - return selectedFlatIndex; -} - -function calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var itemsToSkip = visibleItems || 8; - var newIndex = selectedFlatIndex; - - for (var i = 0; i < itemsToSkip; i++) { - var next = findNextNonHeaderIndex(flatModel, newIndex + 1); - if (next === -1) - break; - newIndex = next; - } - - return newIndex; -} - -function calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems) { - if (flatModel.length === 0) - return selectedFlatIndex; - - var itemsToSkip = visibleItems || 8; - var newIndex = selectedFlatIndex; - - for (var i = 0; i < itemsToSkip; i++) { - var prev = findPrevNonHeaderIndex(flatModel, newIndex - 1); - if (prev === -1) - break; - newIndex = prev; - } - - return newIndex; -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml deleted file mode 100644 index 0a50cd3..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultItem.qml +++ /dev/null @@ -1,196 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property var item: null - property bool isSelected: false - property bool isHovered: itemArea.containsMouse || allModeToggleArea.containsMouse - property var controller: null - property int flatIndex: -1 - - signal clicked - signal rightClicked(real mouseX, real mouseY) - - readonly property string iconValue: { - if (!item) - return ""; - switch (item.iconType) { - case "material": - case "nerd": - return "material:" + (item.icon || "apps"); - case "unicode": - return "unicode:" + (item.icon || ""); - case "composite": - return item.iconFull || ""; - case "image": - default: - return item.icon || ""; - } - } - - width: parent?.width ?? 200 - height: 52 - color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : "transparent" - radius: Theme.cornerRadius - - DankRipple { - id: rippleLayer - rippleColor: Theme.surfaceText - cornerRadius: root.radius - } - - MouseArea { - id: itemArea - z: 1 - anchors.fill: parent - anchors.rightMargin: root.item?.type === "plugin_browse" ? 40 : 0 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onPressed: mouse => { - if (mouse.button === Qt.LeftButton) - rippleLayer.trigger(mouse.x, mouse.y); - } - onClicked: mouse => { - if (mouse.button === Qt.RightButton) { - var scenePos = mapToItem(null, mouse.x, mouse.y); - root.rightClicked(scenePos.x, scenePos.y); - } else { - root.clicked(); - } - } - - onPositionChanged: { - if (root.controller) - root.controller.keyboardNavigationActive = false; - } - } - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - AppIconRenderer { - width: 36 - height: 36 - anchors.verticalCenter: parent.verticalCenter - iconValue: root.iconValue - iconSize: 36 - fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?" - materialIconSizeAdjustment: 12 - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: parent.width - 36 - Theme.spacingM * 3 - rightContent.width - spacing: 2 - - Text { - width: parent.width - text: root.item?._hName ?? root.item?.name ?? "" - textFormat: root.item?._hRich ? Text.RichText : Text.PlainText - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - font.family: Theme.fontFamily - color: Theme.surfaceText - elide: Text.ElideRight - horizontalAlignment: Text.AlignLeft - } - - Text { - width: parent.width - text: root.item?._hSub ?? root.item?.subtitle ?? "" - textFormat: root.item?._hRich ? Text.RichText : Text.PlainText - font.pixelSize: Theme.fontSizeSmall - font.family: Theme.fontFamily - color: Theme.surfaceVariantText - elide: Text.ElideRight - clip: true - visible: (root.item?.subtitle ?? "").length > 0 - horizontalAlignment: Text.AlignLeft - } - } - - Row { - id: rightContent - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Rectangle { - id: allModeToggle - visible: root.item?.type === "plugin_browse" - width: 28 - height: 28 - radius: 14 - anchors.verticalCenter: parent.verticalCenter - color: allModeToggleArea.containsMouse ? Theme.surfaceHover : "transparent" - - property bool isAllowed: { - if (root.item?.type !== "plugin_browse") - return false; - var pluginId = root.item?.data?.pluginId; - if (!pluginId) - return false; - SettingsData.launcherPluginVisibility; - return SettingsData.getPluginAllowWithoutTrigger(pluginId); - } - - DankIcon { - anchors.centerIn: parent - name: allModeToggle.isAllowed ? "visibility" : "visibility_off" - size: 18 - color: allModeToggle.isAllowed ? Theme.primary : Theme.surfaceVariantText - } - - MouseArea { - id: allModeToggleArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - var pluginId = root.item?.data?.pluginId; - if (!pluginId) - return; - SettingsData.setPluginAllowWithoutTrigger(pluginId, !allModeToggle.isAllowed); - } - } - } - - Rectangle { - visible: !!root.item?.type && root.item.type !== "app" && root.item.type !== "plugin_browse" - width: typeBadge.implicitWidth + Theme.spacingS * 2 - height: 20 - radius: 10 - color: Theme.surfaceVariantAlpha - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: typeBadge - anchors.centerIn: parent - text: { - if (!root.item) - return ""; - switch (root.item.type) { - case "plugin": - return I18n.tr("Plugin"); - case "file": - return root.item.data?.is_dir ? I18n.tr("Folder") : I18n.tr("File"); - default: - return ""; - } - } - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.surfaceVariantText - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml deleted file mode 100644 index 53a2d45..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/ResultsList.qml +++ /dev/null @@ -1,498 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - property var controller: null - property int gridColumns: controller?.gridColumns ?? 4 - property var _visualRows: [] - property var _flatIndexToRowMap: ({}) - property var _cumulativeHeights: [] - - signal itemRightClicked(int index, var item, real mouseX, real mouseY) - - function _rebuildVisualModel() { - var sections = root.controller?.sections ?? []; - var rows = []; - var indexMap = {}; - var cumHeights = []; - var cumY = 0; - - for (var s = 0; s < sections.length; s++) { - var section = sections[s]; - var sectionId = section.id; - - cumHeights.push(cumY); - rows.push({ - _rowId: "h_" + sectionId, - type: "header", - section: section, - sectionId: sectionId, - height: 32 - }); - cumY += 32; - - if (section.collapsed) - continue; - - var versionTrigger = root.controller?.viewModeVersion ?? 0; - void (versionTrigger); - var mode = root.controller?.getSectionViewMode(sectionId) ?? "list"; - var items = section.items ?? []; - var flatStartIndex = section.flatStartIndex ?? 0; - - if (mode === "list") { - for (var i = 0; i < items.length; i++) { - var flatIdx = flatStartIndex + i; - indexMap[flatIdx] = rows.length; - cumHeights.push(cumY); - rows.push({ - _rowId: items[i].id, - type: "list_item", - item: items[i], - flatIndex: flatIdx, - sectionId: sectionId, - height: 52 - }); - cumY += 52; - } - } else { - var cols = root.controller?.getGridColumns(sectionId) ?? root.gridColumns; - var cellWidth = mode === "tile" ? Math.floor(root.width / 3) : Math.floor(root.width / root.gridColumns); - var cellHeight = mode === "tile" ? cellWidth * 0.75 : cellWidth + 24; - var numRows = Math.ceil(items.length / cols); - - for (var r = 0; r < numRows; r++) { - var rowItems = []; - for (var c = 0; c < cols; c++) { - var idx = r * cols + c; - if (idx >= items.length) - break; - var fi = flatStartIndex + idx; - indexMap[fi] = rows.length; - rowItems.push({ - item: items[idx], - flatIndex: fi - }); - } - cumHeights.push(cumY); - rows.push({ - _rowId: "gr_" + sectionId + "_" + r, - type: "grid_row", - items: rowItems, - sectionId: sectionId, - viewMode: mode, - cols: cols, - height: cellHeight - }); - cumY += cellHeight; - } - } - } - - root._flatIndexToRowMap = indexMap; - root._cumulativeHeights = cumHeights; - root._visualRows = rows; - } - - onGridColumnsChanged: Qt.callLater(_rebuildVisualModel) - onWidthChanged: Qt.callLater(_rebuildVisualModel) - - Connections { - target: root.controller - function onSectionsChanged() { - Qt.callLater(root._rebuildVisualModel); - } - function onViewModeVersionChanged() { - Qt.callLater(root._rebuildVisualModel); - } - function onSearchModeChanged() { - root._visualRows = []; - root._cumulativeHeights = []; - root._flatIndexToRowMap = {}; - } - } - - function resetScroll() { - mainListView.contentY = mainListView.originY; - } - - function ensureVisible(index) { - if (index < 0 || !controller?.flatModel || index >= controller.flatModel.length) - return; - var entry = controller.flatModel[index]; - if (!entry || entry.isHeader) - return; - var rowIndex = _flatIndexToRowMap[index]; - if (rowIndex === undefined) - return; - - mainListView.positionViewAtIndex(rowIndex, ListView.Contain); - - if (stickyHeader.visible && rowIndex < _cumulativeHeights.length) { - var rowY = _cumulativeHeights[rowIndex]; - var scrollY = mainListView.contentY - mainListView.originY; - if (rowY < scrollY + stickyHeader.height) { - mainListView.contentY = Math.max(mainListView.originY, rowY - stickyHeader.height + mainListView.originY); - } - } - } - - function getSelectedItemPosition() { - var fallback = mapToItem(null, width / 2, height / 2); - if (!controller?.flatModel || controller.selectedFlatIndex < 0) - return fallback; - - var entry = controller.flatModel[controller.selectedFlatIndex]; - if (!entry || entry.isHeader) - return fallback; - - var rowIndex = _flatIndexToRowMap[controller.selectedFlatIndex]; - if (rowIndex === undefined) - return fallback; - - var rowY = (rowIndex < _cumulativeHeights.length) ? _cumulativeHeights[rowIndex] : 0; - var row = _visualRows[rowIndex]; - if (!row) - return fallback; - - var itemX = width / 2; - var itemH = row.height; - - if (row.type === "grid_row") { - var rowItems = row.items; - for (var i = 0; i < rowItems.length; i++) { - if (rowItems[i].flatIndex === controller.selectedFlatIndex) { - var cellWidth = row.viewMode === "tile" ? Math.floor(width / 3) : Math.floor(width / row.cols); - itemX = i * cellWidth + cellWidth / 2; - break; - } - } - } - - var visualY = rowY - mainListView.contentY + mainListView.originY + itemH / 2; - var clampedY = Math.max(40, Math.min(height - 40, visualY)); - return mapToItem(null, itemX, clampedY); - } - - Connections { - target: root.controller - function onSelectedFlatIndexChanged() { - if (root.controller?.keyboardNavigationActive) { - Qt.callLater(() => root.ensureVisible(root.controller.selectedFlatIndex)); - } - } - } - - DankListView { - id: mainListView - anchors.fill: parent - clip: true - scrollBarTopMargin: (root.controller?.sections?.length > 0) ? 32 : 0 - - model: ScriptModel { - values: root._visualRows - objectProp: "_rowId" - } - - add: null - remove: null - displaced: null - move: null - - delegate: Item { - id: delegateRoot - required property var modelData - required property int index - - width: mainListView.width - height: modelData?.height ?? 52 - - SectionHeader { - anchors.fill: parent - visible: delegateRoot.modelData?.type === "header" - section: delegateRoot.modelData?.section ?? null - controller: root.controller - viewMode: { - var vt = root.controller?.viewModeVersion ?? 0; - void (vt); - return root.controller?.getSectionViewMode(delegateRoot.modelData?.sectionId ?? "") ?? "list"; - } - canChangeViewMode: { - var vt = root.controller?.viewModeVersion ?? 0; - void (vt); - return root.controller?.canChangeSectionViewMode(delegateRoot.modelData?.sectionId ?? "") ?? false; - } - canCollapse: root.controller?.canCollapseSection(delegateRoot.modelData?.sectionId ?? "") ?? false - } - - ResultItem { - anchors.fill: parent - visible: delegateRoot.modelData?.type === "list_item" - item: delegateRoot.modelData?.type === "list_item" ? (delegateRoot.modelData?.item ?? null) : null - isSelected: delegateRoot.modelData?.type === "list_item" && (delegateRoot.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex - controller: root.controller - flatIndex: delegateRoot.modelData?.type === "list_item" ? (delegateRoot.modelData?.flatIndex ?? -1) : -1 - - onClicked: { - if (root.controller && delegateRoot.modelData?.item) { - root.controller.executeItem(delegateRoot.modelData.item); - } - } - - onRightClicked: (mouseX, mouseY) => { - root.itemRightClicked(delegateRoot.modelData?.flatIndex ?? -1, delegateRoot.modelData?.item ?? null, mouseX, mouseY); - } - } - - Row { - id: gridRowContent - anchors.fill: parent - visible: delegateRoot.modelData?.type === "grid_row" - - Repeater { - model: delegateRoot.modelData?.type === "grid_row" ? (delegateRoot.modelData?.items ?? []) : [] - - Item { - id: gridCellDelegate - required property var modelData - required property int index - - readonly property real cellWidth: delegateRoot.modelData?.viewMode === "tile" ? Math.floor(delegateRoot.width / 3) : Math.floor(delegateRoot.width / (delegateRoot.modelData?.cols ?? root.gridColumns)) - - width: cellWidth - height: delegateRoot.height - - GridItem { - width: parent.width - 4 - height: parent.height - 4 - anchors.centerIn: parent - visible: delegateRoot.modelData?.viewMode === "grid" - item: gridCellDelegate.modelData?.item ?? null - isSelected: (gridCellDelegate.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex - controller: root.controller - flatIndex: gridCellDelegate.modelData?.flatIndex ?? -1 - - onClicked: { - if (root.controller && gridCellDelegate.modelData?.item) { - root.controller.executeItem(gridCellDelegate.modelData.item); - } - } - - onRightClicked: (mouseX, mouseY) => { - root.itemRightClicked(gridCellDelegate.modelData?.flatIndex ?? -1, gridCellDelegate.modelData?.item ?? null, mouseX, mouseY); - } - } - - TileItem { - width: parent.width - 4 - height: parent.height - 4 - anchors.centerIn: parent - visible: delegateRoot.modelData?.viewMode === "tile" - item: gridCellDelegate.modelData?.item ?? null - isSelected: (gridCellDelegate.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex - controller: root.controller - flatIndex: gridCellDelegate.modelData?.flatIndex ?? -1 - - onClicked: { - if (root.controller && gridCellDelegate.modelData?.item) { - root.controller.executeItem(gridCellDelegate.modelData.item); - } - } - - onRightClicked: (mouseX, mouseY) => { - root.itemRightClicked(gridCellDelegate.modelData?.flatIndex ?? -1, gridCellDelegate.modelData?.item ?? null, mouseX, mouseY); - } - } - } - } - } - } - } - - Rectangle { - id: bottomShadow - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 24 - z: 100 - visible: { - if (BlurService.enabled) - return false; - if (mainListView.contentHeight <= mainListView.height) - return false; - var atBottom = mainListView.contentY >= mainListView.contentHeight - mainListView.height + mainListView.originY - 5; - if (atBottom) - return false; - - var flatModel = root.controller?.flatModel; - if (!flatModel || flatModel.length === 0) - return false; - var lastItemIdx = -1; - for (var i = flatModel.length - 1; i >= 0; i--) { - if (!flatModel[i].isHeader) { - lastItemIdx = i; - break; - } - } - if (lastItemIdx >= 0 && root.controller?.selectedFlatIndex === lastItemIdx) - return false; - return true; - } - gradient: Gradient { - GradientStop { - position: 0.0 - color: "transparent" - } - GradientStop { - position: 1.0 - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - } - } - } - - Rectangle { - id: stickyHeader - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: 32 - z: 101 - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - visible: stickyHeaderSection !== null - - readonly property int versionTrigger: root.controller?.viewModeVersion ?? 0 - - readonly property var stickyHeaderSection: { - var scrollY = mainListView.contentY - mainListView.originY; - if (scrollY <= 0) - return null; - - var rows = root._visualRows; - var heights = root._cumulativeHeights; - if (rows.length === 0 || heights.length === 0) - return null; - - var lo = 0; - var hi = rows.length - 1; - while (lo < hi) { - var mid = (lo + hi + 1) >> 1; - if (mid < heights.length && heights[mid] <= scrollY) - lo = mid; - else - hi = mid - 1; - } - - for (var i = lo; i >= 0; i--) { - if (rows[i].type === "header") - return rows[i].section; - } - return null; - } - - SectionHeader { - width: parent.width - section: stickyHeader.stickyHeaderSection - controller: root.controller - viewMode: { - void (stickyHeader.versionTrigger); - return root.controller?.getSectionViewMode(stickyHeader.stickyHeaderSection?.id) ?? "list"; - } - canChangeViewMode: { - void (stickyHeader.versionTrigger); - return root.controller?.canChangeSectionViewMode(stickyHeader.stickyHeaderSection?.id) ?? false; - } - canCollapse: { - void (stickyHeader.versionTrigger); - return root.controller?.canCollapseSection(stickyHeader.stickyHeaderSection?.id) ?? false; - } - isSticky: true - } - } - - Item { - anchors.centerIn: parent - visible: (!root.controller?.sections || root.controller.sections.length === 0) && !root.controller?.isFileSearching - width: emptyColumn.implicitWidth - height: emptyColumn.implicitHeight - - Column { - id: emptyColumn - spacing: Theme.spacingM - - DankIcon { - anchors.horizontalCenter: parent.horizontalCenter - name: getEmptyIcon() - size: 48 - color: Theme.outlineButton - - function getEmptyIcon() { - var mode = root.controller?.searchMode ?? "all"; - switch (mode) { - case "files": - var fileType = root.controller?.fileSearchType ?? "all"; - switch (fileType) { - case "dir": - return "folder_open"; - case "file": - return "insert_drive_file"; - default: - return "folder_open"; - } - case "plugins": - return "extension"; - case "apps": - return "apps"; - default: - return "search_off"; - } - } - } - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - text: getEmptyText() - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - horizontalAlignment: Text.AlignHCenter - - function getEmptyText() { - var mode = root.controller?.searchMode ?? "all"; - var hasQuery = root.controller?.searchQuery?.length > 0; - - switch (mode) { - case "files": - if (!DSearchService.dsearchAvailable) - return I18n.tr("File search requires dsearch\nInstall from github.com/AvengeMedia/danksearch"); - if (!hasQuery) - return I18n.tr("Type to search files"); - if (root.controller.searchQuery.length < 2) - return I18n.tr("Type at least 2 characters"); - var fileType = root.controller?.fileSearchType ?? "all"; - switch (fileType) { - case "dir": - return I18n.tr("No folders found"); - case "file": - return I18n.tr("No files found"); - default: - return I18n.tr("No results found"); - } - case "plugins": - return hasQuery ? I18n.tr("No plugin results") : I18n.tr("Browse or search plugins"); - case "apps": - return I18n.tr("No apps found"); - default: - return I18n.tr("No results found"); - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js deleted file mode 100644 index 7d54df7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Scorer.js +++ /dev/null @@ -1,265 +0,0 @@ -.pragma library - -const Weights = { - exactMatch: 10000, - prefixMatch: 5000, - wordBoundary: 3000, - substring: 500, - fuzzy: 100, - frecency: 2000, - typeBonus: { - app: 1000, - plugin: 900, - file: 800, - action: 600 - } -} - -function tokenize(text) { - return text.toLowerCase().trim().split(/[\s\-_]+/).filter(function (w) { return w.length > 0 }) -} - -function hasWordBoundaryMatch(text, query) { - var textWords = tokenize(text) - var queryWords = tokenize(query) - - if (queryWords.length === 0) return false - if (queryWords.length > textWords.length) return false - - for (var i = 0; i <= textWords.length - queryWords.length; i++) { - var allMatch = true - for (var j = 0; j < queryWords.length; j++) { - if (!textWords[i + j].startsWith(queryWords[j])) { - allMatch = false - break - } - } - if (allMatch) return true - } - return false -} - -function levenshteinDistance(s1, s2) { - var len1 = s1.length - var len2 = s2.length - var prev = new Array(len2 + 1) - var curr = new Array(len2 + 1) - - for (var j = 0; j <= len2; j++) - prev[j] = j - - for (var i = 1; i <= len1; i++) { - curr[0] = i - for (var j = 1; j <= len2; j++) { - var cost = s1[i - 1] === s2[j - 1] ? 0 : 1 - curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost) - } - var tmp = prev - prev = curr - curr = tmp - } - return prev[len2] -} - -function fuzzyScore(text, query) { - var maxDistance = query.length === 3 ? 1 : query.length <= 6 ? 2 : 3 - var bestScore = 0 - - if (Math.abs(text.length - query.length) <= maxDistance) { - var distance = levenshteinDistance(text, query) - if (distance <= maxDistance) { - var maxLen = Math.max(text.length, query.length) - bestScore = 1 - (distance / maxLen) - } - } - - var words = tokenize(text) - for (var i = 0; i < words.length && bestScore < 0.8; i++) { - if (Math.abs(words[i].length - query.length) > maxDistance) continue - var wordDistance = levenshteinDistance(words[i], query) - if (wordDistance <= maxDistance) { - var wordMaxLen = Math.max(words[i].length, query.length) - var score = 1 - (wordDistance / wordMaxLen) - bestScore = Math.max(bestScore, score) - } - } - - return bestScore -} - -function getTimeBucketWeight(daysSinceUsed) { - for (var i = 0; i < TimeBuckets.length; i++) { - if (daysSinceUsed <= TimeBuckets[i].maxDays) { - return TimeBuckets[i].weight - } - } - return 10 -} - -function calculateTextScore(name, query) { - if (name === query) return Weights.exactMatch - if (name.startsWith(query)) return Weights.prefixMatch - if (hasWordBoundaryMatch(name, query)) return Weights.wordBoundary - if (name.includes(query)) return Weights.substring - - if (query.length >= 3) { - var fs = fuzzyScore(name, query) - if (fs > 0) return fs * Weights.fuzzy - } - - return 0 -} - -function score(item, query, frecencyData) { - var typeBonus = Weights.typeBonus[item.type] || 0 - - if (!query || query.length === 0) { - var usageCount = frecencyData ? frecencyData.usageCount : 0 - return typeBonus + (usageCount * 100) - } - - var name = (item.name || "").toLowerCase() - var q = query.toLowerCase() - - var textScore = calculateTextScore(name, q) - - if (textScore === 0 && item.subtitle) { - var subtitleScore = calculateTextScore(item.subtitle.toLowerCase(), q) - textScore = subtitleScore * 0.5 - } - - if (textScore === 0 && item.keywords) { - for (var i = 0; i < item.keywords.length; i++) { - var keywordScore = calculateTextScore(item.keywords[i].toLowerCase(), q) - if (keywordScore > 0) { - textScore = keywordScore * 0.3 - break - } - } - } - - if (textScore === 0) return 0 - - var usageBonus = frecencyData ? Math.min(frecencyData.usageCount * 50, Weights.frecency) : 0 - - return textScore + usageBonus + typeBonus -} - -function scoreItems(items, query, getFrecencyFn) { - var scored = [] - - for (var i = 0; i < items.length; i++) { - var item = items[i] - var itemScore - - if (item._preScored !== undefined && (query || item._preScored > 900)) { - itemScore = item._preScored - } else { - var frecencyData = getFrecencyFn ? getFrecencyFn(item) : null - itemScore = score(item, query, frecencyData) - } - - if (itemScore > 0 || !query || query.length === 0) { - scored.push({ - item: item, - score: itemScore - }) - } - } - - scored.sort(function (a, b) { - return b.score - a.score - }) - - return scored -} - -function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSection) { - var sections = {} - var result = [] - var limit = maxPerSection || 50 - - for (var i = 0; i < sectionOrder.length; i++) { - var sectionId = sectionOrder[i].id - sections[sectionId] = { - id: sectionId, - title: sectionOrder[i].title, - icon: sectionOrder[i].icon, - priority: sectionOrder[i].priority, - items: [], - collapsed: false, - flatStartIndex: 0 - } - } - - for (var i = 0; i < scoredItems.length; i++) { - var scoredItem = scoredItems[i] - var item = scoredItem.item - var sectionId = item.section || "apps" - - if (sections[sectionId] && sections[sectionId].items.length < limit) { - sections[sectionId].items.push(item) - } else if (sections["apps"] && sections["apps"].items.length < limit) { - sections["apps"].items.push(item) - } - } - - for (var i = 0; i < sectionOrder.length; i++) { - var section = sections[sectionOrder[i].id] - if (section && section.items.length > 0) { - if (sortAlphabetically && section.id === "apps") { - section.items.sort(function (a, b) { - return (a.name || "").localeCompare(b.name || "") - }) - } - result.push(section) - } - } - - return result -} - -function flattenSections(sections) { - var flat = [] - flat._sectionBounds = null - var bounds = {} - - for (var i = 0; i < sections.length; i++) { - var section = sections[i] - - flat.push({ - isHeader: true, - section: section, - sectionId: section.id, - sectionIndex: i - }) - - var itemStart = flat.length - section.flatStartIndex = itemStart - - if (!section.collapsed) { - for (var j = 0; j < section.items.length; j++) { - flat.push({ - isHeader: false, - item: section.items[j], - sectionId: section.id, - sectionIndex: i, - indexInSection: j - }) - } - } - - var itemEnd = flat.length - 1 - var itemCount = flat.length - itemStart - if (itemCount > 0) { - bounds[section.id] = { - start: itemStart, - end: itemEnd, - count: itemCount - } - } - } - - flat._sectionBounds = bounds - return flat -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml deleted file mode 100644 index aba4c2f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/Section.qml +++ /dev/null @@ -1,114 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import qs.Common - -Item { - id: root - - property var section: null - property var controller: null - property string viewMode: "list" - property int gridColumns: 4 - property int startIndex: 0 - - signal itemClicked(int flatIndex) - signal itemRightClicked(int flatIndex, var item, real mouseX, real mouseY) - - height: headerItem.height + (section?.collapsed ? 0 : contentLoader.height + Theme.spacingXS) - width: parent?.width ?? 200 - - SectionHeader { - id: headerItem - width: parent.width - section: root.section - controller: root.controller - viewMode: root.viewMode - canChangeViewMode: root.controller?.canChangeSectionViewMode(root.section?.id) ?? true - - onViewModeToggled: { - if (root.controller && root.section) { - var newMode = root.viewMode === "list" ? "grid" : "list"; - root.controller.setSectionViewMode(root.section.id, newMode); - } - } - } - - Loader { - id: contentLoader - anchors.top: headerItem.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.topMargin: Theme.spacingXS - active: !root.section?.collapsed - visible: active - - sourceComponent: root.viewMode === "grid" ? gridComponent : listComponent - - Component { - id: listComponent - - Column { - spacing: 2 - width: contentLoader.width - - Repeater { - model: ScriptModel { - values: root.section?.items ?? [] - objectProp: "id" - } - - ResultItem { - required property var modelData - required property int index - - width: parent?.width ?? 200 - item: modelData - isSelected: (root.startIndex + index) === root.controller?.selectedFlatIndex - controller: root.controller - flatIndex: root.startIndex + index - - onClicked: root.itemClicked(root.startIndex + index) - onRightClicked: (mouseX, mouseY) => { - root.itemRightClicked(root.startIndex + index, modelData, mouseX, mouseY); - } - } - } - } - } - - Component { - id: gridComponent - - Flow { - width: contentLoader.width - spacing: 4 - - Repeater { - model: ScriptModel { - values: root.section?.items ?? [] - objectProp: "id" - } - - GridItem { - required property var modelData - required property int index - - width: Math.floor(contentLoader.width / root.gridColumns) - height: width + 24 - item: modelData - isSelected: (root.startIndex + index) === root.controller?.selectedFlatIndex - controller: root.controller - flatIndex: root.startIndex + index - - onClicked: root.itemClicked(root.startIndex + index) - onRightClicked: (mouseX, mouseY) => { - root.itemRightClicked(root.startIndex + index, modelData, mouseX, mouseY); - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml deleted file mode 100644 index ee366c7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/SectionHeader.qml +++ /dev/null @@ -1,340 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Controls -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - property var section: null - property var controller: null - property string viewMode: "list" - property bool canChangeViewMode: true - property bool canCollapse: true - property bool isSticky: false - - signal viewModeToggled - - width: parent?.width ?? 200 - height: 32 - color: isSticky ? "transparent" : (hoverArea.containsMouse ? Theme.surfaceHover : "transparent") - radius: Theme.cornerRadius - - MouseArea { - id: hoverArea - anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.NoButton - } - - Row { - id: leftContent - anchors.left: parent.left - anchors.leftMargin: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - // Whether the apps category picker should replace the plain title - readonly property bool hasAppCategories: root.section?.id === "apps" && (root.controller?.appCategories?.length ?? 0) > 0 - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - // Hide section icon when the category chip already shows one - visible: !leftContent.hasAppCategories - name: root.section?.icon ?? "folder" - size: 16 - color: Theme.surfaceVariantText - } - - // Plain title — hidden when the category chip is shown - StyledText { - anchors.verticalCenter: parent.verticalCenter - visible: !leftContent.hasAppCategories - text: root.section?.title ?? "" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceVariantText - } - - // Compact inline category chip — only visible on the apps section - Item { - id: categoryChip - visible: leftContent.hasAppCategories - anchors.verticalCenter: parent.verticalCenter - // Size to content with a fixed-min width so it doesn't jump around - width: chipRow.implicitWidth + Theme.spacingM * 2 - height: 24 - - readonly property string currentCategory: root.controller?.appCategory || (root.controller?.appCategories?.length > 0 ? root.controller.appCategories[0] : "") - readonly property var iconMap: { - const cats = root.controller?.appCategories ?? []; - const m = {}; - cats.forEach(c => { m[c] = AppSearchService.getCategoryIcon(c); }); - return m; - } - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: chipArea.containsMouse || categoryPopup.visible ? Theme.surfaceContainerHigh : "transparent" - border.color: categoryPopup.visible ? Theme.primary : Theme.outlineMedium - border.width: categoryPopup.visible ? 2 : 1 - } - - Row { - id: chipRow - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: categoryChip.iconMap[categoryChip.currentCategory] ?? "apps" - size: 14 - color: Theme.surfaceText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: categoryChip.currentCategory - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - } - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: categoryPopup.visible ? "expand_less" : "expand_more" - size: 14 - color: Theme.surfaceVariantText - } - } - - MouseArea { - id: chipArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (categoryPopup.visible) { - categoryPopup.close(); - } else { - const pos = categoryChip.mapToItem(Overlay.overlay, 0, 0); - categoryPopup.x = pos.x; - categoryPopup.y = pos.y + categoryChip.height + 4; - categoryPopup.open(); - } - } - } - - Popup { - id: categoryPopup - parent: Overlay.overlay - width: Math.max(categoryChip.width, 180) - padding: 0 - modal: true - dim: false - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - - background: Rectangle { color: "transparent" } - - contentItem: Rectangle { - radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1) - border.color: Theme.primary - border.width: 2 - - ElevationShadow { - anchors.fill: parent - z: -1 - level: Theme.elevationLevel2 - fallbackOffset: 4 - targetRadius: parent.radius - targetColor: parent.color - borderColor: parent.border.color - borderWidth: parent.border.width - shadowEnabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled - } - - ListView { - id: categoryList - anchors.fill: parent - anchors.margins: Theme.spacingS - model: root.controller?.appCategories ?? [] - spacing: 2 - clip: true - interactive: contentHeight > height - implicitHeight: contentHeight - - delegate: Rectangle { - id: catDelegate - required property string modelData - required property int index - width: categoryList.width - height: 32 - radius: Theme.cornerRadius - readonly property bool isCurrent: categoryChip.currentCategory === modelData - color: isCurrent ? Theme.primaryHover : catArea.containsMouse ? Theme.primaryHoverLight : "transparent" - - Row { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - spacing: Theme.spacingS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: categoryChip.iconMap[catDelegate.modelData] ?? "apps" - size: 16 - color: catDelegate.isCurrent ? Theme.primary : Theme.surfaceText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: catDelegate.modelData - font.pixelSize: Theme.fontSizeMedium - color: catDelegate.isCurrent ? Theme.primary : Theme.surfaceText - font.weight: catDelegate.isCurrent ? Font.Medium : Font.Normal - } - } - - MouseArea { - id: catArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (root.controller) - root.controller.setAppCategory(catDelegate.modelData); - categoryPopup.close(); - } - } - } - } - } - - // Size to list content, cap at 10 visible items - height: Math.min((root.controller?.appCategories?.length ?? 0) * 34, 10 * 34) + Theme.spacingS * 2 + 4 - } - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: root.section?.items?.length ?? 0 - font.pixelSize: Theme.fontSizeSmall - color: Theme.outlineButton - } - } - - Row { - id: rightContent - anchors.right: parent.right - anchors.rightMargin: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Row { - id: viewModeRow - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - visible: root.canChangeViewMode && !root.section?.collapsed - - Repeater { - model: [ - { - mode: "list", - icon: "view_list" - }, - { - mode: "grid", - icon: "grid_view" - }, - { - mode: "tile", - icon: "view_module" - } - ] - - Rectangle { - required property var modelData - required property int index - - width: 20 - height: 20 - radius: 4 - color: root.viewMode === modelData.mode ? Theme.primaryHover : modeArea.containsMouse ? Theme.surfaceHover : "transparent" - - DankIcon { - anchors.centerIn: parent - name: parent.modelData.icon - size: 14 - color: root.viewMode === parent.modelData.mode ? Theme.primary : Theme.surfaceVariantText - } - - MouseArea { - id: modeArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (root.viewMode !== parent.modelData.mode && root.controller && root.section) { - root.controller.setSectionViewMode(root.section.id, parent.modelData.mode); - } - } - } - } - } - } - - Item { - id: collapseButton - width: root.canCollapse ? 24 : 0 - height: 24 - visible: root.canCollapse - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: root.section?.collapsed ? "expand_more" : "expand_less" - size: 16 - color: collapseArea.containsMouse ? Theme.primary : Theme.surfaceVariantText - } - - MouseArea { - id: collapseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (root.controller && root.section) { - root.controller.toggleSection(root.section.id); - } - } - } - } - } - - MouseArea { - anchors.fill: parent - anchors.rightMargin: rightContent.width + Theme.spacingS - cursorShape: root.canCollapse ? Qt.PointingHandCursor : Qt.ArrowCursor - enabled: root.canCollapse - onClicked: { - if (root.canCollapse && root.controller && root.section) { - root.controller.toggleSection(root.section.id); - } - } - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: 1 - color: Theme.outlineMedium - visible: root.isSticky - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml deleted file mode 100644 index 0b48802..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DankLauncherV2/TileItem.qml +++ /dev/null @@ -1,199 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell.Wayland -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - property var item: null - property bool isSelected: false - property bool isHovered: itemArea.containsMouse - property var controller: null - property int flatIndex: -1 - - signal clicked - signal rightClicked(real mouseX, real mouseY) - - radius: Theme.cornerRadius - color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent" - border.width: isSelected ? 2 : 0 - border.color: Theme.primary - - readonly property string toplevelId: item?.data?.toplevelId ?? "" - readonly property var waylandToplevel: { - if (!toplevelId || !item?.pluginId) - return null; - const pluginInstance = PluginService.pluginInstances[item.pluginId]; - if (!pluginInstance?.getToplevelById) - return null; - return pluginInstance.getToplevelById(toplevelId); - } - readonly property bool hasScreencopy: waylandToplevel !== null - - readonly property string iconValue: { - if (!item) - return ""; - if (hasScreencopy) - return ""; - var data = item.data; - if (data?.imageUrl) - return "image:" + data.imageUrl; - if (data?.imagePath) - return "image:" + data.imagePath; - if (data?.path && isImageFile(data.path)) - return "image:" + data.path; - switch (item.iconType) { - case "material": - case "nerd": - return "material:" + (item.icon || "image"); - case "unicode": - return "unicode:" + (item.icon || ""); - case "composite": - return item.iconFull || ""; - case "image": - default: - return item.icon || ""; - } - } - - function isImageFile(path) { - if (!path) - return false; - var ext = path.split('.').pop().toLowerCase(); - return ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "jxl", "avif", "heif", "exr"].indexOf(ext) >= 0; - } - - DankRipple { - id: rippleLayer - rippleColor: Theme.surfaceText - cornerRadius: root.radius - } - - Item { - anchors.fill: parent - anchors.margins: 4 - - Rectangle { - id: imageContainer - anchors.fill: parent - radius: Theme.cornerRadius - 2 - color: Theme.surfaceContainerHigh - clip: true - - ScreencopyView { - id: screencopyView - anchors.fill: parent - captureSource: root.waylandToplevel - live: root.hasScreencopy - visible: root.hasScreencopy - - Rectangle { - anchors.fill: parent - color: root.isHovered ? Theme.withAlpha(Theme.surfaceVariant, 0.2) : "transparent" - } - } - - AppIconRenderer { - anchors.fill: parent - iconValue: root.iconValue - iconSize: Math.min(parent.width, parent.height) - fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?" - materialIconSizeAdjustment: iconSize * 0.3 - visible: !root.hasScreencopy - } - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: labelText.implicitHeight + Theme.spacingS * 2 - color: Theme.withAlpha(Theme.surfaceContainer, 0.85) - visible: root.item?.name?.length > 0 - - Text { - id: labelText - anchors.fill: parent - anchors.margins: Theme.spacingXS - text: root.item?._hName ?? root.item?.name ?? "" - textFormat: root.item?._hRich ? Text.RichText : Text.PlainText - font.pixelSize: Theme.fontSizeSmall - font.family: Theme.fontFamily - color: Theme.surfaceText - elide: Text.ElideRight - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - } - } - - Rectangle { - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: Theme.spacingXS - width: 20 - height: 20 - radius: 10 - color: Theme.primary - visible: root.isSelected - - DankIcon { - anchors.centerIn: parent - name: "check" - size: 14 - color: Theme.primaryText - } - } - - Rectangle { - id: attributionBadge - anchors.top: parent.top - anchors.left: parent.left - anchors.margins: Theme.spacingXS - width: root.hasScreencopy ? 28 : 40 - height: root.hasScreencopy ? 28 : 16 - radius: root.hasScreencopy ? 14 : 4 - color: root.hasScreencopy ? Theme.surfaceContainer : "transparent" - visible: attributionImage.status === Image.Ready - opacity: 0.95 - - Image { - id: attributionImage - anchors.fill: parent - anchors.margins: root.hasScreencopy ? 4 : 0 - fillMode: Image.PreserveAspectFit - source: root.item?.data?.attribution || "" - mipmap: true - } - } - } - } - - MouseArea { - id: itemArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onPressed: mouse => { - if (mouse.button === Qt.LeftButton) - rippleLayer.trigger(mouse.x, mouse.y); - } - onClicked: mouse => { - if (mouse.button === Qt.RightButton) { - var scenePos = mapToItem(null, mouse.x, mouse.y); - root.rightClicked(scenePos.x, scenePos.y); - return; - } - root.clicked(); - } - - onPositionChanged: { - if (root.controller) - root.controller.keyboardNavigationActive = false; - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml deleted file mode 100644 index f8a97de..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/DisplayConfirmationModal.qml +++ /dev/null @@ -1,212 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modals.Common -import qs.Widgets - -DankModal { - id: root - - property string outputName: "" - property var changes: [] - property int countdown: 10 - - signal confirmed - signal reverted - - shouldBeVisible: false - allowStacking: true - modalWidth: 420 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 200 - - Timer { - id: countdownTimer - interval: 1000 - repeat: true - running: root.shouldBeVisible - onTriggered: { - root.countdown--; - if (root.countdown <= 0) { - root.reverted(); - root.close(); - } - } - } - - onOpened: { - countdown = 10; - countdownTimer.start(); - } - - onDialogClosed: { - countdownTimer.stop(); - } - - onBackgroundClicked: { - root.reverted(); - root.close(); - } - - content: Component { - FocusScope { - id: confirmContent - - anchors.fill: parent - focus: true - implicitHeight: mainColumn.implicitHeight - - Keys.onEscapePressed: event => { - root.reverted(); - root.close(); - event.accepted = true; - } - - Keys.onReturnPressed: event => { - root.confirmed(); - root.close(); - event.accepted = true; - } - - Column { - id: mainColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingM - spacing: Theme.spacingM - - StyledText { - text: I18n.tr("Confirm Display Changes") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - Rectangle { - width: parent.width - height: 70 - radius: Theme.cornerRadius - color: Theme.surfaceContainerHighest - - StyledText { - anchors.centerIn: parent - text: root.countdown + "s" - font.pixelSize: Theme.fontSizeXLarge * 1.5 - color: Theme.primary - font.weight: Font.Bold - } - } - - Column { - width: parent.width - spacing: Theme.spacingXS - visible: root.changes.length > 0 - - Repeater { - model: root.changes - - StyledText { - required property var modelData - text: modelData - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - } - - Item { - width: parent.width - height: 36 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Rectangle { - width: Math.max(70, revertText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: revertArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - - StyledText { - id: revertText - - anchors.centerIn: parent - text: I18n.tr("Revert") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: revertArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - root.reverted(); - root.close(); - } - } - } - - Rectangle { - width: Math.max(80, confirmText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: confirmArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - - StyledText { - id: confirmText - - anchors.centerIn: parent - text: I18n.tr("Keep Changes") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: confirmArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - root.confirmed(); - root.close(); - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - - DankActionButton { - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: { - root.reverted(); - root.close(); - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml deleted file mode 100644 index 8b96742..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserContent.qml +++ /dev/null @@ -1,920 +0,0 @@ -import Qt.labs.folderlistmodel -import QtCore -import QtQuick -import QtQuick.Controls -import qs.Common -import qs.Widgets - -FocusScope { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string homeDir: StandardPaths.writableLocation(StandardPaths.HomeLocation) - property string docsDir: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) - property string musicDir: StandardPaths.writableLocation(StandardPaths.MusicLocation) - property string videosDir: StandardPaths.writableLocation(StandardPaths.MoviesLocation) - property string picsDir: StandardPaths.writableLocation(StandardPaths.PicturesLocation) - property string downloadDir: StandardPaths.writableLocation(StandardPaths.DownloadLocation) - property string desktopDir: StandardPaths.writableLocation(StandardPaths.DesktopLocation) - property string currentPath: "" - property var fileExtensions: ["*.*"] - property alias filterExtensions: root.fileExtensions - property string browserTitle: "Select File" - property string browserIcon: "folder_open" - property string browserType: "generic" - property bool showHiddenFiles: false - property int selectedIndex: -1 - property bool keyboardNavigationActive: false - property bool backButtonFocused: false - property bool saveMode: false - property string defaultFileName: "" - property int keyboardSelectionIndex: -1 - property bool keyboardSelectionRequested: false - property bool showKeyboardHints: false - property bool showFileInfo: false - property string selectedFilePath: "" - property string selectedFileName: "" - property bool selectedFileIsDir: false - property bool showOverwriteConfirmation: false - property string pendingFilePath: "" - property bool showSidebar: true - property string viewMode: "grid" - property string sortBy: "name" - property bool sortAscending: true - property int iconSizeIndex: 1 - property var iconSizes: [80, 120, 160, 200] - property bool pathEditMode: false - property bool pathInputHasFocus: false - property int actualGridColumns: 5 - property bool _initialized: false - property bool closeOnEscape: true - property var windowControls: null - - signal fileSelected(string path) - signal closeRequested - - function encodeFileUrl(path) { - if (!path) - return ""; - return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/'); - } - - function initialize() { - loadSettings(); - currentPath = getLastPath(); - _initialized = true; - } - - function reset() { - currentPath = getLastPath(); - selectedIndex = -1; - keyboardNavigationActive = false; - backButtonFocused = false; - } - - function loadSettings() { - const type = browserType || "default"; - const settings = CacheData.fileBrowserSettings[type]; - const isImageBrowser = ["wallpaper", "profile"].includes(browserType); - - if (settings) { - viewMode = settings.viewMode || (isImageBrowser ? "grid" : "list"); - sortBy = settings.sortBy || "name"; - sortAscending = settings.sortAscending !== undefined ? settings.sortAscending : true; - iconSizeIndex = settings.iconSizeIndex !== undefined ? settings.iconSizeIndex : 1; - showSidebar = settings.showSidebar !== undefined ? settings.showSidebar : true; - } else { - viewMode = isImageBrowser ? "grid" : "list"; - } - } - - function saveSettings() { - if (!_initialized) - return; - const type = browserType || "default"; - let settings = CacheData.fileBrowserSettings; - if (!settings[type]) { - settings[type] = {}; - } - settings[type].viewMode = viewMode; - settings[type].sortBy = sortBy; - settings[type].sortAscending = sortAscending; - settings[type].iconSizeIndex = iconSizeIndex; - settings[type].showSidebar = showSidebar; - settings[type].lastPath = currentPath; - CacheData.fileBrowserSettings = settings; - - if (browserType === "wallpaper") { - CacheData.wallpaperLastPath = currentPath; - } else if (browserType === "profile") { - CacheData.profileLastPath = currentPath; - } - - CacheData.saveCache(); - } - - onViewModeChanged: saveSettings() - onSortByChanged: saveSettings() - onSortAscendingChanged: saveSettings() - onIconSizeIndexChanged: saveSettings() - onShowSidebarChanged: saveSettings() - - function isImageFile(fileName) { - if (!fileName) - return false; - const ext = fileName.toLowerCase().split('.').pop(); - return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext); - } - - function getLastPath() { - const type = browserType || "default"; - const settings = CacheData.fileBrowserSettings[type]; - const lastPath = settings?.lastPath || ""; - return (lastPath && lastPath !== "") ? lastPath : homeDir; - } - - function saveLastPath(path) { - const type = browserType || "default"; - let settings = CacheData.fileBrowserSettings; - if (!settings[type]) { - settings[type] = {}; - } - settings[type].lastPath = path; - CacheData.fileBrowserSettings = settings; - CacheData.saveCache(); - - if (browserType === "wallpaper") { - CacheData.wallpaperLastPath = path; - } else if (browserType === "profile") { - CacheData.profileLastPath = path; - } - } - - function setSelectedFileData(path, name, isDir) { - selectedFilePath = path; - selectedFileName = name; - selectedFileIsDir = isDir; - } - - function navigateUp() { - const path = currentPath; - if (path === homeDir) - return; - const lastSlash = path.lastIndexOf('/'); - if (lastSlash <= 0) - return; - const newPath = path.substring(0, lastSlash); - if (newPath.length < homeDir.length) { - currentPath = homeDir; - saveLastPath(homeDir); - } else { - currentPath = newPath; - saveLastPath(newPath); - } - } - - function navigateTo(path) { - currentPath = path; - saveLastPath(path); - selectedIndex = -1; - backButtonFocused = false; - } - - function keyboardFileSelection(index) { - if (index < 0) - return; - keyboardSelectionTimer.targetIndex = index; - keyboardSelectionTimer.start(); - } - - function executeKeyboardSelection(index) { - keyboardSelectionIndex = index; - keyboardSelectionRequested = true; - } - - function handleSaveFile(filePath) { - var normalizedPath = filePath; - if (!normalizedPath.startsWith("file://")) { - normalizedPath = encodeFileUrl(filePath); - } - - var exists = false; - var fileName = filePath.split('/').pop(); - - for (var i = 0; i < folderModel.count; i++) { - if (folderModel.get(i, "fileName") === fileName && !folderModel.get(i, "fileIsDir")) { - exists = true; - break; - } - } - - if (exists) { - pendingFilePath = normalizedPath; - showOverwriteConfirmation = true; - } else { - fileSelected(normalizedPath); - closeRequested(); - } - } - - onCurrentPathChanged: { - selectedFilePath = ""; - selectedFileName = ""; - selectedFileIsDir = false; - saveSettings(); - } - - onSelectedIndexChanged: { - if (selectedIndex >= 0 && folderModel && selectedIndex < folderModel.count) { - selectedFilePath = ""; - selectedFileName = ""; - selectedFileIsDir = false; - } - } - - property var steamPaths: [StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.steam/steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.local/share/Steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/snap/steam/common/.local/share/Steam/steamapps/workshop/content/431960"] - - property var quickAccessLocations: [ - { - "name": I18n.tr("Home"), - "path": homeDir, - "icon": "home" - }, - { - "name": I18n.tr("Documents"), - "path": docsDir, - "icon": "description" - }, - { - "name": I18n.tr("Downloads"), - "path": downloadDir, - "icon": "download" - }, - { - "name": I18n.tr("Pictures"), - "path": picsDir, - "icon": "image" - }, - { - "name": I18n.tr("Music"), - "path": musicDir, - "icon": "music_note" - }, - { - "name": I18n.tr("Videos"), - "path": videosDir, - "icon": "movie" - }, - { - "name": I18n.tr("Desktop"), - "path": desktopDir, - "icon": "computer" - } - ] - - FolderListModel { - id: folderModel - - showDirsFirst: true - showDotAndDotDot: false - showHidden: root.showHiddenFiles - caseSensitive: false - nameFilters: fileExtensions - showFiles: true - showDirs: true - folder: encodeFileUrl(currentPath || homeDir) - sortField: { - switch (sortBy) { - case "name": - return FolderListModel.Name; - case "size": - return FolderListModel.Size; - case "modified": - return FolderListModel.Time; - case "type": - return FolderListModel.Type; - default: - return FolderListModel.Name; - } - } - sortReversed: !sortAscending - } - - QtObject { - id: keyboardController - - property int totalItems: folderModel.count - property int gridColumns: viewMode === "list" ? 1 : Math.max(1, actualGridColumns) - - function handleKey(event) { - if (event.key === Qt.Key_Escape && root.closeOnEscape) { - closeRequested(); - event.accepted = true; - return; - } - if (event.key === Qt.Key_F10) { - showKeyboardHints = !showKeyboardHints; - event.accepted = true; - return; - } - if (event.key === Qt.Key_F1 || event.key === Qt.Key_I) { - showFileInfo = !showFileInfo; - event.accepted = true; - return; - } - if ((event.modifiers & Qt.AltModifier && event.key === Qt.Key_Left) || event.key === Qt.Key_Backspace) { - if (currentPath !== homeDir) { - navigateUp(); - event.accepted = true; - } - return; - } - if (!keyboardNavigationActive) { - const isInitKey = event.key === Qt.Key_Tab || event.key === Qt.Key_Down || event.key === Qt.Key_Right || (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) || (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) || (event.key === Qt.Key_L && event.modifiers & Qt.ControlModifier); - - if (isInitKey) { - keyboardNavigationActive = true; - if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } else { - backButtonFocused = false; - selectedIndex = 0; - } - event.accepted = true; - } - return; - } - switch (event.key) { - case Qt.Key_Tab: - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = 0; - } else if (selectedIndex < totalItems - 1) { - selectedIndex++; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } else { - selectedIndex = 0; - } - event.accepted = true; - break; - case Qt.Key_Backtab: - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = totalItems - 1; - } else if (selectedIndex > 0) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } else { - selectedIndex = totalItems - 1; - } - event.accepted = true; - break; - case Qt.Key_N: - if (event.modifiers & Qt.ControlModifier) { - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = 0; - } else if (selectedIndex < totalItems - 1) { - selectedIndex++; - } - event.accepted = true; - } - break; - case Qt.Key_P: - if (event.modifiers & Qt.ControlModifier) { - if (selectedIndex > 0) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } - event.accepted = true; - } - break; - case Qt.Key_J: - if (event.modifiers & Qt.ControlModifier) { - if (selectedIndex < totalItems - 1) { - selectedIndex++; - } - event.accepted = true; - } - break; - case Qt.Key_K: - if (event.modifiers & Qt.ControlModifier) { - if (selectedIndex > 0) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } - event.accepted = true; - } - break; - case Qt.Key_H: - if (event.modifiers & Qt.ControlModifier) { - if (!backButtonFocused && selectedIndex > 0) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } - event.accepted = true; - } - break; - case Qt.Key_L: - if (event.modifiers & Qt.ControlModifier) { - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = 0; - } else if (selectedIndex < totalItems - 1) { - selectedIndex++; - } - event.accepted = true; - } - break; - case Qt.Key_Left: - if (pathInputHasFocus) - return; - if (backButtonFocused) - return; - if (selectedIndex > 0) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } - event.accepted = true; - break; - case Qt.Key_Right: - if (pathInputHasFocus) - return; - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = 0; - } else if (selectedIndex < totalItems - 1) { - selectedIndex++; - } - event.accepted = true; - break; - case Qt.Key_Up: - if (backButtonFocused) { - backButtonFocused = false; - if (gridColumns === 1) { - selectedIndex = 0; - } else { - var col = selectedIndex % gridColumns; - selectedIndex = Math.min(col, totalItems - 1); - } - } else if (selectedIndex >= gridColumns) { - selectedIndex -= gridColumns; - } else if (selectedIndex > 0 && gridColumns === 1) { - selectedIndex--; - } else if (currentPath !== homeDir) { - backButtonFocused = true; - selectedIndex = -1; - } - event.accepted = true; - break; - case Qt.Key_Down: - if (backButtonFocused) { - backButtonFocused = false; - selectedIndex = 0; - } else if (gridColumns === 1) { - if (selectedIndex < totalItems - 1) { - selectedIndex++; - } - } else { - var newIndex = selectedIndex + gridColumns; - if (newIndex < totalItems) { - selectedIndex = newIndex; - } else { - var lastRowStart = Math.floor((totalItems - 1) / gridColumns) * gridColumns; - var col = selectedIndex % gridColumns; - var targetIndex = lastRowStart + col; - if (targetIndex < totalItems && targetIndex > selectedIndex) { - selectedIndex = targetIndex; - } - } - } - event.accepted = true; - break; - case Qt.Key_Return: - case Qt.Key_Enter: - case Qt.Key_Space: - if (backButtonFocused) { - navigateUp(); - } else if (selectedIndex >= 0 && selectedIndex < totalItems) { - root.keyboardFileSelection(selectedIndex); - } - event.accepted = true; - break; - } - } - } - - Timer { - id: keyboardSelectionTimer - - property int targetIndex: -1 - - interval: 1 - onTriggered: { - executeKeyboardSelection(targetIndex); - } - } - - focus: true - - Keys.onPressed: event => { - keyboardController.handleKey(event); - } - - Column { - anchors.fill: parent - spacing: 0 - - Item { - width: parent.width - height: 48 - - MouseArea { - anchors.fill: parent - onPressed: if (windowControls) - windowControls.tryStartMove() - onDoubleClicked: if (windowControls) - windowControls.tryToggleMaximize() - } - - Row { - spacing: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: Theme.spacingL - - DankIcon { - name: browserIcon - size: Theme.iconSizeLarge - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: browserTitle - font.pixelSize: Theme.fontSizeXLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - DankActionButton { - circular: false - iconName: showHiddenFiles ? "visibility_off" : "visibility" - iconSize: Theme.iconSize - 4 - iconColor: showHiddenFiles ? Theme.primary : Theme.surfaceText - onClicked: showHiddenFiles = !showHiddenFiles - } - - DankActionButton { - circular: false - iconName: viewMode === "grid" ? "view_list" : "grid_view" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: viewMode = viewMode === "grid" ? "list" : "grid" - } - - DankActionButton { - circular: false - iconName: iconSizeIndex === 0 ? "photo_size_select_small" : iconSizeIndex === 1 ? "photo_size_select_large" : iconSizeIndex === 2 ? "photo_size_select_actual" : "zoom_in" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - visible: viewMode === "grid" - onClicked: iconSizeIndex = (iconSizeIndex + 1) % iconSizes.length - } - - DankActionButton { - circular: false - iconName: "info" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.showKeyboardHints = !root.showKeyboardHints - } - - DankActionButton { - visible: windowControls?.supported ?? false - circular: false - iconName: windowControls?.targetWindow?.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: if (windowControls) - windowControls.tryToggleMaximize() - } - - DankActionButton { - circular: false - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.closeRequested() - } - } - } - - StyledRect { - width: parent.width - height: 1 - color: Theme.outline - } - - Item { - width: parent.width - height: parent.height - 49 - - Row { - anchors.fill: parent - spacing: 0 - - Row { - width: showSidebar ? 201 : 0 - height: parent.height - spacing: 0 - visible: showSidebar - - FileBrowserSidebar { - height: parent.height - quickAccessLocations: root.quickAccessLocations - currentPath: root.currentPath - onLocationSelected: path => navigateTo(path) - } - - StyledRect { - width: 1 - height: parent.height - color: Theme.outline - } - } - - Column { - width: parent.width - (showSidebar ? 201 : 0) - height: parent.height - spacing: 0 - - FileBrowserNavigation { - width: parent.width - currentPath: root.currentPath - homeDir: root.homeDir - backButtonFocused: root.backButtonFocused - keyboardNavigationActive: root.keyboardNavigationActive - showSidebar: root.showSidebar - pathEditMode: root.pathEditMode - onNavigateUp: root.navigateUp() - onNavigateTo: path => root.navigateTo(path) - onPathInputFocusChanged: hasFocus => { - root.pathInputHasFocus = hasFocus; - if (hasFocus) { - root.pathEditMode = true; - } - } - } - - StyledRect { - width: parent.width - height: 1 - color: Theme.outline - } - - Item { - id: gridContainer - width: parent.width - height: parent.height - 41 - clip: true - - property real gridCellWidth: iconSizes[iconSizeIndex] + 24 - property real gridCellHeight: iconSizes[iconSizeIndex] + 56 - property real availableGridWidth: width - Theme.spacingM * 2 - property int gridColumns: Math.max(1, Math.floor(availableGridWidth / gridCellWidth)) - property real gridLeftMargin: Theme.spacingM + Math.max(0, (availableGridWidth - (gridColumns * gridCellWidth)) / 2) - - onGridColumnsChanged: { - root.actualGridColumns = gridColumns; - } - Component.onCompleted: { - root.actualGridColumns = gridColumns; - } - - DankGridView { - id: fileGrid - anchors.fill: parent - anchors.leftMargin: gridContainer.gridLeftMargin - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS - visible: viewMode === "grid" - cellWidth: gridContainer.gridCellWidth - cellHeight: gridContainer.gridCellHeight - cacheBuffer: 260 - model: folderModel - currentIndex: selectedIndex - onCurrentIndexChanged: { - if (keyboardNavigationActive && currentIndex >= 0) - positionViewAtIndex(currentIndex, GridView.Contain); - } - - ScrollBar.vertical: DankScrollbar { - id: gridScrollbar - } - - ScrollBar.horizontal: DankScrollbar { - policy: ScrollBar.AlwaysOff - } - - delegate: FileBrowserGridDelegate { - iconSizes: root.iconSizes - iconSizeIndex: root.iconSizeIndex - selectedIndex: root.selectedIndex - keyboardNavigationActive: root.keyboardNavigationActive - onItemClicked: (index, path, name, isDir) => { - selectedIndex = index; - setSelectedFileData(path, name, isDir); - if (isDir) { - navigateTo(path); - } else { - fileSelected(path); - root.closeRequested(); - } - } - onItemSelected: (index, path, name, isDir) => { - setSelectedFileData(path, name, isDir); - } - - Connections { - function onKeyboardSelectionRequestedChanged() { - if (root.keyboardSelectionRequested && root.keyboardSelectionIndex === index) { - root.keyboardSelectionRequested = false; - selectedIndex = index; - setSelectedFileData(filePath, fileName, fileIsDir); - if (fileIsDir) { - navigateTo(filePath); - } else { - fileSelected(filePath); - root.closeRequested(); - } - } - } - - target: root - } - } - } - - DankListView { - id: fileList - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS - visible: viewMode === "list" - spacing: 2 - model: folderModel - currentIndex: selectedIndex - onCurrentIndexChanged: { - if (keyboardNavigationActive && currentIndex >= 0) - positionViewAtIndex(currentIndex, ListView.Contain); - } - - ScrollBar.vertical: DankScrollbar { - id: listScrollbar - } - - delegate: FileBrowserListDelegate { - width: fileList.width - selectedIndex: root.selectedIndex - keyboardNavigationActive: root.keyboardNavigationActive - onItemClicked: (index, path, name, isDir) => { - selectedIndex = index; - setSelectedFileData(path, name, isDir); - if (isDir) { - navigateTo(path); - } else { - fileSelected(path); - root.closeRequested(); - } - } - onItemSelected: (index, path, name, isDir) => { - setSelectedFileData(path, name, isDir); - } - - Connections { - function onKeyboardSelectionRequestedChanged() { - if (root.keyboardSelectionRequested && root.keyboardSelectionIndex === index) { - root.keyboardSelectionRequested = false; - selectedIndex = index; - setSelectedFileData(filePath, fileName, fileIsDir); - if (fileIsDir) { - navigateTo(filePath); - } else { - fileSelected(filePath); - root.closeRequested(); - } - } - } - - target: root - } - } - } - } - } - } - - FileBrowserSaveRow { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingL - saveMode: root.saveMode - defaultFileName: root.defaultFileName - currentPath: root.currentPath - onSaveRequested: filePath => handleSaveFile(filePath) - } - - KeyboardHints { - id: keyboardHints - - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingL - showHints: root.showKeyboardHints - } - - FileInfo { - id: fileInfo - - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: Theme.spacingL - width: 300 - showFileInfo: root.showFileInfo - selectedIndex: root.selectedIndex - sourceFolderModel: folderModel - currentPath: root.currentPath - currentFileName: root.selectedFileName - currentFileIsDir: root.selectedFileIsDir - currentFileExtension: { - if (root.selectedFileIsDir || !root.selectedFileName) - return ""; - - var lastDot = root.selectedFileName.lastIndexOf('.'); - return lastDot > 0 ? root.selectedFileName.substring(lastDot + 1).toLowerCase() : ""; - } - } - - FileBrowserSortMenu { - id: sortMenu - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: 120 - anchors.rightMargin: Theme.spacingL - sortBy: root.sortBy - sortAscending: root.sortAscending - onSortBySelected: value => { - root.sortBy = value; - } - onSortOrderSelected: ascending => { - root.sortAscending = ascending; - } - } - } - - FileBrowserOverwriteDialog { - anchors.fill: parent - showDialog: showOverwriteConfirmation - pendingFilePath: root.pendingFilePath - onConfirmed: filePath => { - showOverwriteConfirmation = false; - fileSelected(filePath); - pendingFilePath = ""; - Qt.callLater(() => root.closeRequested()); - } - onCancelled: { - showOverwriteConfirmation = false; - pendingFilePath = ""; - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml deleted file mode 100644 index effa9bd..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserGridDelegate.qml +++ /dev/null @@ -1,253 +0,0 @@ -import QtQuick -import QtQuick.Effects -import qs.Common -import qs.Widgets - -StyledRect { - id: delegateRoot - - required property bool fileIsDir - required property string filePath - required property string fileName - required property int index - - property bool weMode: false - property var iconSizes: [80, 120, 160, 200] - property int iconSizeIndex: 1 - property int selectedIndex: -1 - property bool keyboardNavigationActive: false - - signal itemClicked(int index, string path, string name, bool isDir) - signal itemSelected(int index, string path, string name, bool isDir) - - function getFileExtension(fileName) { - const parts = fileName.split('.'); - if (parts.length > 1) { - return parts[parts.length - 1].toLowerCase(); - } - return ""; - } - - function determineFileType(fileName) { - const ext = getFileExtension(fileName); - - const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico", "jxl", "avif", "heif", "exr"]; - if (imageExts.includes(ext)) { - return "image"; - } - - const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"]; - if (videoExts.includes(ext)) { - return "video"; - } - - const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"]; - if (audioExts.includes(ext)) { - return "audio"; - } - - const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"]; - if (codeExts.includes(ext)) { - return "code"; - } - - const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"]; - if (docExts.includes(ext)) { - return "document"; - } - - const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"]; - if (archiveExts.includes(ext)) { - return "archive"; - } - - if (!ext || fileName.indexOf('.') === -1) { - return "binary"; - } - - return "file"; - } - - function isImageFile(fileName) { - if (!fileName) { - return false; - } - return determineFileType(fileName) === "image"; - } - - function isVideoFile(fileName) { - if (!fileName) { - return false; - } - return determineFileType(fileName) === "video"; - } - - property bool isImage: isImageFile(delegateRoot.fileName) - property bool isVideo: isVideoFile(delegateRoot.fileName) - - property string _xdgCacheHome: Paths.strip(Paths.xdgCache) - property string _thumbnailSize: iconSizeIndex >= 2 ? "x-large" : "large" - property int _thumbnailPx: iconSizeIndex >= 2 ? 512 : 256 - property string videoThumbnailPath: { - if (!delegateRoot.fileIsDir && isVideo) { - const hash = Qt.md5("file://" + delegateRoot.filePath); - return _xdgCacheHome + "/thumbnails/" + _thumbnailSize + "/" + hash + ".png"; - } - return ""; - } - - property string _videoThumb: "" - - onVideoThumbnailPathChanged: { - _videoThumb = ""; - if (!videoThumbnailPath) - return; - const thumbPath = videoThumbnailPath; - const thumbDir = _xdgCacheHome + "/thumbnails/" + _thumbnailSize; - const size = _thumbnailPx; - const fp = delegateRoot.filePath; - Paths.mkdir(thumbDir); - Proc.runCommand(null, ["test", "-f", thumbPath], function(output, exitCode) { - if (exitCode === 0) { - _videoThumb = thumbPath; - } else { - Proc.runCommand(null, ["ffmpegthumbnailer", "-i", fp, "-o", thumbPath, "-s", String(size), "-f"], function(output, exitCode) { - if (exitCode === 0) - _videoThumb = thumbPath; - }); - } - }); - } - - function getIconForFile(fileName) { - const lowerName = fileName.toLowerCase(); - if (lowerName.startsWith("dockerfile")) { - return "docker"; - } - const ext = fileName.split('.').pop(); - return ext || ""; - } - - width: weMode ? 245 : iconSizes[iconSizeIndex] + 16 - height: weMode ? 205 : iconSizes[iconSizeIndex] + 48 - radius: Theme.cornerRadius - color: { - if (keyboardNavigationActive && delegateRoot.index === selectedIndex) - return Theme.surfacePressed; - - return mouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent"; - } - border.color: keyboardNavigationActive && delegateRoot.index === selectedIndex ? Theme.primary : "transparent" - border.width: (keyboardNavigationActive && delegateRoot.index === selectedIndex) ? 2 : 0 - - Component.onCompleted: { - if (keyboardNavigationActive && delegateRoot.index === selectedIndex) - itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir); - } - - onSelectedIndexChanged: { - if (keyboardNavigationActive && selectedIndex === delegateRoot.index) - itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir); - } - - Column { - anchors.centerIn: parent - spacing: Theme.spacingS - - Item { - width: weMode ? 225 : (iconSizes[iconSizeIndex] - 8) - height: weMode ? 165 : (iconSizes[iconSizeIndex] - 8) - anchors.horizontalCenter: parent.horizontalCenter - - Image { - id: gridPreviewImage - anchors.fill: parent - anchors.margins: 2 - property var weExtensions: [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".tga", ".jxl", ".avif", ".heif", ".exr"] - property int weExtIndex: 0 - property string imagePath: { - if (weMode && delegateRoot.fileIsDir) - return delegateRoot.filePath + "/preview" + weExtensions[weExtIndex]; - if (!delegateRoot.fileIsDir && isImage) - return delegateRoot.filePath; - if (_videoThumb) - return _videoThumb; - return ""; - } - source: imagePath ? "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/') : "" - onStatusChanged: { - if (weMode && delegateRoot.fileIsDir && status === Image.Error) { - if (weExtIndex < weExtensions.length - 1) { - weExtIndex++; - } else { - imagePath = ""; - } - } - } - fillMode: Image.PreserveAspectCrop - sourceSize.width: weMode ? 225 : iconSizes[iconSizeIndex] - sourceSize.height: weMode ? 225 : iconSizes[iconSizeIndex] - asynchronous: true - visible: false - } - - MultiEffect { - anchors.fill: parent - anchors.margins: 2 - source: gridPreviewImage - maskEnabled: true - maskSource: gridImageMask - visible: gridPreviewImage.status === Image.Ready && ((!delegateRoot.fileIsDir && (isImage || isVideo)) || (weMode && delegateRoot.fileIsDir)) - maskThresholdMin: 0.5 - maskSpreadAtMin: 1 - } - - Item { - id: gridImageMask - anchors.fill: parent - anchors.margins: 2 - layer.enabled: true - layer.smooth: true - visible: false - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: "black" - antialiasing: true - } - } - - DankNFIcon { - anchors.centerIn: parent - name: delegateRoot.fileIsDir ? "folder" : getIconForFile(delegateRoot.fileName) - size: iconSizes[iconSizeIndex] * 0.45 - color: delegateRoot.fileIsDir ? Theme.primary : Theme.surfaceText - visible: (!delegateRoot.fileIsDir && !isImage && !(isVideo && gridPreviewImage.status === Image.Ready)) || (delegateRoot.fileIsDir && !weMode) - } - } - - StyledText { - text: delegateRoot.fileName || "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - width: delegateRoot.width - Theme.spacingM - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - anchors.horizontalCenter: parent.horizontalCenter - maximumLineCount: 2 - wrapMode: Text.Wrap - } - } - - MouseArea { - id: mouseArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - itemClicked(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir); - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml deleted file mode 100644 index 2f452b4..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserListDelegate.qml +++ /dev/null @@ -1,258 +0,0 @@ -import QtQuick -import QtQuick.Effects -import qs.Common -import qs.Widgets - -StyledRect { - id: listDelegateRoot - - required property bool fileIsDir - required property string filePath - required property string fileName - required property int index - required property var fileModified - required property int fileSize - - property int selectedIndex: -1 - property bool keyboardNavigationActive: false - - signal itemClicked(int index, string path, string name, bool isDir) - signal itemSelected(int index, string path, string name, bool isDir) - - function getFileExtension(fileName) { - const parts = fileName.split('.'); - if (parts.length > 1) { - return parts[parts.length - 1].toLowerCase(); - } - return ""; - } - - function determineFileType(fileName) { - const ext = getFileExtension(fileName); - - const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico", "jxl", "avif", "heif", "exr"]; - if (imageExts.includes(ext)) { - return "image"; - } - - const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"]; - if (videoExts.includes(ext)) { - return "video"; - } - - const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"]; - if (audioExts.includes(ext)) { - return "audio"; - } - - const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"]; - if (codeExts.includes(ext)) { - return "code"; - } - - const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"]; - if (docExts.includes(ext)) { - return "document"; - } - - const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"]; - if (archiveExts.includes(ext)) { - return "archive"; - } - - if (!ext || fileName.indexOf('.') === -1) { - return "binary"; - } - - return "file"; - } - - function isImageFile(fileName) { - if (!fileName) { - return false; - } - return determineFileType(fileName) === "image"; - } - - function isVideoFile(fileName) { - if (!fileName) { - return false; - } - return determineFileType(fileName) === "video"; - } - - property bool isImage: isImageFile(listDelegateRoot.fileName) - property bool isVideo: isVideoFile(listDelegateRoot.fileName) - - property string _xdgCacheHome: Paths.strip(Paths.xdgCache) - property string videoThumbnailPath: { - if (!listDelegateRoot.fileIsDir && isVideo) { - const hash = Qt.md5("file://" + listDelegateRoot.filePath); - return _xdgCacheHome + "/thumbnails/normal/" + hash + ".png"; - } - return ""; - } - - property string _videoThumb: "" - - onVideoThumbnailPathChanged: { - _videoThumb = ""; - if (!videoThumbnailPath) - return; - const thumbPath = videoThumbnailPath; - const fp = listDelegateRoot.filePath; - Paths.mkdir(_xdgCacheHome + "/thumbnails/normal"); - Proc.runCommand(null, ["test", "-f", thumbPath], function(output, exitCode) { - if (exitCode === 0) { - _videoThumb = thumbPath; - } else { - Proc.runCommand(null, ["ffmpegthumbnailer", "-i", fp, "-o", thumbPath, "-s", "128", "-f"], function(output, exitCode) { - if (exitCode === 0) - _videoThumb = thumbPath; - }); - } - }); - } - - function getIconForFile(fileName) { - const lowerName = fileName.toLowerCase(); - if (lowerName.startsWith("dockerfile")) { - return "docker"; - } - const ext = fileName.split('.').pop(); - return ext || ""; - } - - function formatFileSize(size) { - if (size < 1024) - return size + " B"; - if (size < 1024 * 1024) - return (size / 1024).toFixed(1) + " KB"; - if (size < 1024 * 1024 * 1024) - return (size / (1024 * 1024)).toFixed(1) + " MB"; - return (size / (1024 * 1024 * 1024)).toFixed(1) + " GB"; - } - - height: 44 - radius: Theme.cornerRadius - color: { - if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) - return Theme.surfacePressed; - return listMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent"; - } - border.color: keyboardNavigationActive && listDelegateRoot.index === selectedIndex ? Theme.primary : "transparent" - border.width: (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) ? 2 : 0 - - Component.onCompleted: { - if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) - itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir); - } - - onSelectedIndexChanged: { - if (keyboardNavigationActive && selectedIndex === listDelegateRoot.index) - itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir); - } - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - spacing: Theme.spacingS - - Item { - width: 28 - height: 28 - anchors.verticalCenter: parent.verticalCenter - - Image { - id: listPreviewImage - anchors.fill: parent - property string imagePath: { - if (!listDelegateRoot.fileIsDir && isImage) - return listDelegateRoot.filePath; - if (_videoThumb) - return _videoThumb; - return ""; - } - source: imagePath ? "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/') : "" - fillMode: Image.PreserveAspectCrop - sourceSize.width: 32 - sourceSize.height: 32 - asynchronous: true - visible: false - } - - MultiEffect { - anchors.fill: parent - source: listPreviewImage - maskEnabled: true - maskSource: listImageMask - visible: listPreviewImage.status === Image.Ready && !listDelegateRoot.fileIsDir && (isImage || isVideo) - maskThresholdMin: 0.5 - maskSpreadAtMin: 1 - } - - Item { - id: listImageMask - anchors.fill: parent - layer.enabled: true - layer.smooth: true - visible: false - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: "black" - antialiasing: true - } - } - - DankNFIcon { - anchors.centerIn: parent - name: listDelegateRoot.fileIsDir ? "folder" : getIconForFile(listDelegateRoot.fileName) - size: Theme.iconSize - 2 - color: listDelegateRoot.fileIsDir ? Theme.primary : Theme.surfaceText - visible: listDelegateRoot.fileIsDir || (!isImage && !(isVideo && listPreviewImage.status === Image.Ready)) - } - } - - StyledText { - text: listDelegateRoot.fileName || "" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - 280 - elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter - maximumLineCount: 1 - clip: true - } - - StyledText { - text: listDelegateRoot.fileIsDir ? "" : formatFileSize(listDelegateRoot.fileSize) - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: 70 - horizontalAlignment: Text.AlignRight - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: Qt.formatDateTime(listDelegateRoot.fileModified, "MMM d, yyyy h:mm AP") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: 140 - horizontalAlignment: Text.AlignRight - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: listMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - itemClicked(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir); - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml deleted file mode 100644 index c7686ca..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserModal.qml +++ /dev/null @@ -1,97 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Widgets - -FloatingWindow { - id: fileBrowserModal - - property bool disablePopupTransparency: true - property string browserTitle: "Select File" - property string browserIcon: "folder_open" - property string browserType: "generic" - property var fileExtensions: ["*.*"] - property alias filterExtensions: fileBrowserModal.fileExtensions - property bool showHiddenFiles: false - property bool saveMode: false - property string defaultFileName: "" - property var parentModal: null - property bool shouldHaveFocus: visible - property bool allowFocusOverride: false - property bool shouldBeVisible: visible - property bool allowStacking: true - - signal fileSelected(string path) - signal dialogClosed - - function open() { - visible = true; - } - - function close() { - visible = false; - } - - objectName: "fileBrowserModal" - title: "Files - " + browserTitle - minimumSize: Qt.size(500, 400) - implicitWidth: 800 - implicitHeight: 600 - color: Theme.surfaceContainer - visible: false - - onVisibleChanged: { - if (visible) { - if (parentModal && "shouldHaveFocus" in parentModal) { - parentModal.shouldHaveFocus = false; - parentModal.allowFocusOverride = true; - } - Qt.callLater(() => { - if (content) { - content.reset(); - content.forceActiveFocus(); - } - }); - } else { - if (parentModal && "allowFocusOverride" in parentModal) { - parentModal.allowFocusOverride = false; - parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); - } - dialogClosed(); - } - } - - Loader { - id: contentLoader - anchors.fill: parent - active: fileBrowserModal.visible - sourceComponent: FileBrowserContent { - id: content - anchors.fill: parent - focus: true - closeOnEscape: false - windowControls: fileBrowserModal.windowControlsRef - - browserTitle: fileBrowserModal.browserTitle - browserIcon: fileBrowserModal.browserIcon - browserType: fileBrowserModal.browserType - fileExtensions: fileBrowserModal.fileExtensions - showHiddenFiles: fileBrowserModal.showHiddenFiles - saveMode: fileBrowserModal.saveMode - defaultFileName: fileBrowserModal.defaultFileName - - Component.onCompleted: initialize() - - onFileSelected: path => fileBrowserModal.fileSelected(path) - onCloseRequested: fileBrowserModal.close() - } - } - - property alias content: contentLoader.item - property alias windowControlsRef: windowControls - - FloatingWindowControls { - id: windowControls - targetWindow: fileBrowserModal - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml deleted file mode 100644 index 61ce7b6..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserNavigation.qml +++ /dev/null @@ -1,130 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Row { - id: navigation - - property string currentPath: "" - property string homeDir: "" - property bool backButtonFocused: false - property bool keyboardNavigationActive: false - property bool showSidebar: true - property bool pathEditMode: false - property bool pathInputHasFocus: false - - signal navigateUp() - signal navigateTo(string path) - signal pathInputFocusChanged(bool hasFocus) - - height: 40 - leftPadding: Theme.spacingM - rightPadding: Theme.spacingM - spacing: Theme.spacingS - - StyledRect { - width: 32 - height: 32 - radius: Theme.cornerRadius - color: (backButtonMouseArea.containsMouse || (backButtonFocused && keyboardNavigationActive)) && currentPath !== homeDir ? Theme.surfaceVariant : "transparent" - opacity: currentPath !== homeDir ? 1 : 0 - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: "arrow_back" - size: Theme.iconSizeSmall - color: Theme.surfaceText - } - - MouseArea { - id: backButtonMouseArea - - anchors.fill: parent - hoverEnabled: currentPath !== homeDir - cursorShape: currentPath !== homeDir ? Qt.PointingHandCursor : Qt.ArrowCursor - enabled: currentPath !== homeDir - onClicked: navigation.navigateUp() - } - } - - Item { - width: Math.max(0, (parent?.width ?? 0) - 40 - Theme.spacingS - (showSidebar ? 0 : 80)) - height: 32 - anchors.verticalCenter: parent.verticalCenter - - StyledRect { - anchors.fill: parent - radius: Theme.cornerRadius - color: pathEditMode ? Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) : "transparent" - border.color: pathEditMode ? Theme.primary : "transparent" - border.width: pathEditMode ? 1 : 0 - visible: !pathEditMode - - StyledText { - id: pathDisplay - text: currentPath.replace("file://", "") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - elide: Text.ElideMiddle - verticalAlignment: Text.AlignVCenter - maximumLineCount: 1 - wrapMode: Text.NoWrap - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.IBeamCursor - onClicked: { - pathEditMode = true - pathInput.text = currentPath.replace("file://", "") - Qt.callLater(() => pathInput.forceActiveFocus()) - } - } - } - - DankTextField { - id: pathInput - anchors.fill: parent - visible: pathEditMode - topPadding: Theme.spacingXS - bottomPadding: Theme.spacingXS - onAccepted: { - const newPath = text.trim() - if (newPath !== "") { - navigation.navigateTo(newPath) - } - pathEditMode = false - } - Keys.onEscapePressed: { - pathEditMode = false - } - Keys.onDownPressed: { - pathEditMode = false - } - onActiveFocusChanged: { - navigation.pathInputFocusChanged(activeFocus) - if (!activeFocus && pathEditMode) { - pathEditMode = false - } - } - } - } - - Row { - spacing: Theme.spacingXS - visible: !showSidebar - anchors.verticalCenter: parent.verticalCenter - - DankActionButton { - circular: false - iconName: "sort" - iconSize: Theme.iconSize - 6 - iconColor: Theme.surfaceText - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml deleted file mode 100644 index a664be5..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserOverwriteDialog.qml +++ /dev/null @@ -1,127 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Item { - id: overwriteDialog - - property bool showDialog: false - property string pendingFilePath: "" - - signal confirmed(string filePath) - signal cancelled() - - visible: showDialog - focus: showDialog - - Keys.onEscapePressed: { - cancelled() - } - - Keys.onReturnPressed: { - confirmed(pendingFilePath) - } - - Rectangle { - anchors.fill: parent - color: Theme.shadowStrong - opacity: 0.8 - - MouseArea { - anchors.fill: parent - onClicked: { - cancelled() - } - } - } - - StyledRect { - anchors.centerIn: parent - width: 400 - height: 160 - color: Theme.surfaceContainer - radius: Theme.cornerRadius - border.color: Theme.outlineMedium - border.width: 1 - - Column { - anchors.centerIn: parent - width: parent.width - Theme.spacingL * 2 - spacing: Theme.spacingM - - StyledText { - text: I18n.tr("File Already Exists") - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Medium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("A file with this name already exists. Do you want to overwrite it?") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - } - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - StyledRect { - width: 80 - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceVariantHover : Theme.surfaceVariant - border.color: Theme.outline - border.width: 1 - - StyledText { - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - cancelled() - } - } - } - - StyledRect { - width: 90 - height: 36 - radius: Theme.cornerRadius - color: overwriteArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - - StyledText { - anchors.centerIn: parent - text: I18n.tr("Overwrite") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: overwriteArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - confirmed(pendingFilePath) - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml deleted file mode 100644 index 6360c7f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSaveRow.qml +++ /dev/null @@ -1,74 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Row { - id: saveRow - - property bool saveMode: false - property string defaultFileName: "" - property string currentPath: "" - - signal saveRequested(string filePath) - - height: saveMode ? 40 : 0 - visible: saveMode - spacing: Theme.spacingM - - DankTextField { - id: fileNameInput - - width: parent.width - saveButton.width - Theme.spacingM - height: 40 - text: defaultFileName - placeholderText: I18n.tr("Enter filename...") - ignoreLeftRightKeys: false - focus: saveMode - topPadding: Theme.spacingS - bottomPadding: Theme.spacingS - Component.onCompleted: { - if (saveMode) - Qt.callLater(() => { - forceActiveFocus() - }) - } - onAccepted: { - if (text.trim() !== "") { - var basePath = currentPath.replace(/^file:\/\//, '') - var fullPath = basePath + "/" + text.trim() - fullPath = fullPath.replace(/\/+/g, '/') - saveRequested(fullPath) - } - } - } - - StyledRect { - id: saveButton - - width: 80 - height: 40 - color: fileNameInput.text.trim() !== "" ? Theme.primary : Theme.surfaceVariant - radius: Theme.cornerRadius - - StyledText { - anchors.centerIn: parent - text: I18n.tr("Save") - color: fileNameInput.text.trim() !== "" ? Theme.primaryText : Theme.surfaceVariantText - font.pixelSize: Theme.fontSizeMedium - } - - StateLayer { - stateColor: Theme.primary - cornerRadius: Theme.cornerRadius - enabled: fileNameInput.text.trim() !== "" - onClicked: { - if (fileNameInput.text.trim() !== "") { - var basePath = currentPath.replace(/^file:\/\//, '') - var fullPath = basePath + "/" + fileNameInput.text.trim() - fullPath = fullPath.replace(/\/+/g, '/') - saveRequested(fullPath) - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml deleted file mode 100644 index bc02b3e..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSidebar.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -StyledRect { - id: sidebar - - property var quickAccessLocations: [] - property string currentPath: "" - signal locationSelected(string path) - - width: 200 - color: Theme.surface - clip: true - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingS - spacing: 4 - - StyledText { - text: I18n.tr("Quick Access") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - leftPadding: Theme.spacingS - bottomPadding: Theme.spacingXS - } - - Repeater { - model: quickAccessLocations - - StyledRect { - width: parent?.width ?? 0 - height: 38 - radius: Theme.cornerRadius - color: quickAccessMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : (currentPath === modelData?.path ? Theme.surfacePressed : "transparent") - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: modelData?.icon ?? "" - size: Theme.iconSize - 2 - color: currentPath === modelData?.path ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: modelData?.name ?? "" - font.pixelSize: Theme.fontSizeMedium - color: currentPath === modelData?.path ? Theme.primary : Theme.surfaceText - font.weight: currentPath === modelData?.path ? Font.Medium : Font.Normal - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: quickAccessMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: locationSelected(modelData?.path ?? "") - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml deleted file mode 100644 index e1886f9..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSortMenu.qml +++ /dev/null @@ -1,183 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -StyledRect { - id: sortMenu - - property string sortBy: "name" - property bool sortAscending: true - - signal sortBySelected(string value) - signal sortOrderSelected(bool ascending) - - width: 200 - height: sortColumn.height + Theme.spacingM * 2 - color: Theme.surfaceContainer - radius: Theme.cornerRadius - border.color: Theme.outlineMedium - border.width: 1 - visible: false - z: 100 - - Column { - id: sortColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - spacing: Theme.spacingXS - - StyledText { - text: "Sort By" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - } - - Repeater { - model: [{ - "name": "Name", - "value": "name" - }, { - "name": "Size", - "value": "size" - }, { - "name": "Modified", - "value": "modified" - }, { - "name": "Type", - "value": "type" - }] - - StyledRect { - width: sortColumn?.width ?? 0 - height: 32 - radius: Theme.cornerRadius - color: sortMouseArea.containsMouse ? Theme.surfaceVariant : (sortBy === modelData?.value ? Theme.surfacePressed : "transparent") - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - spacing: Theme.spacingS - - DankIcon { - name: sortBy === modelData?.value ? "check" : "" - size: Theme.iconSizeSmall - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - visible: sortBy === modelData?.value - } - - StyledText { - text: modelData?.name ?? "" - font.pixelSize: Theme.fontSizeMedium - color: sortBy === modelData?.value ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: sortMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - sortMenu.sortBySelected(modelData?.value ?? "name") - sortMenu.visible = false - } - } - } - } - - StyledRect { - width: sortColumn.width - height: 1 - color: Theme.outline - } - - StyledText { - text: "Order" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - font.weight: Font.Medium - topPadding: Theme.spacingXS - } - - StyledRect { - width: sortColumn?.width ?? 0 - height: 32 - radius: Theme.cornerRadius - color: ascMouseArea.containsMouse ? Theme.surfaceVariant : (sortAscending ? Theme.surfacePressed : "transparent") - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - spacing: Theme.spacingS - - DankIcon { - name: "arrow_upward" - size: Theme.iconSizeSmall - color: sortAscending ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: "Ascending" - font.pixelSize: Theme.fontSizeMedium - color: sortAscending ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: ascMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - sortMenu.sortOrderSelected(true) - sortMenu.visible = false - } - } - } - - StyledRect { - width: sortColumn?.width ?? 0 - height: 32 - radius: Theme.cornerRadius - color: descMouseArea.containsMouse ? Theme.surfaceVariant : (!sortAscending ? Theme.surfacePressed : "transparent") - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - spacing: Theme.spacingS - - DankIcon { - name: "arrow_downward" - size: Theme.iconSizeSmall - color: !sortAscending ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: "Descending" - font.pixelSize: Theme.fontSizeMedium - color: !sortAscending ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: descMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - sortMenu.sortOrderSelected(false) - sortMenu.visible = false - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml deleted file mode 100644 index 25b8d5a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileBrowserSurfaceModal.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick -import Quickshell.Wayland -import qs.Common -import qs.Modals.Common - -DankModal { - id: fileBrowserSurfaceModal - - property string browserTitle: "Select File" - property string browserIcon: "folder_open" - property string browserType: "generic" - property var fileExtensions: ["*.*"] - property alias filterExtensions: fileBrowserSurfaceModal.fileExtensions - property bool showHiddenFiles: false - property bool saveMode: false - property string defaultFileName: "" - property var parentPopout: null - - signal fileSelected(string path) - - layerNamespace: "dms:filebrowser" - modalWidth: 800 - modalHeight: 600 - backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - closeOnEscapeKey: true - closeOnBackgroundClick: true - allowStacking: true - keepPopoutsOpen: true - - onBackgroundClicked: close() - - onOpened: { - if (parentPopout) { - parentPopout.customKeyboardFocus = WlrKeyboardFocus.None; - } - Qt.callLater(() => { - if (contentLoader.item) { - contentLoader.item.reset(); - contentLoader.item.forceActiveFocus(); - } - }); - } - - onDialogClosed: { - if (parentPopout) { - parentPopout.customKeyboardFocus = null; - } - } - - content: FileBrowserContent { - focus: true - - browserTitle: fileBrowserSurfaceModal.browserTitle - browserIcon: fileBrowserSurfaceModal.browserIcon - browserType: fileBrowserSurfaceModal.browserType - fileExtensions: fileBrowserSurfaceModal.fileExtensions - showHiddenFiles: fileBrowserSurfaceModal.showHiddenFiles - saveMode: fileBrowserSurfaceModal.saveMode - defaultFileName: fileBrowserSurfaceModal.defaultFileName - - Component.onCompleted: initialize() - - onFileSelected: path => fileBrowserSurfaceModal.fileSelected(path) - onCloseRequested: fileBrowserSurfaceModal.close() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml deleted file mode 100644 index c41f039..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml +++ /dev/null @@ -1,237 +0,0 @@ -import QtQuick -import QtCore -import Quickshell.Io -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property bool showFileInfo: false - property int selectedIndex: -1 - property var sourceFolderModel: null - property string currentPath: "" - - height: 200 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) - border.color: Theme.secondary - border.width: 2 - opacity: showFileInfo ? 1 : 0 - z: 100 - - onShowFileInfoChanged: { - if (showFileInfo && currentFileName && currentPath) { - const fullPath = currentPath + "/" + currentFileName - fileStatProcess.selectedFilePath = fullPath - fileStatProcess.running = true - } - } - - Process { - id: fileStatProcess - command: ["stat", "-c", "%y|%A|%s|%n", selectedFilePath] - property string selectedFilePath: "" - property var fileStats: null - running: false - - stdout: StdioCollector { - onStreamFinished: { - if (text && text.trim()) { - const parts = text.trim().split('|') - if (parts.length >= 4) { - fileStatProcess.fileStats = { - "modifiedTime": parts[0], - "permissions": parts[1], - "size": parseInt(parts[2]) || 0, - "fullPath": parts[3] - } - } - } - } - } - - onExited: function (exitCode) {} - } - - property string currentFileName: "" - property bool currentFileIsDir: false - property string currentFileExtension: "" - - onCurrentFileNameChanged: { - if (showFileInfo && currentFileName && currentPath) { - const fullPath = currentPath + "/" + currentFileName - if (fullPath !== fileStatProcess.selectedFilePath) { - fileStatProcess.selectedFilePath = fullPath - fileStatProcess.running = true - } - } - } - - function updateFileInfo(filePath, fileName, isDirectory) { - if (filePath && filePath !== fileStatProcess.selectedFilePath) { - fileStatProcess.selectedFilePath = filePath - currentFileName = fileName || "" - currentFileIsDir = isDirectory || false - - let ext = "" - if (!isDirectory && fileName) { - const lastDot = fileName.lastIndexOf('.') - if (lastDot > 0) { - ext = fileName.substring(lastDot + 1).toLowerCase() - } - } - currentFileExtension = ext - - if (showFileInfo) { - fileStatProcess.running = true - } - } - } - - readonly property var currentFileDisplayData: { - if (selectedIndex < 0 || !sourceFolderModel) { - return { - "exists": false, - "name": "No selection", - "type": "", - "size": "", - "modified": "", - "permissions": "", - "extension": "", - "position": "N/A" - } - } - - const hasValidFile = currentFileName !== "" - return { - "exists": hasValidFile, - "name": hasValidFile ? currentFileName : "Loading...", - "type": currentFileIsDir ? "Directory" : "File", - "size": fileStatProcess.fileStats ? formatFileSize(fileStatProcess.fileStats.size) : "Calculating...", - "modified": fileStatProcess.fileStats ? formatDateTime(fileStatProcess.fileStats.modifiedTime) : "Loading...", - "permissions": fileStatProcess.fileStats ? fileStatProcess.fileStats.permissions : "Loading...", - "extension": currentFileExtension, - "position": sourceFolderModel ? ((selectedIndex + 1) + " of " + sourceFolderModel.count) : "N/A" - } - } - - Column { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingM - spacing: Theme.spacingXS - - Row { - width: parent.width - spacing: Theme.spacingS - - DankIcon { - name: "info" - size: Theme.iconSize - color: Theme.secondary - } - - StyledText { - text: I18n.tr("File Information") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Column { - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: currentFileDisplayData.name - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - elide: Text.ElideMiddle - wrapMode: Text.NoWrap - font.weight: Font.Medium - } - - StyledText { - text: currentFileDisplayData.type + (currentFileDisplayData.extension ? " (." + currentFileDisplayData.extension + ")" : "") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: parent.width - } - - StyledText { - text: currentFileDisplayData.size - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: parent.width - visible: currentFileDisplayData.exists && !currentFileIsDir - } - - StyledText { - text: currentFileDisplayData.modified - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: parent.width - elide: Text.ElideRight - visible: currentFileDisplayData.exists - } - - StyledText { - text: currentFileDisplayData.permissions - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - visible: currentFileDisplayData.exists - } - - StyledText { - text: currentFileDisplayData.position - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: parent.width - } - } - } - - StyledText { - text: I18n.tr("F1/I: Toggle • F10: Help") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingM - horizontalAlignment: Text.AlignHCenter - } - - function formatFileSize(bytes) { - if (bytes === 0 || !bytes) { - return "0 B" - } - const k = 1024 - const sizes = ['B', 'KB', 'MB', 'GB', 'TB'] - const i = Math.floor(Math.log(bytes) / Math.log(k)) - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i] - } - - function formatDateTime(dateTimeString) { - if (!dateTimeString) { - return "Unknown" - } - const parts = dateTimeString.split(' ') - if (parts.length >= 2) { - return parts[0] + " " + parts[1].split('.')[0] - } - return dateTimeString - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml deleted file mode 100644 index 1910810..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/KeyboardHints.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property bool showHints: false - - height: 80 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) - border.color: Theme.primary - border.width: 2 - opacity: showHints ? 1 : 0 - z: 100 - - Column { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingS - spacing: 2 - - StyledText { - text: I18n.tr("Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - width: parent.width - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - } - - StyledText { - text: I18n.tr("Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - width: parent.width - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - } - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml deleted file mode 100644 index 8a5ca00..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml +++ /dev/null @@ -1,492 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - property var greeterRoot: parent ? parent.greeterRoot : null - - readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2) - readonly property real sectionIconSize: Theme.iconSizeSmall + 2 - readonly property real keybindRowHeight: Math.round(Theme.fontSizeMedium * 2) - readonly property real keyBadgeHeight: Math.round(Theme.fontSizeSmall * 1.83) - - readonly property var featureNames: ({ - "spotlight": "App Launcher", - "clipboard": "Clipboard", - "processlist": "Task Manager", - "settings": "Settings", - "notifications": "Notifications", - "notepad": "Notepad", - "hotkeys": "Keybinds", - "lock": "Lock Screen", - "dankdash": "Dashboard" - }) - - function getFeatureDesc(action) { - const match = action.match(/dms\s+ipc\s+call\s+(\w+)/); - if (match && featureNames[match[1]]) - return featureNames[match[1]]; - return null; - } - - readonly property var dmsKeybinds: { - if (!greeterRoot || !greeterRoot.cheatsheetLoaded || !greeterRoot.cheatsheetData || !greeterRoot.cheatsheetData.binds) - return []; - const seen = new Set(); - const binds = []; - const allBinds = greeterRoot.cheatsheetData.binds; - for (const category in allBinds) { - const categoryBinds = allBinds[category]; - for (let i = 0; i < categoryBinds.length; i++) { - const bind = categoryBinds[i]; - if (!bind.key || !bind.action) - continue; - if (!bind.action.includes("dms")) - continue; - if (!(bind.action.includes("spawn") || bind.action.includes("exec"))) - continue; - const feature = getFeatureDesc(bind.action); - if (!feature) - continue; - if (seen.has(feature)) - continue; - seen.add(feature); - binds.push({ - key: bind.key, - desc: feature - }); - } - } - return binds; - } - - readonly property bool hasKeybinds: dmsKeybinds.length > 0 - - DankFlickable { - anchors.fill: parent - clip: true - contentHeight: mainColumn.height + Theme.spacingL * 2 - contentWidth: width - - Column { - id: mainColumn - anchors.horizontalCenter: parent.horizontalCenter - width: Math.min(640, parent.width - Theme.spacingXL * 2) - topPadding: Theme.spacingL - spacing: Theme.spacingL - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Rectangle { - width: root.headerIconContainerSize - height: root.headerIconContainerSize - radius: Math.round(root.headerIconContainerSize * 0.29) - color: Theme.withAlpha(Theme.success, 0.15) - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: "check_circle" - size: Theme.iconSize + 4 - color: Theme.success - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: I18n.tr("You're All Set!", "greeter completion page title") - font.pixelSize: Theme.fontSizeXLarge - font.weight: Font.Bold - color: Theme.surfaceText - } - - StyledText { - text: I18n.tr("DankMaterialShell is ready to use", "greeter completion page subtitle") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - } - } - } - - Column { - width: parent.width - spacing: Theme.spacingS - visible: root.hasKeybinds - - Row { - width: parent.width - spacing: Theme.spacingS - - DankIcon { - name: "keyboard" - size: root.sectionIconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("DMS Shortcuts", "greeter keybinds section header") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - id: keybindsRect - width: parent.width - height: keybindsGrid.height + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - - readonly property bool useTwoColumns: width > 500 - readonly property int columnCount: useTwoColumns ? 2 : 1 - readonly property real itemWidth: useTwoColumns ? (width - Theme.spacingM * 3) / 2 : width - Theme.spacingM * 2 - property real maxKeyWidth: 0 - - Grid { - id: keybindsGrid - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - columns: keybindsRect.columnCount - rowSpacing: Theme.spacingS - columnSpacing: Theme.spacingM - - Repeater { - model: root.dmsKeybinds - - Row { - width: keybindsRect.itemWidth - height: root.keybindRowHeight - spacing: Theme.spacingS - - Item { - width: keybindsRect.maxKeyWidth - height: parent.height - - Row { - id: keysRow - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - property real naturalWidth: { - let w = 0; - for (let i = 0; i < children.length; i++) { - if (children[i].visible) - w += children[i].width + (i > 0 ? Theme.spacingXS : 0); - } - return w; - } - - Component.onCompleted: { - Qt.callLater(() => { - if (naturalWidth > keybindsRect.maxKeyWidth) - keybindsRect.maxKeyWidth = naturalWidth; - }); - } - - Repeater { - model: (modelData.key || "").split("+") - - Rectangle { - width: singleKeyText.implicitWidth + Theme.spacingM - height: root.keyBadgeHeight - radius: Theme.spacingXS - color: Theme.surfaceContainerHighest - border.width: 1 - border.color: Theme.outline - - StyledText { - id: singleKeyText - anchors.centerIn: parent - color: Theme.secondary - text: modelData - font.pixelSize: Theme.fontSizeSmall - 1 - font.weight: Font.Medium - isMonospace: true - } - } - } - } - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - width: parent.width - keybindsRect.maxKeyWidth - Theme.spacingS - text: modelData.desc || "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - elide: Text.ElideRight - } - } - } - } - } - } - - Rectangle { - width: parent.width - height: noKeybindsColumn.height + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - visible: !root.hasKeybinds - - Column { - id: noKeybindsColumn - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - - Row { - spacing: Theme.spacingS - - DankIcon { - name: "keyboard" - size: root.sectionIconSize - color: Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("No DMS shortcuts configured", "greeter no keybinds message") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - width: parent.width - height: Math.round(Theme.fontSizeMedium * 2.85) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHighest - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: Theme.primary - opacity: noKeybindsLinkMouse.containsMouse ? 0.12 : 0 - } - - Row { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "menu_book" - size: root.sectionIconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Configure Keybinds", "greeter configure keybinds link") - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - DankIcon { - name: "open_in_new" - size: Theme.iconSizeSmall - 2 - color: Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: noKeybindsLinkMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - let url = "https://danklinux.com/docs/dankmaterialshell/keybinds-ipc"; - if (CompositorService.isNiri) - url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings"; - else if (CompositorService.isHyprland) - url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-1"; - else if (CompositorService.isDwl) - url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-2"; - Qt.openUrlExternally(url); - } - } - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.3 - visible: root.hasKeybinds - } - - Column { - width: parent.width - spacing: Theme.spacingS - - Row { - width: parent.width - spacing: Theme.spacingS - - DankIcon { - name: "settings" - size: root.sectionIconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Configure", "greeter settings section header") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Grid { - width: parent.width - columns: 2 - rowSpacing: Theme.spacingS - columnSpacing: Theme.spacingS - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "display_settings" - title: I18n.tr("Displays", "greeter settings link") - description: I18n.tr("Resolution, position, scale", "greeter displays description") - onClicked: PopoutService.openSettingsWithTab("display_config") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "wallpaper" - title: I18n.tr("Wallpaper", "greeter settings link") - description: I18n.tr("Background image", "greeter wallpaper description") - onClicked: PopoutService.openSettingsWithTab("wallpaper") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "format_paint" - title: I18n.tr("Theme & Colors", "greeter settings link") - description: I18n.tr("Dynamic colors, presets", "greeter theme description") - onClicked: PopoutService.openSettingsWithTab("theme") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "notifications" - title: I18n.tr("Notifications", "greeter settings link") - description: I18n.tr("Popup behavior, position", "greeter notifications description") - onClicked: PopoutService.openSettingsWithTab("notifications") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "toolbar" - title: I18n.tr("DankBar", "greeter settings link") - description: I18n.tr("Widgets, layout, style", "greeter dankbar description") - onClicked: PopoutService.openSettingsWithTab("dankbar_settings") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "keyboard" - title: I18n.tr("Keybinds", "greeter settings link") - description: I18n.tr("niri shortcuts config", "greeter keybinds niri description") - visible: KeybindsService.available - onClicked: PopoutService.openSettingsWithTab("keybinds") - } - - GreeterSettingsCard { - width: (parent.width - Theme.spacingS) / 2 - iconName: "dock_to_bottom" - title: I18n.tr("Dock", "greeter settings link") - description: I18n.tr("Position, pinned apps", "greeter dock description") - visible: !KeybindsService.available - onClicked: PopoutService.openSettingsWithTab("dock") - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.3 - } - - Column { - width: parent.width - spacing: Theme.spacingS - - Row { - width: parent.width - spacing: Theme.spacingS - - DankIcon { - name: "explore" - size: root.sectionIconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Explore", "greeter explore section header") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - width: parent.width - spacing: Theme.spacingS - - GreeterQuickLink { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "menu_book" - title: I18n.tr("Docs", "greeter documentation link") - isExternal: true - onClicked: Qt.openUrlExternally("https://danklinux.com/docs") - } - - GreeterQuickLink { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "extension" - title: I18n.tr("Plugins", "greeter plugins link") - isExternal: true - onClicked: Qt.openUrlExternally("https://danklinux.com/plugins") - } - - GreeterQuickLink { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "palette" - title: I18n.tr("Themes", "greeter themes link") - isExternal: true - onClicked: Qt.openUrlExternally("https://danklinux.com/plugins?tab=themes") - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml deleted file mode 100644 index 288cd58..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorPage.qml +++ /dev/null @@ -1,427 +0,0 @@ -import QtQuick -import Quickshell.Io -import qs.Common -import qs.Widgets - -Item { - id: root - - property bool isRunning: false - property bool hasRun: false - property var doctorResults: null - property int errorCount: 0 - property int warningCount: 0 - property int okCount: 0 - property int infoCount: 0 - property string selectedFilter: "error" - - readonly property real loadingContainerSize: Math.round(Theme.iconSize * 5) - readonly property real pulseRingSize: Math.round(Theme.iconSize * 3.3) - readonly property real centerIconContainerSize: Math.round(Theme.iconSize * 2.67) - readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2) - - readonly property var filteredResults: { - if (!doctorResults?.results) - return []; - return doctorResults.results.filter(r => r.status === selectedFilter); - } - - function runDoctor() { - hasRun = false; - isRunning = true; - doctorProcess.running = true; - } - - Component.onCompleted: runDoctor() - - Item { - id: loadingView - anchors.fill: parent - visible: root.isRunning - - Column { - anchors.centerIn: parent - spacing: Theme.spacingXL - - Item { - width: root.loadingContainerSize - height: root.loadingContainerSize - anchors.horizontalCenter: parent.horizontalCenter - - Rectangle { - id: pulseRing1 - anchors.centerIn: parent - width: root.pulseRingSize - height: root.pulseRingSize - radius: root.pulseRingSize / 2 - color: "transparent" - border.width: Math.round(Theme.spacingXS * 0.75) - border.color: Theme.primary - opacity: 0 - - SequentialAnimation on opacity { - running: root.isRunning - loops: Animation.Infinite - NumberAnimation { - from: 0.8 - to: 0 - duration: 1500 - easing.type: Easing.OutQuad - } - } - - SequentialAnimation on scale { - running: root.isRunning - loops: Animation.Infinite - NumberAnimation { - from: 0.5 - to: 1.5 - duration: 1500 - easing.type: Easing.OutQuad - } - } - } - - Rectangle { - id: pulseRing2 - anchors.centerIn: parent - width: root.pulseRingSize - height: root.pulseRingSize - radius: root.pulseRingSize / 2 - color: "transparent" - border.width: Math.round(Theme.spacingXS * 0.75) - border.color: Theme.secondary - opacity: 0 - - SequentialAnimation on opacity { - running: root.isRunning - loops: Animation.Infinite - NumberAnimation { - from: 0.8 - to: 0 - duration: 1500 - easing.type: Easing.OutQuad - } - } - - SequentialAnimation on scale { - running: root.isRunning - loops: Animation.Infinite - NumberAnimation { - from: 0.3 - to: 1.3 - duration: 1500 - easing.type: Easing.OutQuad - } - } - } - - Rectangle { - anchors.centerIn: parent - width: root.centerIconContainerSize - height: root.centerIconContainerSize - radius: root.centerIconContainerSize / 2 - color: Theme.primaryContainer - - DankIcon { - anchors.centerIn: parent - name: "vital_signs" - size: Theme.iconSizeLarge - color: Theme.primary - } - - SequentialAnimation on scale { - running: root.isRunning - loops: Animation.Infinite - NumberAnimation { - from: 1 - to: 1.1 - duration: 750 - easing.type: Easing.InOutQuad - } - NumberAnimation { - from: 1.1 - to: 1 - duration: 750 - easing.type: Easing.InOutQuad - } - } - } - } - - Column { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingS - - StyledText { - text: I18n.tr("System Check", "greeter doctor page title") - font.pixelSize: Theme.fontSizeXLarge - font.weight: Font.Bold - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("Analyzing configuration...", "greeter doctor page loading text") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - - Item { - id: resultsView - anchors.fill: parent - visible: root.hasRun && !root.isRunning - opacity: (root.hasRun && !root.isRunning) ? 1 : 0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.emphasizedEasing - } - } - - Column { - id: headerSection - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.topMargin: Theme.spacingL - anchors.leftMargin: Theme.spacingXL - anchors.rightMargin: Theme.spacingXL - spacing: Theme.spacingL - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingM - - Rectangle { - width: root.headerIconContainerSize - height: root.headerIconContainerSize - radius: Math.round(root.headerIconContainerSize * 0.29) - color: root.errorCount > 0 ? Theme.errorContainer : Theme.primaryContainer - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: root.errorCount > 0 ? "warning" : "check_circle" - size: Theme.iconSize + 4 - color: root.errorCount > 0 ? Theme.error : Theme.primary - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: I18n.tr("System Check", "greeter doctor page title") - font.pixelSize: Theme.fontSizeXLarge - font.weight: Font.Bold - color: Theme.surfaceText - } - - StyledText { - text: { - if (root.errorCount === 0) - return I18n.tr("All checks passed", "greeter doctor page success"); - return root.errorCount === 1 - ? I18n.tr("%1 issue found", "greeter doctor page error count").arg(root.errorCount) - : I18n.tr("%1 issues found", "greeter doctor page error count").arg(root.errorCount); - } - font.pixelSize: Theme.fontSizeMedium - color: root.errorCount > 0 ? Theme.error : Theme.surfaceVariantText - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingS - - GreeterStatusCard { - width: (parent.width - Theme.spacingS * 3) / 4 - count: root.errorCount - label: I18n.tr("Errors", "greeter doctor page status card") - iconName: "error" - iconColor: Theme.error - bgColor: Theme.errorContainer || Theme.withAlpha(Theme.error, 0.15) - selected: root.selectedFilter === "error" - onClicked: root.selectedFilter = "error" - } - - GreeterStatusCard { - width: (parent.width - Theme.spacingS * 3) / 4 - count: root.warningCount - label: I18n.tr("Warnings", "greeter doctor page status card") - iconName: "warning" - iconColor: Theme.warning - bgColor: Theme.withAlpha(Theme.warning, 0.15) - selected: root.selectedFilter === "warn" - onClicked: root.selectedFilter = "warn" - } - - GreeterStatusCard { - width: (parent.width - Theme.spacingS * 3) / 4 - count: root.infoCount - label: I18n.tr("Info", "greeter doctor page status card") - iconName: "info" - iconColor: Theme.secondary - bgColor: Theme.withAlpha(Theme.secondary, 0.15) - selected: root.selectedFilter === "info" - onClicked: root.selectedFilter = "info" - } - - GreeterStatusCard { - width: (parent.width - Theme.spacingS * 3) / 4 - count: root.okCount - label: I18n.tr("OK", "greeter doctor page status card") - iconName: "check_circle" - iconColor: Theme.success - bgColor: Theme.withAlpha(Theme.success, 0.15) - selected: root.selectedFilter === "ok" - onClicked: root.selectedFilter = "ok" - } - } - } - - Rectangle { - id: resultsContainer - anchors.top: headerSection.bottom - anchors.bottom: footerSection.top - anchors.left: parent.left - anchors.right: parent.right - anchors.topMargin: Theme.spacingL - anchors.bottomMargin: Theme.spacingM - anchors.leftMargin: Theme.spacingXL - anchors.rightMargin: Theme.spacingXL - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - clip: true - - Column { - anchors.centerIn: parent - spacing: Theme.spacingS - visible: root.filteredResults.length === 0 - - DankIcon { - name: { - switch (root.selectedFilter) { - case "error": - return "check_circle"; - case "warn": - return "thumb_up"; - case "info": - return "info"; - default: - return "verified"; - } - } - size: Math.round(Theme.iconSize * 1.67) - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: { - switch (root.selectedFilter) { - case "error": - return I18n.tr("No errors", "greeter doctor page empty state"); - case "warn": - return I18n.tr("No warnings", "greeter doctor page empty state"); - case "info": - return I18n.tr("No info items", "greeter doctor page empty state"); - default: - return I18n.tr("No checks passed", "greeter doctor page empty state"); - } - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - - DankFlickable { - anchors.fill: parent - anchors.margins: Theme.spacingM - clip: true - contentHeight: resultsColumn.height - contentWidth: width - visible: root.filteredResults.length > 0 - - Column { - id: resultsColumn - width: parent.width - spacing: Theme.spacingS - - Repeater { - model: root.filteredResults - - GreeterDoctorResultItem { - width: resultsColumn.width - resultData: modelData - } - } - } - } - } - - Row { - id: footerSection - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: Theme.spacingL - spacing: Theme.spacingM - - DankButton { - text: I18n.tr("Run Again", "greeter doctor page button") - iconName: "refresh" - backgroundColor: Theme.surfaceContainerHighest - textColor: Theme.surfaceText - onClicked: root.runDoctor() - } - } - } - - Process { - id: doctorProcess - command: ["dms", "doctor", "--json"] - running: false - - stdout: StdioCollector { - onStreamFinished: { - root.isRunning = false; - root.hasRun = true; - try { - root.doctorResults = JSON.parse(text); - if (root.doctorResults?.summary) { - root.errorCount = root.doctorResults.summary.errors || 0; - root.warningCount = root.doctorResults.summary.warnings || 0; - root.okCount = root.doctorResults.summary.ok || 0; - root.infoCount = root.doctorResults.summary.info || 0; - } - if (root.errorCount > 0) - root.selectedFilter = "error"; - else if (root.warningCount > 0) - root.selectedFilter = "warn"; - else if (root.infoCount > 0) - root.selectedFilter = "info"; - else - root.selectedFilter = "ok"; - } catch (e) { - console.error("GreeterDoctorPage: Failed to parse doctor output:", e); - } - } - } - - onExited: exitCode => { - if (exitCode !== 0) { - root.isRunning = false; - root.hasRun = true; - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml deleted file mode 100644 index b15969a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterDoctorResultItem.qml +++ /dev/null @@ -1,109 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property var resultData: null - - readonly property string status: resultData?.status || "ok" - readonly property string statusIcon: { - switch (status) { - case "error": - return "error"; - case "warn": - return "warning"; - case "info": - return "info"; - default: - return "check_circle"; - } - } - readonly property color statusColor: { - switch (status) { - case "error": - return Theme.error; - case "warn": - return Theme.warning; - case "info": - return Theme.secondary; - default: - return Theme.success; - } - } - - height: Math.round(Theme.fontSizeMedium * 3.4) - radius: Theme.cornerRadius - color: Theme.withAlpha(statusColor, 0.08) - - DankIcon { - id: statusIcon - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - name: root.statusIcon - size: Theme.iconSize - 4 - color: root.statusColor - } - - Column { - anchors.left: statusIcon.right - anchors.leftMargin: Theme.spacingS - anchors.right: categoryChip.visible ? categoryChip.left : (urlButton.visible ? urlButton.left : parent.right) - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - spacing: 1 - - StyledText { - width: parent.width - text: root.resultData?.name || "" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceText - elide: Text.ElideRight - } - - StyledText { - width: parent.width - text: root.resultData?.message || "" - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - elide: Text.ElideRight - visible: text.length > 0 - } - } - - Rectangle { - id: categoryChip - anchors.right: urlButton.visible ? urlButton.left : parent.right - anchors.rightMargin: urlButton.visible ? Theme.spacingXS : Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - height: Math.round(Theme.fontSizeSmall * 1.67) - width: categoryText.implicitWidth + Theme.spacingS - radius: Theme.spacingXS - color: Theme.surfaceContainerHighest - visible: !!(root.resultData?.category) - - StyledText { - id: categoryText - anchors.centerIn: parent - text: root.resultData?.category || "" - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.surfaceVariantText - } - } - - DankActionButton { - id: urlButton - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - iconName: "open_in_new" - iconSize: Theme.iconSize - 6 - buttonSize: 24 - visible: !!(root.resultData?.url) - tooltipText: root.resultData?.url || "" - onClicked: Qt.openUrlExternally(root.resultData.url) - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml deleted file mode 100644 index a5bf4f4..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterFeatureCard.qml +++ /dev/null @@ -1,74 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property string iconName: "" - property string title: "" - property string description: "" - - signal clicked - - readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.5) - - height: Math.round(Theme.fontSizeMedium * 6.4) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: Theme.primary - opacity: mouseArea.containsMouse ? 0.12 : 0 - } - - Column { - anchors.centerIn: parent - spacing: Theme.spacingS - - Rectangle { - width: root.iconContainerSize - height: root.iconContainerSize - radius: Math.round(root.iconContainerSize * 0.28) - color: Theme.primaryContainer - anchors.horizontalCenter: parent.horizontalCenter - - DankIcon { - anchors.centerIn: parent - name: root.iconName - size: Theme.iconSize - 4 - color: Theme.primary - } - } - - Column { - anchors.horizontalCenter: parent.horizontalCenter - spacing: 2 - - StyledText { - text: root.title - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: root.description - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.clicked() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml deleted file mode 100644 index 973dab2..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterModal.qml +++ /dev/null @@ -1,333 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - property int currentPage: 0 - readonly property int totalPages: 3 - readonly property var pageComponents: [welcomePage, doctorPage, completePage] - - property var cheatsheetData: ({}) - property bool cheatsheetLoaded: false - - readonly property int modalWidth: 720 - readonly property int modalHeight: screen ? Math.min(760, screen.height - 80) : 760 - - signal greeterCompleted - - Component.onCompleted: Qt.callLater(loadCheatsheet) - - function loadCheatsheet() { - const provider = KeybindsService.cheatsheetProvider; - if (KeybindsService.cheatsheetAvailable && provider && !cheatsheetLoaded) { - cheatsheetProcess.command = ["dms", "keybinds", "show", provider]; - cheatsheetProcess.running = true; - } - } - - Connections { - target: KeybindsService - function onCheatsheetAvailableChanged() { - if (KeybindsService.cheatsheetAvailable && !root.cheatsheetLoaded) - loadCheatsheet(); - } - } - - function getKeybind(actionPattern) { - if (!cheatsheetLoaded || !cheatsheetData.binds) - return ""; - for (const category in cheatsheetData.binds) { - const binds = cheatsheetData.binds[category]; - for (let i = 0; i < binds.length; i++) { - const bind = binds[i]; - if (bind.action && bind.action.includes(actionPattern)) - return bind.key || ""; - } - } - return ""; - } - - function show() { - currentPage = FirstLaunchService.requestedStartPage || 0; - visible = true; - } - - function showAtPage(page) { - currentPage = page; - visible = true; - } - - function nextPage() { - if (currentPage < totalPages - 1) - currentPage++; - } - - function prevPage() { - if (currentPage > 0) - currentPage--; - } - - function finish() { - FirstLaunchService.markFirstLaunchComplete(); - greeterCompleted(); - visible = false; - } - - function skip() { - FirstLaunchService.markFirstLaunchComplete(); - greeterCompleted(); - visible = false; - } - - objectName: "greeterModal" - title: I18n.tr("Welcome", "greeter modal window title") - minimumSize: Qt.size(modalWidth, modalHeight) - maximumSize: Qt.size(modalWidth, modalHeight) - color: Theme.surfaceContainer - visible: false - - Process { - id: cheatsheetProcess - running: false - - stdout: StdioCollector { - onStreamFinished: { - const trimmed = text.trim(); - if (trimmed.length === 0) - return; - try { - root.cheatsheetData = JSON.parse(trimmed); - root.cheatsheetLoaded = true; - } catch (e) { - console.warn("Greeter: Failed to parse cheatsheet:", e); - } - } - } - } - - FocusScope { - id: contentFocusScope - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - root.skip(); - event.accepted = true; - } - - Keys.onPressed: event => { - switch (event.key) { - case Qt.Key_Return: - case Qt.Key_Enter: - if (root.currentPage < root.totalPages - 1) - root.nextPage(); - else - root.finish(); - event.accepted = true; - break; - case Qt.Key_Left: - if (root.currentPage > 0) - root.prevPage(); - event.accepted = true; - break; - case Qt.Key_Right: - if (root.currentPage < root.totalPages - 1) - root.nextPage(); - event.accepted = true; - break; - } - } - - MouseArea { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: headerRow.height + Theme.spacingM - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - Item { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - height: Math.round(Theme.fontSizeMedium * 2.85) - - Rectangle { - id: pageIndicatorContainer - readonly property real indicatorHeight: Math.round(Theme.fontSizeMedium * 2) - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - width: pageIndicatorRow.width + Theme.spacingM * 2 - height: indicatorHeight - radius: indicatorHeight / 2 - color: Theme.surfaceContainerHigh - - Row { - id: pageIndicatorRow - anchors.centerIn: parent - spacing: Theme.spacingS - - Repeater { - model: root.totalPages - - Rectangle { - required property int index - property bool isActive: index === root.currentPage - readonly property real dotSize: Math.round(Theme.spacingS * 1.3) - - width: isActive ? dotSize * 3 : dotSize - height: dotSize - radius: dotSize / 2 - color: isActive ? Theme.primary : Theme.surfaceTextAlpha - anchors.verticalCenter: parent.verticalCenter - - Behavior on width { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.emphasizedEasing - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - } - } - } - } - } - } - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported && windowControls.canMaximize - iconName: root.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.skip() - - DankTooltip { - text: I18n.tr("Skip setup", "greeter skip button tooltip") - } - } - } - } - - Item { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerRow.bottom - anchors.bottom: footerRow.top - anchors.topMargin: Theme.spacingS - - Loader { - id: pageLoader - anchors.fill: parent - sourceComponent: root.pageComponents[root.currentPage] - - property var greeterRoot: root - } - } - - Rectangle { - id: footerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Math.round(Theme.fontSizeMedium * 4.5) - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.top: parent.top - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.5 - } - - Row { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingL - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankButton { - visible: root.currentPage < root.totalPages - 1 - text: I18n.tr("Skip", "greeter skip button") - backgroundColor: "transparent" - textColor: Theme.surfaceVariantText - onClicked: root.skip() - } - - DankButton { - visible: root.currentPage > 0 - text: I18n.tr("Back", "greeter back button") - iconName: "arrow_back" - backgroundColor: Theme.surfaceContainerHighest - textColor: Theme.surfaceText - onClicked: root.prevPage() - } - - DankButton { - visible: root.currentPage < root.totalPages - 1 - enabled: !(root.currentPage === 1 && pageLoader.item && pageLoader.item.isRunning) - text: root.currentPage === 0 ? I18n.tr("Get Started", "greeter first page button") : I18n.tr("Next", "greeter next button") - iconName: "arrow_forward" - backgroundColor: Theme.primary - textColor: Theme.primaryText - onClicked: root.nextPage() - } - - DankButton { - visible: root.currentPage === root.totalPages - 1 - text: I18n.tr("Finish", "greeter finish button") - iconName: "check" - backgroundColor: Theme.primary - textColor: Theme.primaryText - onClicked: root.finish() - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } - - Component { - id: welcomePage - GreeterWelcomePage {} - } - - Component { - id: doctorPage - GreeterDoctorPage {} - } - - Component { - id: completePage - GreeterCompletePage {} - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml deleted file mode 100644 index d064275..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterQuickLink.qml +++ /dev/null @@ -1,60 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property string iconName: "" - property string title: "" - property bool isExternal: false - - signal clicked - - height: Math.round(Theme.fontSizeMedium * 3.1) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: Theme.primary - opacity: mouseArea.containsMouse ? 0.12 : 0 - } - - Row { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: root.iconName - size: Theme.iconSizeSmall + 2 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: root.title - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - DankIcon { - visible: root.isExternal - name: "open_in_new" - size: Theme.iconSizeSmall - 2 - color: Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.clicked() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml deleted file mode 100644 index 85e6b1c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterSettingsCard.qml +++ /dev/null @@ -1,78 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property string iconName: "" - property string title: "" - property string description: "" - - signal clicked - - readonly property real iconContainerSize: Math.round(Theme.iconSize * 1.5) - - height: Math.round(Theme.fontSizeMedium * 4.5) - radius: Theme.cornerRadius - color: Theme.surfaceContainerHigh - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: Theme.primary - opacity: mouseArea.containsMouse ? 0.12 : 0 - } - - Row { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Theme.spacingM - spacing: Theme.spacingM - - Rectangle { - width: root.iconContainerSize - height: root.iconContainerSize - radius: Math.round(root.iconContainerSize * 0.28) - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: root.iconName - size: Theme.iconSize - 4 - color: Theme.primaryText - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - width: parent.width - root.iconContainerSize - Theme.spacingM - - StyledText { - text: root.title - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.surfaceText - } - - StyledText { - text: root.description - font.pixelSize: Theme.fontSizeSmall - 1 - color: Theme.surfaceVariantText - width: parent.width - elide: Text.ElideRight - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.clicked() - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml deleted file mode 100644 index af0d5d6..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterStatusCard.qml +++ /dev/null @@ -1,75 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property int count: 0 - property string label: "" - property string iconName: "" - property color iconColor: Theme.surfaceText - property color bgColor: Theme.surfaceContainerHigh - property bool selected: false - - signal clicked - - height: Math.round(Theme.fontSizeMedium * 5) - radius: Theme.cornerRadius - color: bgColor - border.width: selected ? 2 : 0 - border.color: selected ? iconColor : "transparent" - scale: mouseArea.pressed ? 0.97 : 1 - - Behavior on scale { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.emphasizedEasing - } - } - - Behavior on border.width { - NumberAnimation { - duration: Theme.shortDuration - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: root.clicked() - } - - Column { - anchors.centerIn: parent - spacing: Theme.spacingXS - - Row { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Theme.spacingS - - DankIcon { - name: root.iconName - size: Theme.iconSize - 4 - color: root.iconColor - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: root.count.toString() - font.pixelSize: Theme.fontSizeXLarge - font.weight: Font.Bold - color: root.iconColor - anchors.verticalCenter: parent.verticalCenter - } - } - - StyledText { - text: root.label - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml deleted file mode 100644 index fcb4fc5..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Greeter/GreeterWelcomePage.qml +++ /dev/null @@ -1,165 +0,0 @@ -import QtQuick -import QtQuick.Effects -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - readonly property real logoSize: Math.round(Theme.iconSize * 5.3) - - Column { - id: mainColumn - anchors.centerIn: parent - width: Math.min(Math.round(Theme.fontSizeMedium * 43), parent.width - Theme.spacingXL * 2) - spacing: Theme.spacingXL - - Column { - width: parent.width - spacing: Theme.spacingM - - Image { - width: root.logoSize - height: width * (569.94629 / 506.50931) - anchors.horizontalCenter: parent.horizontalCenter - fillMode: Image.PreserveAspectFit - smooth: true - mipmap: true - asynchronous: true - source: "file://" + Theme.shellDir + "/assets/danklogonormal.svg" - layer.enabled: true - layer.smooth: true - layer.mipmap: true - layer.effect: MultiEffect { - saturation: 0 - colorization: 1 - colorizationColor: Theme.primary - } - } - - Column { - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Welcome to DankMaterialShell", "greeter welcome page title") - font.pixelSize: Theme.fontSizeXLarge + 4 - font.weight: Font.Bold - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("A modern desktop shell for Wayland compositors", "greeter welcome page tagline") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outlineMedium - opacity: 0.3 - } - - Column { - width: parent.width - spacing: Theme.spacingM - - StyledText { - text: I18n.tr("Features", "greeter welcome page section header") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - } - - Grid { - width: parent.width - columns: 3 - rowSpacing: Theme.spacingS - columnSpacing: Theme.spacingS - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "auto_awesome" - title: I18n.tr("Dynamic Theming", "greeter feature card title") - description: I18n.tr("Colors from wallpaper", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("theme") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "format_paint" - title: I18n.tr("App Theming", "greeter feature card title") - description: I18n.tr("GTK, Qt, IDEs, more", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("theme") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "download" - title: I18n.tr("Theme Registry", "greeter feature card title") - description: I18n.tr("Community themes", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("theme") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "view_carousel" - title: I18n.tr("DankBar", "greeter feature card title") - description: I18n.tr("Modular widget bar", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("dankbar_settings") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "extension" - title: I18n.tr("Plugins", "greeter feature card title") - description: I18n.tr("Extensible architecture", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("plugins") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "layers" - title: I18n.tr("Multi-Monitor", "greeter feature card title") - description: I18n.tr("Per-screen config", "greeter feature card description") - onClicked: { - const hasDisplayConfig = CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl; - PopoutService.openSettingsWithTab(hasDisplayConfig ? "display_config" : "display_widgets"); - } - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "nightlight" - title: I18n.tr("Display Control", "greeter feature card title") - description: I18n.tr("Night mode & gamma", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("display_gamma") - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "tune" - title: I18n.tr("Control Center", "greeter feature card title") - description: I18n.tr("Quick system toggles", "greeter feature card description") - // This is doing an IPC since its just easier and lazier to access the bar ref - onClicked: Quickshell.execDetached(["dms", "ipc", "call", "control-center", "open"]) - } - - GreeterFeatureCard { - width: (parent.width - Theme.spacingS * 2) / 3 - iconName: "lock" - title: I18n.tr("Lock Screen", "greeter feature card title") - description: I18n.tr("Security & privacy", "greeter feature card description") - onClicked: PopoutService.openSettingsWithTab("lock_screen") - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml deleted file mode 100644 index e1d6765..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml +++ /dev/null @@ -1,347 +0,0 @@ -import QtQml -import QtQuick -import QtQuick.Layouts -import Quickshell.Hyprland -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:keybinds" - useOverlayLayer: true - property real scrollStep: 60 - property var activeFlickable: null - property real _maxW: Math.min(Screen.width * 0.92, 1200) - property real _maxH: Math.min(Screen.height * 0.92, 900) - modalWidth: _maxW - modalHeight: _maxH - onBackgroundClicked: close() - onOpened: { - Qt.callLater(() => { - modalFocusScope.forceActiveFocus(); - if (contentLoader.item?.searchField) - contentLoader.item.searchField.forceActiveFocus(); - }); - if (!Object.keys(KeybindsService.cheatsheet).length && KeybindsService.cheatsheetAvailable) - KeybindsService.loadCheatsheet(); - } - - HyprlandFocusGrab { - windows: [root.contentWindow] - active: root.useHyprlandFocusGrab && root.shouldHaveFocus - } - - function scrollDown() { - if (!root.activeFlickable) - return; - let newY = root.activeFlickable.contentY + scrollStep; - newY = Math.min(newY, root.activeFlickable.contentHeight - root.activeFlickable.height); - root.activeFlickable.contentY = newY; - } - - function scrollUp() { - if (!root.activeFlickable) - return; - let newY = root.activeFlickable.contentY - root.scrollStep; - newY = Math.max(0, newY); - root.activeFlickable.contentY = newY; - } - - modalFocusScope.Keys.onPressed: event => { - if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) { - scrollDown(); - event.accepted = true; - } else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) { - scrollUp(); - event.accepted = true; - } else if (event.key === Qt.Key_Down) { - scrollDown(); - event.accepted = true; - } else if (event.key === Qt.Key_Up) { - scrollUp(); - event.accepted = true; - } - } - - content: Component { - Item { - anchors.fill: parent - property alias searchField: searchField - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingL - - RowLayout { - width: parent.width - - StyledText { - Layout.alignment: Qt.AlignLeft - text: KeybindsService.cheatsheet.title || i18n("Keybinds") - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Bold - color: Theme.primary - } - - DankTextField { - id: searchField - Layout.alignment: Qt.AlignRight - leftIconName: "search" - keyForwardTargets: [root.modalFocusScope] - onTextEdited: searchDebounce.restart() - Keys.onEscapePressed: event => { - root.close(); - event.accepted = true; - } - } - } - - Timer { - id: searchDebounce - interval: 50 - repeat: false - onTriggered: { - mainFlickable.categories = mainFlickable.generateCategories(searchField.text); - } - } - - DankFlickable { - id: mainFlickable - width: parent.width - height: parent.height - parent.spacing - 40 - contentWidth: rowLayout.implicitWidth - contentHeight: rowLayout.implicitHeight - clip: true - - Component.onCompleted: root.activeFlickable = mainFlickable - - property var rawBinds: KeybindsService.cheatsheet.binds || {} - - function generateCategories(query) { - const lowerQuery = query ? query.toLowerCase().trim() : ""; - const lowerQueryWords = query.split(/\s+/); - const processed = {}; - - for (const cat in rawBinds) { - const binds = rawBinds[cat]; - const catLower = cat.toLowerCase(); - const subcats = {}; - let hasSubcats = false; - for (let i = 0; i < binds.length; i++) { - const bind = binds[i]; - const keyLower = bind.key.toLowerCase(); - const descLower = bind.desc.toLowerCase(); - const actionLower = bind.action.toLowerCase(); - - if (bind.hideOnOverlay) - continue; - let shouldContinue = false; - for (let j = 0; j < lowerQueryWords.length; j++) { - const word = lowerQueryWords[j]; - if (!( - word.length === 0 || - keyLower.includes(word) || - descLower.includes(word) || - catLower.includes(word) || - actionLower.includes(word) - )) { - shouldContinue = true; - break; - } - } - if (shouldContinue) - continue; - - if (bind.subcat) { - hasSubcats = true; - if (!subcats[bind.subcat]) - subcats[bind.subcat] = []; - subcats[bind.subcat].push(bind); - } else { - if (!subcats["_root"]) - subcats["_root"] = []; - subcats["_root"].push(bind); - } - } - - if (Object.keys(subcats).length === 0) - continue; - - processed[cat] = { - hasSubcats: hasSubcats, - subcats: subcats, - subcatKeys: Object.keys(subcats) - }; - } - - return processed; - } - - property var categories: generateCategories(""); - - function estimateCategoryHeight(catName) { - const catData = categories[catName]; - if (!catData) - return 0; - let bindCount = 0; - for (const key of catData.subcatKeys) { - bindCount += catData.subcats[key]?.length || 0; - if (key !== "_root") - bindCount += 1; - } - return 40 + bindCount * 28; - } - - property var categoryKeys: Object.keys(categories); - - function distributeCategories(cols) { - const columns = []; - const heights = []; - for (let i = 0; i < cols; i++) { - columns.push([]); - heights.push(0); - } - const sorted = [...categoryKeys].sort((a, b) => estimateCategoryHeight(b) - estimateCategoryHeight(a)); - for (const cat of sorted) { - let minIdx = 0; - for (let i = 1; i < cols; i++) { - if (heights[i] < heights[minIdx]) - minIdx = i; - } - columns[minIdx].push(cat); - heights[minIdx] += estimateCategoryHeight(cat); - } - return columns; - } - - Row { - id: rowLayout - width: mainFlickable.width - spacing: Theme.spacingM - - property int numColumns: Math.max(1, Math.min(3, Math.floor(width / 350))) - property var columnCategories: mainFlickable.distributeCategories(numColumns) - - Repeater { - model: rowLayout.numColumns - - Column { - id: masonryColumn - width: (rowLayout.width - rowLayout.spacing * (rowLayout.numColumns - 1)) / rowLayout.numColumns - spacing: Theme.spacingXL - - Repeater { - model: rowLayout.columnCategories[index] || [] - - Column { - id: categoryColumn - width: parent.width - spacing: Theme.spacingXS - - property string catName: modelData - property var catData: mainFlickable.categories[catName] - - StyledText { - text: categoryColumn.catName - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Bold - color: Theme.primary - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.primary - opacity: 0.3 - } - - Item { - width: 1 - height: Theme.spacingXS - } - - Column { - width: parent.width - spacing: Theme.spacingM - - Repeater { - model: categoryColumn.catData?.subcatKeys || [] - - Column { - width: parent.width - spacing: Theme.spacingXS - - property string subcatName: modelData - property var subcatBinds: categoryColumn.catData?.subcats?.[subcatName] || [] - - StyledText { - visible: parent.subcatName !== "_root" - text: parent.subcatName - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.DemiBold - color: Theme.primary - opacity: 0.7 - } - - Column { - width: parent.width - spacing: Theme.spacingXS - - Repeater { - model: parent.parent.subcatBinds - - Item { - width: parent.width - height: 24 - - StyledRect { - id: keyBadge - width: Math.min(keyText.implicitWidth + 12, 160) - height: 22 - radius: 4 - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: keyText - anchors.centerIn: parent - color: Theme.secondary - text: (modelData.key || "").replace(/\+/g, " + ") - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - isMonospace: true - elide: Text.ElideRight - width: Math.min(implicitWidth, 148) - } - } - - StyledText { - anchors.left: parent.left - anchors.leftMargin: 170 - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - text: modelData.desc || modelData.action || "" - font.pixelSize: Theme.fontSizeSmall - opacity: 0.9 - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml deleted file mode 100644 index 9d19388..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/MuxModal.qml +++ /dev/null @@ -1,633 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import Quickshell.Hyprland -import Quickshell.Io -import Quickshell -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: muxModal - - layerNamespace: "dms:mux" - - property int selectedIndex: -1 - property string searchText: "" - property var filteredSessions: [] - - function updateFilteredSessions() { - var filtered = [] - var lowerSearch = searchText.trim().toLowerCase() - for (var i = 0; i < MuxService.sessions.length; i++) { - var session = MuxService.sessions[i] - if (lowerSearch.length > 0 && !session.name.toLowerCase().includes(lowerSearch)) - continue - filtered.push(session) - } - filteredSessions = filtered - - if (selectedIndex >= filteredSessions.length) { - selectedIndex = Math.max(0, filteredSessions.length - 1) - } - } - - onSearchTextChanged: updateFilteredSessions() - - Connections { - target: MuxService - function onSessionsChanged() { - updateFilteredSessions() - } - } - - HyprlandFocusGrab { - id: grab - windows: [muxModal.contentWindow] - active: CompositorService.isHyprland && muxModal.shouldHaveFocus - } - - function toggle() { - if (shouldBeVisible) { - hide() - } else { - show() - } - } - - function show() { - open() - selectedIndex = -1 - searchText = "" - MuxService.refreshSessions() - shouldHaveFocus = true - - Qt.callLater(() => { - if (muxPanel && muxPanel.searchField) { - muxPanel.searchField.forceActiveFocus(); - } - }) - } - - function hide() { - close() - selectedIndex = -1 - searchText = "" - } - - function attachToSession(name) { - MuxService.attachToSession(name) - hide() - } - - function renameSession(name) { - inputModal.showWithOptions({ - title: I18n.tr("Rename Session"), - message: I18n.tr("Enter a new name for session \"%1\"").arg(name), - initialText: name, - onConfirm: function (newName) { - MuxService.renameSession(name, newName) - } - }) - } - - function killSession(name) { - confirmModal.showWithOptions({ - title: I18n.tr("Kill Session"), - message: I18n.tr("Are you sure you want to kill session \"%1\"?").arg(name), - confirmText: I18n.tr("Kill"), - confirmColor: Theme.primary, - onConfirm: function () { - MuxService.killSession(name) - } - }) - } - - function createNewSession() { - inputModal.showWithOptions({ - title: I18n.tr("New Session"), - message: I18n.tr("Please write a name for your new %1 session").arg(MuxService.displayName), - onConfirm: function (name) { - MuxService.createSession(name) - hide() - } - }) - } - - function selectNext() { - selectedIndex = Math.min(selectedIndex + 1, filteredSessions.length - 1) - } - - function selectPrevious() { - selectedIndex = Math.max(selectedIndex - 1, -1) - } - - function activateSelected() { - if (selectedIndex === -1) { - createNewSession() - } else if (selectedIndex >= 0 && selectedIndex < filteredSessions.length) { - attachToSession(filteredSessions[selectedIndex].name) - } - } - - visible: false - modalWidth: 600 - modalHeight: 600 - backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - cornerRadius: Theme.cornerRadius - borderColor: Theme.outlineMedium - borderWidth: 1 - enableShadow: true - keepContentLoaded: true - - onBackgroundClicked: hide() - - Timer { - interval: 3000 - running: muxModal.shouldBeVisible - repeat: true - onTriggered: MuxService.refreshSessions() - } - - IpcHandler { - function open(): string { - muxModal.show() - return "MUX_OPEN_SUCCESS" - } - - function close(): string { - muxModal.hide() - return "MUX_CLOSE_SUCCESS" - } - - function toggle(): string { - muxModal.toggle() - return "MUX_TOGGLE_SUCCESS" - } - - target: "mux" - } - - // Backwards compatibility - IpcHandler { - function open(): string { - muxModal.show() - return "TMUX_OPEN_SUCCESS" - } - - function close(): string { - muxModal.hide() - return "TMUX_CLOSE_SUCCESS" - } - - function toggle(): string { - muxModal.toggle() - return "TMUX_TOGGLE_SUCCESS" - } - - target: "tmux" - } - - InputModal { - id: inputModal - onShouldBeVisibleChanged: { - if (shouldBeVisible) { - muxModal.shouldHaveFocus = false; - muxModal.contentWindow.visible = false; - return; - } - if (muxModal.shouldBeVisible) { - muxModal.contentWindow.visible = true; - } - Qt.callLater(function () { - if (!muxModal.shouldBeVisible) { - return; - } - muxModal.shouldHaveFocus = true; - muxModal.modalFocusScope.forceActiveFocus(); - if (muxPanel.searchField) { - muxPanel.searchField.forceActiveFocus(); - } - }); - } - } - - ConfirmModal { - id: confirmModal - onShouldBeVisibleChanged: { - if (shouldBeVisible) { - muxModal.shouldHaveFocus = false; - muxModal.contentWindow.visible = false; - return; - } - if (muxModal.shouldBeVisible) { - muxModal.contentWindow.visible = true; - } - Qt.callLater(function () { - if (!muxModal.shouldBeVisible) { - return; - } - muxModal.shouldHaveFocus = true; - muxModal.modalFocusScope.forceActiveFocus(); - if (muxPanel.searchField) { - muxPanel.searchField.forceActiveFocus(); - } - }); - } - } - - directContent: Item { - id: muxPanel - - clip: false - - property alias searchField: searchField - - Keys.onPressed: event => { - if ((event.key === Qt.Key_J && (event.modifiers & Qt.ControlModifier)) || - (event.key === Qt.Key_Down)) { - selectNext() - event.accepted = true - } else if ((event.key === Qt.Key_K && (event.modifiers & Qt.ControlModifier)) || - (event.key === Qt.Key_Up)) { - selectPrevious() - event.accepted = true - } else if (event.key === Qt.Key_N && (event.modifiers & Qt.ControlModifier)) { - createNewSession() - event.accepted = true - } else if (event.key === Qt.Key_R && (event.modifiers & Qt.ControlModifier)) { - if (MuxService.supportsRename && selectedIndex >= 0 && selectedIndex < filteredSessions.length) { - renameSession(filteredSessions[selectedIndex].name) - } - event.accepted = true - } else if (event.key === Qt.Key_D && (event.modifiers & Qt.ControlModifier)) { - if (selectedIndex >= 0 && selectedIndex < filteredSessions.length) { - killSession(filteredSessions[selectedIndex].name) - } - event.accepted = true - } else if (event.key === Qt.Key_Escape) { - hide() - event.accepted = true - } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { - activateSelected() - event.accepted = true - } - } - - Column { - width: parent.width - Theme.spacingM * 2 - height: parent.height - Theme.spacingM * 2 - x: Theme.spacingM - y: Theme.spacingM - spacing: Theme.spacingS - - // Header - Item { - width: parent.width - height: 40 - - StyledText { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - text: I18n.tr("%1 Sessions").arg(MuxService.displayName) - font.pixelSize: Theme.fontSizeLarge + 4 - font.weight: Font.Bold - color: Theme.surfaceText - } - - StyledText { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - text: { - const total = MuxService.sessions.length; - const filtered = muxModal.filteredSessions.length; - const activePart = total === 1 - ? I18n.tr("%1 active session").arg(total) - : I18n.tr("%1 active sessions").arg(total); - const filteredPart = filtered === 1 - ? I18n.tr("%1 filtered").arg(filtered) - : I18n.tr("%1 filtered").arg(filtered); - return activePart + ", " + filteredPart; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - } - } - - // Search field - DankTextField { - id: searchField - - width: parent.width - height: 48 - cornerRadius: Theme.cornerRadius - backgroundColor: Theme.surfaceContainerHigh - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: "search" - leftIconSize: Theme.iconSize - leftIconColor: Theme.surfaceVariantText - leftIconFocusedColor: Theme.primary - showClearButton: true - font.pixelSize: Theme.fontSizeMedium - placeholderText: I18n.tr("Search sessions...") - keyForwardTargets: [muxPanel] - - onTextEdited: { - muxModal.searchText = text - muxModal.selectedIndex = 0 - } - } - - // New Session Button - Rectangle { - width: parent.width - height: 56 - radius: Theme.cornerRadius - color: muxModal.selectedIndex === -1 ? Theme.primaryContainer : - (newMouse.containsMouse ? Theme.surfaceContainerHigh : Theme.surfaceContainer) - - RowLayout { - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - Rectangle { - Layout.preferredWidth: 40 - Layout.preferredHeight: 40 - radius: 20 - color: Theme.primaryContainer - - DankIcon { - anchors.centerIn: parent - name: "add" - size: Theme.iconSize - color: Theme.primary - } - } - - Column { - Layout.fillWidth: true - spacing: 2 - - StyledText { - text: I18n.tr("New Session") - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - } - - StyledText { - text: I18n.tr("Create a new %1 session (n)").arg(MuxService.displayName) - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - } - - MouseArea { - id: newMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: muxModal.createNewSession() - } - } - - // Sessions List - Rectangle { - width: parent.width - height: parent.height - 88 - 48 - shortcutsBar.height - Theme.spacingS * 3 - radius: Theme.cornerRadius - color: "transparent" - - ScrollView { - anchors.fill: parent - clip: true - - Column { - width: parent.width - spacing: Theme.spacingXS - - Repeater { - model: ScriptModel { - values: muxModal.filteredSessions - } - - delegate: Rectangle { - required property var modelData - required property int index - - width: parent.width - height: 64 - radius: Theme.cornerRadius - color: muxModal.selectedIndex === index ? Theme.primaryContainer : - (sessionMouse.containsMouse ? Theme.surfaceContainerHigh : "transparent") - - MouseArea { - id: sessionMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: muxModal.attachToSession(modelData.name) - } - - RowLayout { - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - // Avatar - Rectangle { - Layout.preferredWidth: 40 - Layout.preferredHeight: 40 - radius: 20 - color: modelData.attached ? Theme.primaryContainer : Theme.surfaceContainerHigh - - StyledText { - anchors.centerIn: parent - text: modelData.name.charAt(0).toUpperCase() - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Bold - color: modelData.attached ? Theme.primary : Theme.surfaceText - } - } - - // Info - Column { - Layout.fillWidth: true - spacing: 2 - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - elide: Text.ElideRight - } - - StyledText { - text: { - var parts = [] - if (modelData.windows !== "N/A") - parts.push(modelData.windows === 1 - ? I18n.tr("%1 window").arg(modelData.windows) - : I18n.tr("%1 windows").arg(modelData.windows)) - parts.push(modelData.attached ? I18n.tr("attached") : I18n.tr("detached")) - return parts.join(" \u2022 ") - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - - // Rename button (tmux only) - Rectangle { - Layout.preferredWidth: 36 - Layout.preferredHeight: 36 - radius: 18 - visible: MuxService.supportsRename - color: renameMouse.containsMouse ? Theme.surfaceContainerHighest : "transparent" - - DankIcon { - anchors.centerIn: parent - name: "edit" - size: Theme.iconSizeSmall - color: renameMouse.containsMouse ? Theme.primary : Theme.surfaceVariantText - } - - MouseArea { - id: renameMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: muxModal.renameSession(modelData.name) - } - } - - // Delete button - Rectangle { - Layout.preferredWidth: 36 - Layout.preferredHeight: 36 - radius: 18 - color: deleteMouse.containsMouse ? Theme.errorContainer : "transparent" - - DankIcon { - anchors.centerIn: parent - name: "delete" - size: Theme.iconSizeSmall - color: deleteMouse.containsMouse ? Theme.error : Theme.surfaceVariantText - } - - MouseArea { - id: deleteMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - muxModal.killSession(modelData.name) - } - } - } - } - } - } - - // Empty state - Item { - width: parent.width - height: muxModal.filteredSessions.length === 0 ? 200 : 0 - visible: muxModal.filteredSessions.length === 0 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - name: muxModal.searchText.length > 0 ? "search_off" : "terminal" - size: 48 - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: muxModal.searchText.length > 0 ? I18n.tr("No sessions found") : I18n.tr("No active %1 sessions").arg(MuxService.displayName) - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: muxModal.searchText.length > 0 ? I18n.tr("Try a different search") : I18n.tr("Press 'n' or click 'New Session' to create one") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - } - } - - // Shortcuts bar - Row { - id: shortcutsBar - width: parent.width - spacing: Theme.spacingM - bottomPadding: Theme.spacingS - - Repeater { - model: { - var shortcuts = [ - { key: "↑↓", label: I18n.tr("Navigate") }, - { key: "↵", label: I18n.tr("Attach") }, - { key: "^N", label: I18n.tr("New") }, - { key: "^D", label: I18n.tr("Kill") }, - { key: "Esc", label: I18n.tr("Close") } - ] - if (MuxService.supportsRename) - shortcuts.splice(3, 0, { key: "^R", label: I18n.tr("Rename") }) - return shortcuts - } - - delegate: Row { - required property var modelData - spacing: 4 - - Rectangle { - width: keyText.width + Theme.spacingS - height: keyText.height + 4 - radius: 4 - color: Theme.surfaceContainerHighest - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: keyText - anchors.centerIn: parent - text: modelData.key - font.pixelSize: Theme.fontSizeSmall - 1 - font.weight: Font.Medium - color: Theme.surfaceVariantText - } - } - - StyledText { - text: modelData.label - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml deleted file mode 100644 index 79dbada..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkInfoModal.qml +++ /dev/null @@ -1,155 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:network-info" - - keepPopoutsOpen: true - - property bool networkInfoModalVisible: false - property string networkSSID: "" - property var networkData: null - - function showNetworkInfo(ssid, data) { - networkSSID = ssid; - networkData = data; - networkInfoModalVisible = true; - open(); - NetworkService.fetchNetworkInfo(ssid); - } - - function hideDialog() { - networkInfoModalVisible = false; - close(); - networkSSID = ""; - networkData = null; - } - - visible: networkInfoModalVisible - modalWidth: 600 - modalHeight: 500 - enableShadow: true - onBackgroundClicked: hideDialog() - onVisibleChanged: { - if (!visible) { - networkSSID = ""; - networkData = null; - } - } - - content: Component { - Item { - anchors.fill: parent - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingL - - Row { - width: parent.width - - Column { - width: parent.width - 40 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Network Information") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: I18n.tr("Details for \"%1\"").arg(networkSSID) - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - elide: Text.ElideRight - } - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.hideDialog() - } - } - - Rectangle { - id: detailsRect - - width: parent.width - height: parent.height - 140 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: Theme.outlineStrong - border.width: 1 - clip: true - - DankFlickable { - anchors.fill: parent - anchors.margins: Theme.spacingM - contentHeight: detailsText.contentHeight - - StyledText { - id: detailsText - - width: parent.width - text: NetworkService.networkInfoDetails && NetworkService.networkInfoDetails.replace(/\\n/g, '\n') || I18n.tr("No information available") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - wrapMode: Text.WordWrap - } - } - } - - Item { - width: parent.width - height: 40 - - Rectangle { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: Math.max(70, closeText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: closeArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - - StyledText { - id: closeText - - anchors.centerIn: parent - text: I18n.tr("Close") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: closeArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.hideDialog() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml deleted file mode 100644 index 4b42fdc..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NetworkWiredInfoModal.qml +++ /dev/null @@ -1,155 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:network-info-wired" - - keepPopoutsOpen: true - - property bool networkWiredInfoModalVisible: false - property string networkID: "" - property var networkData: null - - function showNetworkInfo(id, data) { - networkID = id; - networkData = data; - networkWiredInfoModalVisible = true; - open(); - NetworkService.fetchWiredNetworkInfo(data.uuid); - } - - function hideDialog() { - networkWiredInfoModalVisible = false; - close(); - networkID = ""; - networkData = null; - } - - visible: networkWiredInfoModalVisible - modalWidth: 600 - modalHeight: 500 - enableShadow: true - onBackgroundClicked: hideDialog() - onVisibleChanged: { - if (!visible) { - networkID = ""; - networkData = null; - } - } - - content: Component { - Item { - anchors.fill: parent - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingL - - Row { - width: parent.width - - Column { - width: parent.width - 40 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Network Information") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: I18n.tr("Details for \"%1\"").arg(networkSSID) - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - elide: Text.ElideRight - } - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.hideDialog() - } - } - - Rectangle { - id: detailsRect - - width: parent.width - height: parent.height - 140 - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: Theme.outlineStrong - border.width: 1 - clip: true - - DankFlickable { - anchors.fill: parent - anchors.margins: Theme.spacingM - contentHeight: detailsText.contentHeight - - StyledText { - id: detailsText - - width: parent.width - text: NetworkService.networkWiredInfoDetails && NetworkService.networkWiredInfoDetails.replace(/\\n/g, '\n') || I18n.tr("No information available") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - wrapMode: Text.WordWrap - } - } - } - - Item { - width: parent.width - height: 40 - - Rectangle { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: Math.max(70, closeText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: closeArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - - StyledText { - id: closeText - - anchors.centerIn: parent - text: I18n.tr("Close") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: closeArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: root.hideDialog() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml deleted file mode 100644 index 8653344..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/NotificationModal.qml +++ /dev/null @@ -1,225 +0,0 @@ -import QtQuick -import Quickshell.Hyprland -import Quickshell.Io -import qs.Common -import qs.Modals.Common -import qs.Modules.Notifications.Center -import qs.Services - -DankModal { - id: notificationModal - - layerNamespace: "dms:notification-center-modal" - - HyprlandFocusGrab { - windows: [notificationModal.contentWindow] - active: notificationModal.useHyprlandFocusGrab && notificationModal.shouldHaveFocus - } - - property bool notificationModalOpen: false - property var notificationListRef: null - property var historyListRef: null - property int currentTab: 0 - - property var notificationHeaderRef: null - - function show() { - notificationModalOpen = true; - currentTab = 0; - NotificationService.onOverlayOpen(); - open(); - modalKeyboardController.reset(); - if (modalKeyboardController && notificationListRef) { - modalKeyboardController.listView = notificationListRef; - modalKeyboardController.rebuildFlatNavigation(); - - Qt.callLater(() => { - modalKeyboardController.keyboardNavigationActive = true; - modalKeyboardController.selectedFlatIndex = 0; - modalKeyboardController.updateSelectedIdFromIndex(); - if (notificationListRef) { - notificationListRef.keyboardActive = true; - notificationListRef.currentIndex = 0; - } - modalKeyboardController.selectionVersion++; - modalKeyboardController.ensureVisible(); - }); - } - } - - function hide() { - notificationModalOpen = false; - NotificationService.onOverlayClose(); - close(); - modalKeyboardController.reset(); - } - - function toggle() { - if (shouldBeVisible) { - hide(); - } else { - show(); - } - } - - function clearAll() { - NotificationService.clearAllNotifications(); - } - - function dismissAllPopups() { - NotificationService.dismissAllPopups(); - } - - modalWidth: Math.min(500, screenWidth - 48) - modalHeight: Math.min(700, screenHeight * 0.85) - backgroundColor: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - visible: false - onBackgroundClicked: hide() - onOpened: () => { - Qt.callLater(() => modalFocusScope.forceActiveFocus()); - } - onShouldBeVisibleChanged: shouldBeVisible => { - if (!shouldBeVisible) { - notificationModalOpen = false; - modalKeyboardController.reset(); - NotificationService.onOverlayClose(); - } - } - modalFocusScope.Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - hide(); - event.accepted = true; - return; - } - - if (event.key === Qt.Key_Left) { - if (notificationHeaderRef && notificationHeaderRef.currentTab > 0) { - notificationHeaderRef.currentTab = 0; - event.accepted = true; - } - return; - } - if (event.key === Qt.Key_Right) { - if (notificationHeaderRef && notificationHeaderRef.currentTab === 0 && SettingsData.notificationHistoryEnabled) { - notificationHeaderRef.currentTab = 1; - event.accepted = true; - } - return; - } - - if (currentTab === 1 && historyListRef) { - historyListRef.handleKey(event); - return; - } - modalKeyboardController.handleKey(event); - } - - NotificationKeyboardController { - id: modalKeyboardController - - listView: null - isOpen: notificationModal.notificationModalOpen - onClose: () => notificationModal.hide() - } - - IpcHandler { - function open(): string { - notificationModal.show(); - return "NOTIFICATION_MODAL_OPEN_SUCCESS"; - } - - function close(): string { - notificationModal.hide(); - return "NOTIFICATION_MODAL_CLOSE_SUCCESS"; - } - - function toggle(): string { - notificationModal.toggle(); - return "NOTIFICATION_MODAL_TOGGLE_SUCCESS"; - } - - function toggleDoNotDisturb(): string { - SessionData.setDoNotDisturb(!SessionData.doNotDisturb); - - return "NOTIFICATION_MODAL_TOGGLE_DND_SUCCESS"; - } - - function getDoNotDisturb(): bool { - return SessionData.doNotDisturb; - } - - function clearAll(): string { - notificationModal.clearAll(); - return "NOTIFICATION_MODAL_CLEAR_ALL_SUCCESS"; - } - - function dismissAllPopups(): string { - notificationModal.dismissAllPopups(); - return "NOTIFICATION_MODAL_DISMISS_ALL_POPUPS_SUCCESS"; - } - - target: "notifications" - } - - content: Component { - Item { - id: notificationKeyHandler - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - anchors.fill: parent - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingM - - NotificationHeader { - id: notificationHeader - keyboardController: modalKeyboardController - onCurrentTabChanged: notificationModal.currentTab = currentTab - Component.onCompleted: notificationModal.notificationHeaderRef = notificationHeader - } - - NotificationSettings { - id: notificationSettings - expanded: notificationHeader.showSettings - } - - KeyboardNavigatedNotificationList { - id: notificationList - width: parent.width - height: parent.height - y - visible: notificationHeader.currentTab === 0 - keyboardController: modalKeyboardController - Component.onCompleted: { - notificationModal.notificationListRef = notificationList; - if (modalKeyboardController) { - modalKeyboardController.listView = notificationList; - modalKeyboardController.rebuildFlatNavigation(); - } - } - } - - HistoryNotificationList { - id: historyList - width: parent.width - height: parent.height - y - visible: notificationHeader.currentTab === 1 - Component.onCompleted: notificationModal.historyListRef = historyList - } - } - - NotificationKeyboardHints { - id: keyboardHints - - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingL - showHints: notificationHeader.currentTab === 0 ? modalKeyboardController.showKeyboardHints : historyList.showKeyboardHints - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml deleted file mode 100644 index 21ddf8f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PolkitAuthModal.qml +++ /dev/null @@ -1,412 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - property string passwordInput: "" - property var currentFlow: PolkitService.agent?.flow - property bool isLoading: false - property bool awaitingFprintForPassword: false - readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2 - - property string polkitEtcPamText: "" - property string polkitLibPamText: "" - property string systemAuthPamText: "" - property string commonAuthPamText: "" - property string passwordAuthPamText: "" - readonly property bool polkitPamHasFprint: { - const polkitText = polkitEtcPamText !== "" ? polkitEtcPamText : polkitLibPamText; - if (!polkitText) - return false; - return pamModuleEnabled(polkitText, "pam_fprintd") || (polkitText.includes("system-auth") && pamModuleEnabled(systemAuthPamText, "pam_fprintd")) || (polkitText.includes("common-auth") && pamModuleEnabled(commonAuthPamText, "pam_fprintd")) || (polkitText.includes("password-auth") && pamModuleEnabled(passwordAuthPamText, "pam_fprintd")); - } - - function stripPamComment(line) { - if (!line) - return ""; - const trimmed = line.trim(); - if (!trimmed || trimmed.startsWith("#")) - return ""; - const hashIdx = trimmed.indexOf("#"); - if (hashIdx >= 0) - return trimmed.substring(0, hashIdx).trim(); - return trimmed; - } - - function pamModuleEnabled(pamText, moduleName) { - if (!pamText || !moduleName) - return false; - const lines = pamText.split(/\r?\n/); - for (let i = 0; i < lines.length; i++) { - const line = stripPamComment(lines[i]); - if (line && line.includes(moduleName)) - return true; - } - return false; - } - - function focusPasswordField() { - passwordField.forceActiveFocus(); - } - - function show() { - passwordInput = ""; - isLoading = false; - awaitingFprintForPassword = false; - visible = true; - Qt.callLater(focusPasswordField); - } - - function hide() { - visible = false; - } - - function _commitSubmit() { - isLoading = true; - awaitingFprintForPassword = false; - currentFlow.submit(passwordInput); - passwordInput = ""; - } - - function submitAuth() { - if (!currentFlow || isLoading) - return; - if (!currentFlow.isResponseRequired) { - awaitingFprintForPassword = true; - return; - } - _commitSubmit(); - } - - function cancelAuth() { - if (isLoading) - return; - awaitingFprintForPassword = false; - if (currentFlow) { - currentFlow.cancelAuthenticationRequest(); - return; - } - hide(); - } - - objectName: "polkitAuthModal" - title: I18n.tr("Authentication") - minimumSize: Qt.size(460, 220) - maximumSize: Qt.size(460, 220) - color: Theme.surfaceContainer - visible: false - - onVisibleChanged: { - if (visible) { - Qt.callLater(focusPasswordField); - return; - } - passwordInput = ""; - isLoading = false; - awaitingFprintForPassword = false; - } - - Connections { - target: PolkitService.agent - enabled: PolkitService.polkitAvailable - - function onAuthenticationRequestStarted() { - show(); - } - - function onIsActiveChanged() { - if (!(PolkitService.agent?.isActive ?? false)) - hide(); - } - } - - Connections { - target: currentFlow - enabled: currentFlow !== null - - function onIsResponseRequiredChanged() { - if (!currentFlow.isResponseRequired) - return; - if (awaitingFprintForPassword && passwordInput !== "") { - _commitSubmit(); - return; - } - awaitingFprintForPassword = false; - isLoading = false; - passwordInput = ""; - passwordField.forceActiveFocus(); - } - - function onAuthenticationSucceeded() { - hide(); - } - - function onAuthenticationFailed() { - isLoading = false; - } - - function onAuthenticationRequestCancelled() { - hide(); - } - } - - FileView { - path: "/etc/pam.d/polkit-1" - printErrors: false - onLoaded: root.polkitEtcPamText = text() - onLoadFailed: root.polkitEtcPamText = "" - } - - FileView { - path: "/usr/lib/pam.d/polkit-1" - printErrors: false - onLoaded: root.polkitLibPamText = text() - onLoadFailed: root.polkitLibPamText = "" - } - - FileView { - path: "/etc/pam.d/system-auth" - printErrors: false - onLoaded: root.systemAuthPamText = text() - onLoadFailed: root.systemAuthPamText = "" - } - - FileView { - path: "/etc/pam.d/common-auth" - printErrors: false - onLoaded: root.commonAuthPamText = text() - onLoadFailed: root.commonAuthPamText = "" - } - - FileView { - path: "/etc/pam.d/password-auth" - printErrors: false - onLoaded: root.passwordAuthPamText = text() - onLoadFailed: root.passwordAuthPamText = "" - } - - FocusScope { - id: contentFocusScope - - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - cancelAuth(); - event.accepted = true; - } - - Item { - id: headerSection - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingM - height: Math.max(titleColumn.implicitHeight, windowButtonRow.implicitHeight) - - MouseArea { - anchors.fill: parent - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - Column { - id: titleColumn - anchors.left: parent.left - anchors.right: windowButtonRow.left - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Authentication Required") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: currentFlow?.message ?? "" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - wrapMode: Text.Wrap - maximumLineCount: 2 - elide: Text.ElideRight - visible: text !== "" - } - - StyledText { - text: currentFlow?.supplementaryMessage ?? "" - font.pixelSize: Theme.fontSizeSmall - color: (currentFlow?.supplementaryIsError ?? false) ? Theme.error : Theme.surfaceTextMedium - width: parent.width - wrapMode: Text.Wrap - maximumLineCount: 2 - elide: Text.ElideRight - opacity: (currentFlow?.supplementaryIsError ?? false) ? 1 : 0.8 - visible: text !== "" - } - } - - Row { - id: windowButtonRow - anchors.right: parent.right - anchors.top: parent.top - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported && windowControls.canMaximize - iconName: root.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - enabled: !isLoading - opacity: enabled ? 1 : 0.5 - onClicked: cancelAuth() - } - } - } - - Column { - id: bottomSection - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - - StyledText { - text: currentFlow?.inputPrompt ?? "" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - width: parent.width - visible: text !== "" - } - - DankTextField { - id: passwordField - - width: parent.width - height: inputFieldHeight - backgroundColor: Theme.surfaceHover - normalBorderColor: Theme.outlineStrong - focusedBorderColor: Theme.primary - borderWidth: 1 - focusedBorderWidth: 2 - leftIconName: polkitPamHasFprint ? "fingerprint" : "" - leftIconSize: 20 - leftIconColor: Theme.primary - leftIconFocusedColor: Theme.primary - opacity: isLoading ? 0.5 : 1 - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: passwordInput - showPasswordToggle: !(currentFlow?.responseVisible ?? false) - echoMode: (currentFlow?.responseVisible ?? false) || passwordVisible ? TextInput.Normal : TextInput.Password - placeholderText: "" - enabled: !isLoading - onTextEdited: passwordInput = text - onAccepted: submitAuth() - } - - StyledText { - text: I18n.tr("Authentication failed, please try again") - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - width: parent.width - visible: currentFlow?.failed ?? false - } - - Item { - width: parent.width - height: 36 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - Rectangle { - width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - enabled: !isLoading - opacity: enabled ? 1 : 0.5 - - StyledText { - id: cancelText - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: parent.enabled - onClicked: cancelAuth() - } - } - - Rectangle { - width: Math.max(80, authText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: authArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - enabled: !isLoading - opacity: enabled ? 1 : 0.5 - - StyledText { - id: authText - anchors.centerIn: parent - text: I18n.tr("Authenticate") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: authArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: parent.enabled - onClicked: submitAuth() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml deleted file mode 100644 index c59037f..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/PowerMenuModal.qml +++ /dev/null @@ -1,809 +0,0 @@ -import QtQuick -import QtQuick.Effects -import Quickshell -import Quickshell.Hyprland -import qs.Common -import qs.Modals.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - - layerNamespace: "dms:power-menu" - keepPopoutsOpen: true - - HyprlandFocusGrab { - windows: [root.contentWindow] - active: root.useHyprlandFocusGrab && root.shouldHaveFocus - } - - property int selectedIndex: 0 - property int selectedRow: 0 - property int selectedCol: 0 - property rect parentBounds: Qt.rect(0, 0, 0, 0) - property var parentScreen: null - property var visibleActions: [] - property int gridColumns: 3 - property int gridRows: 2 - - property string holdAction: "" - property int holdActionIndex: -1 - property real holdProgress: 0 - property bool showHoldHint: false - - readonly property bool needsConfirmation: SettingsData.powerActionConfirm - readonly property int holdDurationMs: SettingsData.powerActionHoldDuration * 1000 - - signal powerActionRequested(string action, string title, string message) - signal lockRequested - - function actionNeedsConfirm(action) { - return action !== "lock" && action !== "restart"; - } - - function startHold(action, actionIndex) { - if (!needsConfirmation || !actionNeedsConfirm(action)) { - executeAction(action); - return; - } - holdAction = action; - holdActionIndex = actionIndex; - holdProgress = 0; - showHoldHint = false; - holdTimer.start(); - } - - function cancelHold() { - if (holdAction === "") - return; - const wasHolding = holdProgress > 0; - holdTimer.stop(); - if (wasHolding && holdProgress < 1) { - showHoldHint = true; - hintTimer.restart(); - } - holdAction = ""; - holdActionIndex = -1; - holdProgress = 0; - } - - function completeHold() { - if (holdProgress < 1) { - cancelHold(); - return; - } - const action = holdAction; - holdTimer.stop(); - holdAction = ""; - holdActionIndex = -1; - holdProgress = 0; - executeAction(action); - } - - function executeAction(action) { - if (action === "lock") { - close(); - lockRequested(); - return; - } - if (action === "restart") { - close(); - Quickshell.execDetached(["dms", "restart"]); - return; - } - close(); - root.powerActionRequested(action, "", ""); - } - - Timer { - id: holdTimer - interval: 16 - repeat: true - onTriggered: { - root.holdProgress = Math.min(1, root.holdProgress + (interval / root.holdDurationMs)); - if (root.holdProgress >= 1) { - stop(); - root.completeHold(); - } - } - } - - Timer { - id: hintTimer - interval: 2000 - onTriggered: root.showHoldHint = false - } - - function openCentered() { - parentBounds = Qt.rect(0, 0, 0, 0); - parentScreen = null; - open(); - } - - function openFromControlCenter(bounds, targetScreen) { - parentBounds = bounds; - parentScreen = targetScreen; - open(); - } - - function updateVisibleActions() { - const allActions = SettingsData.powerMenuActions || ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]; - visibleActions = allActions.filter(action => { - if (action === "hibernate" && !SessionService.hibernateSupported) - return false; - return true; - }); - - if (!SettingsData.powerMenuGridLayout) - return; - const count = visibleActions.length; - if (count === 0) { - gridColumns = 1; - gridRows = 1; - return; - } - - if (count <= 3) { - gridColumns = 1; - gridRows = count; - return; - } - - if (count === 4) { - gridColumns = 2; - gridRows = 2; - return; - } - - gridColumns = 3; - gridRows = Math.ceil(count / 3); - } - - function getDefaultActionIndex() { - const defaultAction = SettingsData.powerMenuDefaultAction || "logout"; - const index = visibleActions.indexOf(defaultAction); - return index >= 0 ? index : 0; - } - - function getActionAtIndex(index) { - if (index < 0 || index >= visibleActions.length) - return ""; - return visibleActions[index]; - } - - function getActionData(action) { - switch (action) { - case "reboot": - return { - "icon": "restart_alt", - "label": I18n.tr("Reboot"), - "key": "R" - }; - case "logout": - return { - "icon": "logout", - "label": I18n.tr("Log Out"), - "key": "X" - }; - case "poweroff": - return { - "icon": "power_settings_new", - "label": I18n.tr("Power Off"), - "key": "P" - }; - case "lock": - return { - "icon": "lock", - "label": I18n.tr("Lock"), - "key": "L" - }; - case "suspend": - return { - "icon": "bedtime", - "label": I18n.tr("Suspend"), - "key": "S" - }; - case "hibernate": - return { - "icon": "ac_unit", - "label": I18n.tr("Hibernate"), - "key": "H" - }; - case "restart": - return { - "icon": "refresh", - "label": I18n.tr("Restart DMS"), - "key": "D" - }; - default: - return { - "icon": "help", - "label": action, - "key": "?" - }; - } - } - - function selectOption(action, actionIndex) { - startHold(action, actionIndex !== undefined ? actionIndex : -1); - } - - shouldBeVisible: false - modalWidth: SettingsData.powerMenuGridLayout ? Math.min(550, gridColumns * 180 + Theme.spacingS * (gridColumns - 1) + Theme.spacingL * 2) : 400 - modalHeight: contentLoader.item ? contentLoader.item.implicitHeight : 300 - enableShadow: true - targetScreen: parentScreen - positioning: parentBounds.width > 0 ? "custom" : "center" - customPosition: { - if (parentBounds.width > 0) { - const effectiveBarThickness = Math.max(26 + (SettingsData.barConfigs[0]?.innerPadding ?? 4) * 0.6 + (SettingsData.barConfigs[0]?.innerPadding ?? 4) + 4, Theme.barHeight - 4 - (8 - (SettingsData.barConfigs[0]?.innerPadding ?? 4))); - const barExclusionZone = effectiveBarThickness + (SettingsData.barConfigs[0]?.spacing ?? 4) + (SettingsData.barConfigs[0]?.bottomGap ?? 0); - const screenW = parentScreen?.width ?? 1920; - const screenH = parentScreen?.height ?? 1080; - const margin = Theme.spacingL; - - let targetX = parentBounds.x + (parentBounds.width - modalWidth) / 2; - let targetY = parentBounds.y + (parentBounds.height - modalHeight) / 2; - - const minY = (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top) === SettingsData.Position.Top ? barExclusionZone + margin : margin; - const maxY = (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top) === SettingsData.Position.Bottom ? screenH - modalHeight - barExclusionZone - margin : screenH - modalHeight - margin; - - targetY = Math.max(minY, Math.min(maxY, targetY)); - - return Qt.point(targetX, targetY); - } - return Qt.point(0, 0); - } - onBackgroundClicked: () => { - cancelHold(); - close(); - } - onOpened: () => { - holdAction = ""; - holdActionIndex = -1; - holdProgress = 0; - showHoldHint = false; - updateVisibleActions(); - const defaultIndex = getDefaultActionIndex(); - if (SettingsData.powerMenuGridLayout) { - selectedRow = Math.floor(defaultIndex / gridColumns); - selectedCol = defaultIndex % gridColumns; - selectedIndex = defaultIndex; - } else { - selectedIndex = defaultIndex; - } - Qt.callLater(() => modalFocusScope.forceActiveFocus()); - } - onDialogClosed: () => { - cancelHold(); - } - Component.onCompleted: updateVisibleActions() - modalFocusScope.Keys.onPressed: event => { - if (event.isAutoRepeat) { - event.accepted = true; - return; - } - if (SettingsData.powerMenuGridLayout) { - handleGridNavigation(event, true); - } else { - handleListNavigation(event, true); - } - } - modalFocusScope.Keys.onReleased: event => { - if (event.isAutoRepeat) { - event.accepted = true; - return; - } - if (SettingsData.powerMenuGridLayout) { - handleGridNavigation(event, false); - } else { - handleListNavigation(event, false); - } - } - - function handleListNavigation(event, isPressed) { - if (!isPressed) { - if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_L || event.key === Qt.Key_S || event.key === Qt.Key_H || event.key === Qt.Key_D || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) { - cancelHold(); - event.accepted = true; - } - return; - } - - switch (event.key) { - case Qt.Key_Up: - case Qt.Key_Backtab: - selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length; - event.accepted = true; - break; - case Qt.Key_Down: - case Qt.Key_Tab: - selectedIndex = (selectedIndex + 1) % visibleActions.length; - event.accepted = true; - break; - case Qt.Key_Return: - case Qt.Key_Enter: - startHold(getActionAtIndex(selectedIndex), selectedIndex); - event.accepted = true; - break; - case Qt.Key_N: - if (event.modifiers & Qt.ControlModifier) { - selectedIndex = (selectedIndex + 1) % visibleActions.length; - event.accepted = true; - } - break; - case Qt.Key_P: - if (!(event.modifiers & Qt.ControlModifier)) { - const idx = visibleActions.indexOf("poweroff"); - startHold("poweroff", idx); - event.accepted = true; - } else { - selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length; - event.accepted = true; - } - break; - case Qt.Key_J: - if (event.modifiers & Qt.ControlModifier) { - selectedIndex = (selectedIndex + 1) % visibleActions.length; - event.accepted = true; - } - break; - case Qt.Key_K: - if (event.modifiers & Qt.ControlModifier) { - selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length; - event.accepted = true; - } - break; - case Qt.Key_R: - startHold("reboot", visibleActions.indexOf("reboot")); - event.accepted = true; - break; - case Qt.Key_X: - startHold("logout", visibleActions.indexOf("logout")); - event.accepted = true; - break; - case Qt.Key_L: - startHold("lock", visibleActions.indexOf("lock")); - event.accepted = true; - break; - case Qt.Key_S: - startHold("suspend", visibleActions.indexOf("suspend")); - event.accepted = true; - break; - case Qt.Key_H: - startHold("hibernate", visibleActions.indexOf("hibernate")); - event.accepted = true; - break; - case Qt.Key_D: - startHold("restart", visibleActions.indexOf("restart")); - event.accepted = true; - break; - } - } - - function handleGridNavigation(event, isPressed) { - if (!isPressed) { - if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_L || event.key === Qt.Key_S || event.key === Qt.Key_H || event.key === Qt.Key_D || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) { - cancelHold(); - event.accepted = true; - } - return; - } - - switch (event.key) { - case Qt.Key_Left: - selectedCol = (selectedCol - 1 + gridColumns) % gridColumns; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - break; - case Qt.Key_Right: - selectedCol = (selectedCol + 1) % gridColumns; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - break; - case Qt.Key_Up: - case Qt.Key_Backtab: - selectedRow = (selectedRow - 1 + gridRows) % gridRows; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - break; - case Qt.Key_Down: - case Qt.Key_Tab: - selectedRow = (selectedRow + 1) % gridRows; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - break; - case Qt.Key_Return: - case Qt.Key_Enter: - startHold(getActionAtIndex(selectedIndex), selectedIndex); - event.accepted = true; - break; - case Qt.Key_N: - if (event.modifiers & Qt.ControlModifier) { - selectedCol = (selectedCol + 1) % gridColumns; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - } - break; - case Qt.Key_P: - if (!(event.modifiers & Qt.ControlModifier)) { - const idx = visibleActions.indexOf("poweroff"); - startHold("poweroff", idx); - event.accepted = true; - } else { - selectedCol = (selectedCol - 1 + gridColumns) % gridColumns; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - } - break; - case Qt.Key_J: - if (event.modifiers & Qt.ControlModifier) { - selectedRow = (selectedRow + 1) % gridRows; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - } - break; - case Qt.Key_K: - if (event.modifiers & Qt.ControlModifier) { - selectedRow = (selectedRow - 1 + gridRows) % gridRows; - selectedIndex = selectedRow * gridColumns + selectedCol; - event.accepted = true; - } - break; - case Qt.Key_R: - startHold("reboot", visibleActions.indexOf("reboot")); - event.accepted = true; - break; - case Qt.Key_X: - startHold("logout", visibleActions.indexOf("logout")); - event.accepted = true; - break; - case Qt.Key_L: - startHold("lock", visibleActions.indexOf("lock")); - event.accepted = true; - break; - case Qt.Key_S: - startHold("suspend", visibleActions.indexOf("suspend")); - event.accepted = true; - break; - case Qt.Key_H: - startHold("hibernate", visibleActions.indexOf("hibernate")); - event.accepted = true; - break; - case Qt.Key_D: - startHold("restart", visibleActions.indexOf("restart")); - event.accepted = true; - break; - } - } - - content: Component { - Item { - anchors.fill: parent - implicitHeight: (SettingsData.powerMenuGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight) + Theme.spacingL * 2 + (root.needsConfirmation ? hintRow.height + Theme.spacingM : 0) - - Grid { - id: buttonGrid - visible: SettingsData.powerMenuGridLayout - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.topMargin: Theme.spacingL - columns: root.gridColumns - columnSpacing: Theme.spacingS - rowSpacing: Theme.spacingS - - Repeater { - model: root.visibleActions - - Rectangle { - id: gridButtonRect - required property int index - required property string modelData - - readonly property var actionData: root.getActionData(modelData) - readonly property bool isSelected: root.selectedIndex === index - readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff" - readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0 - - width: (root.modalWidth - Theme.spacingL * 2 - Theme.spacingS * (root.gridColumns - 1)) / root.gridColumns - height: 100 - radius: Theme.cornerRadius - color: { - if (isSelected) - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); - if (mouseArea.containsMouse) - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08); - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08); - } - border.color: isSelected ? Theme.primary : "transparent" - border.width: isSelected ? 2 : 0 - - Rectangle { - id: gridProgressMask - anchors.fill: parent - radius: parent.radius - visible: false - layer.enabled: true - } - - Item { - anchors.fill: parent - visible: gridButtonRect.isHolding - layer.enabled: gridButtonRect.isHolding - layer.effect: MultiEffect { - maskEnabled: true - maskSource: gridProgressMask - maskSpreadAtMin: 1 - maskThresholdMin: 0.5 - } - - Rectangle { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - width: parent.width * root.holdProgress - color: { - if (gridButtonRect.modelData === "poweroff") - return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3); - if (gridButtonRect.modelData === "reboot") - return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3); - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3); - } - } - } - - Column { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: gridButtonRect.actionData.icon - size: Theme.iconSize + 8 - color: { - if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) { - return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning; - } - return Theme.surfaceText; - } - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: gridButtonRect.actionData.label - font.pixelSize: Theme.fontSizeMedium - color: { - if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) { - return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning; - } - return Theme.surfaceText; - } - font.weight: Font.Medium - anchors.horizontalCenter: parent.horizontalCenter - } - - Rectangle { - width: 20 - height: 16 - radius: 4 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1) - anchors.horizontalCenter: parent.horizontalCenter - - StyledText { - text: gridButtonRect.actionData.key - font.pixelSize: Theme.fontSizeSmall - 1 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) - font.weight: Font.Medium - anchors.centerIn: parent - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: { - root.selectedRow = Math.floor(index / root.gridColumns); - root.selectedCol = index % root.gridColumns; - root.selectedIndex = index; - root.startHold(modelData, index); - } - onReleased: root.cancelHold() - onCanceled: root.cancelHold() - } - } - } - } - - Column { - id: buttonColumn - visible: !SettingsData.powerMenuGridLayout - anchors { - left: parent.left - right: parent.right - top: parent.top - leftMargin: Theme.spacingL - rightMargin: Theme.spacingL - topMargin: Theme.spacingL - } - spacing: Theme.spacingS - - Repeater { - model: root.visibleActions - - Rectangle { - id: listButtonRect - required property int index - required property string modelData - - readonly property var actionData: root.getActionData(modelData) - readonly property bool isSelected: root.selectedIndex === index - readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff" - readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0 - - width: parent.width - height: 56 - radius: Theme.cornerRadius - color: { - if (isSelected) - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); - if (listMouseArea.containsMouse) - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08); - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08); - } - border.color: isSelected ? Theme.primary : "transparent" - border.width: isSelected ? 2 : 0 - - Rectangle { - id: listProgressMask - anchors.fill: parent - radius: parent.radius - visible: false - layer.enabled: true - } - - Item { - anchors.fill: parent - visible: listButtonRect.isHolding - layer.enabled: listButtonRect.isHolding - layer.effect: MultiEffect { - maskEnabled: true - maskSource: listProgressMask - maskSpreadAtMin: 1 - maskThresholdMin: 0.5 - } - - Rectangle { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - width: parent.width * root.holdProgress - color: { - if (listButtonRect.modelData === "poweroff") - return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3); - if (listButtonRect.modelData === "reboot") - return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3); - return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3); - } - } - } - - Row { - anchors { - left: parent.left - right: parent.right - leftMargin: Theme.spacingM - rightMargin: Theme.spacingM - verticalCenter: parent.verticalCenter - } - spacing: Theme.spacingM - - DankIcon { - name: listButtonRect.actionData.icon - size: Theme.iconSize + 4 - color: { - if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) { - return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning; - } - return Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: listButtonRect.actionData.label - font.pixelSize: Theme.fontSizeMedium - color: { - if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) { - return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning; - } - return Theme.surfaceText; - } - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - width: 28 - height: 20 - radius: 4 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1) - anchors { - right: parent.right - rightMargin: Theme.spacingM - verticalCenter: parent.verticalCenter - } - - StyledText { - text: listButtonRect.actionData.key - font.pixelSize: Theme.fontSizeSmall - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) - font.weight: Font.Medium - anchors.centerIn: parent - } - } - - MouseArea { - id: listMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: { - root.selectedIndex = index; - root.startHold(modelData, index); - } - onReleased: root.cancelHold() - onCanceled: root.cancelHold() - } - } - } - } - - Row { - id: hintRow - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.spacingS - spacing: Theme.spacingXS - visible: root.needsConfirmation - opacity: root.showHoldHint ? 1 : 0.5 - - Behavior on opacity { - NumberAnimation { - duration: 150 - } - } - - DankIcon { - name: root.showHoldHint ? "warning" : "touch_app" - size: Theme.fontSizeSmall - color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - readonly property real totalMs: SettingsData.powerActionHoldDuration * 1000 - readonly property int remainingMs: Math.ceil(totalMs * (1 - root.holdProgress)) - text: { - if (root.showHoldHint) - return I18n.tr("Hold longer to confirm"); - if (root.holdProgress > 0) { - if (totalMs < 1000) - return I18n.tr("Hold to confirm (%1 ms)").arg(remainingMs); - return I18n.tr("Hold to confirm (%1s)").arg(Math.ceil(remainingMs / 1000)); - } - if (totalMs < 1000) - return I18n.tr("Hold to confirm (%1 ms)").arg(totalMs); - return I18n.tr("Hold to confirm (%1s)").arg(SettingsData.powerActionHoldDuration); - } - font.pixelSize: Theme.fontSizeSmall - color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) - anchors.verticalCenter: parent.verticalCenter - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml deleted file mode 100644 index 8cfc705..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/ProcessListModal.qml +++ /dev/null @@ -1,609 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import Quickshell -import Quickshell.Wayland -import qs.Common -import qs.Modules.ProcessList -import qs.Services -import qs.Widgets - -FloatingWindow { - id: processListModal - - property bool disablePopupTransparency: true - property int currentTab: 0 - property string searchText: "" - property string expandedPid: "" - property string processFilter: "all" - property bool shouldHaveFocus: visible - property alias shouldBeVisible: processListModal.visible - - signal closingModal - - function show() { - if (!DgopService.dgopAvailable) { - console.warn("ProcessListModal: dgop is not available"); - return; - } - visible = true; - } - - function hide() { - visible = false; - if (processContextMenu.visible) - processContextMenu.close(); - } - - function toggle() { - if (!DgopService.dgopAvailable) { - console.warn("ProcessListModal: dgop is not available"); - return; - } - visible = !visible; - } - - function focusOrToggle() { - if (!DgopService.dgopAvailable) { - console.warn("ProcessListModal: dgop is not available"); - return; - } - if (visible) { - const modalTitle = I18n.tr("System Monitor", "sysmon window title"); - for (const toplevel of ToplevelManager.toplevels.values) { - if (toplevel.title !== "System Monitor" && toplevel.title !== modalTitle) - continue; - if (toplevel.activated) { - hide(); - return; - } - toplevel.activate(); - return; - } - } - show(); - } - - function formatBytes(bytes) { - if (bytes < 1024) - return bytes.toFixed(0) + " B/s"; - if (bytes < 1024 * 1024) - return (bytes / 1024).toFixed(1) + " KB/s"; - if (bytes < 1024 * 1024 * 1024) - return (bytes / (1024 * 1024)).toFixed(1) + " MB/s"; - return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB/s"; - } - - function nextTab() { - currentTab = (currentTab + 1) % 4; - } - - function previousTab() { - currentTab = (currentTab - 1 + 4) % 4; - } - - objectName: "processListModal" - title: I18n.tr("System Monitor", "sysmon window title") - minimumSize: Qt.size(Math.min(Math.round(Theme.fontSizeMedium * 48), Screen.width), Math.min(Math.round(Theme.fontSizeMedium * 34), Screen.height)) - implicitWidth: Math.round(Theme.fontSizeMedium * 71) - implicitHeight: Math.round(Theme.fontSizeMedium * 51) - color: Theme.surfaceContainer - visible: false - - onCurrentTabChanged: { - if (visible && currentTab === 0 && searchField.visible) - searchField.forceActiveFocus(); - } - - onVisibleChanged: { - if (!visible) { - closingModal(); - searchText = ""; - expandedPid = ""; - processFilter = "all"; - processFilterGroup.currentIndex = 0; - if (processesTabLoader.item) - processesTabLoader.item.reset(); - DgopService.removeRef(["cpu", "memory", "network", "disk", "system"]); - } else { - DgopService.addRef(["cpu", "memory", "network", "disk", "system"]); - Qt.callLater(() => { - if (currentTab === 0 && searchField.visible) - searchField.forceActiveFocus(); - else if (contentFocusScope) - contentFocusScope.forceActiveFocus(); - }); - } - } - - ProcessContextMenu { - id: processContextMenu - parentFocusItem: contentFocusScope - onProcessKilled: { - if (processesTabLoader.item) - processesTabLoader.item.forceRefresh(3); - } - } - - FocusScope { - id: contentFocusScope - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - anchors.fill: parent - focus: true - - Keys.onPressed: event => { - if (processContextMenu.visible) - return; - - switch (event.key) { - case Qt.Key_1: - currentTab = 0; - event.accepted = true; - return; - case Qt.Key_2: - currentTab = 1; - event.accepted = true; - return; - case Qt.Key_3: - currentTab = 2; - event.accepted = true; - return; - case Qt.Key_4: - currentTab = 3; - event.accepted = true; - return; - case Qt.Key_Tab: - nextTab(); - event.accepted = true; - return; - case Qt.Key_Backtab: - previousTab(); - event.accepted = true; - return; - case Qt.Key_Escape: - if (searchText.length > 0) { - searchText = ""; - event.accepted = true; - return; - } - if (currentTab === 0 && processesTabLoader.item?.keyboardNavigationActive) { - processesTabLoader.item.reset(); - event.accepted = true; - return; - } - hide(); - event.accepted = true; - return; - case Qt.Key_F: - if (event.modifiers & Qt.ControlModifier) { - searchField.forceActiveFocus(); - event.accepted = true; - return; - } - break; - } - - if (currentTab === 0 && processesTabLoader.item) - processesTabLoader.item.handleKey(event); - } - - Rectangle { - anchors.centerIn: parent - width: 400 - height: 200 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1) - border.color: Theme.error - border.width: 2 - visible: !DgopService.dgopAvailable - - Column { - anchors.centerIn: parent - spacing: Theme.spacingL - - DankIcon { - name: "error" - size: 48 - color: Theme.error - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("System Monitor Unavailable") - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Bold - color: Theme.error - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("The 'dgop' tool is required for system monitoring.\nPlease install dgop to use this feature.", "dgop unavailable error message") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - } - } - } - - ColumnLayout { - anchors.fill: parent - spacing: 0 - visible: DgopService.dgopAvailable - - Item { - Layout.fillWidth: true - Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.4) - - MouseArea { - anchors.fill: parent - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - Row { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingL - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: "analytics" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("System Monitor") - font.pixelSize: Theme.fontSizeXLarge - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported - circular: false - iconName: processListModal.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - circular: false - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: processListModal.hide() - } - } - } - - RowLayout { - Layout.fillWidth: true - Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 3.7) - Layout.leftMargin: Theme.spacingL - Layout.rightMargin: Theme.spacingL - spacing: Theme.spacingM - - Row { - spacing: 2 - - Repeater { - model: [ - { - text: I18n.tr("Processes"), - icon: "list_alt" - }, - { - text: I18n.tr("Performance"), - icon: "analytics" - }, - { - text: I18n.tr("Disks"), - icon: "storage" - }, - { - text: I18n.tr("System"), - icon: "computer" - } - ] - - Rectangle { - width: tabRowContent.implicitWidth + Theme.spacingM * 2 - height: Math.round(Theme.fontSizeMedium * 3.1) - radius: Theme.cornerRadius - color: currentTab === index ? Theme.primaryPressed : (tabMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent") - border.color: currentTab === index ? Theme.primary : "transparent" - border.width: currentTab === index ? 1 : 0 - - Row { - id: tabRowContent - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: modelData.icon - size: Theme.iconSize - 2 - color: currentTab === index ? Theme.primary : Theme.surfaceText - opacity: currentTab === index ? 1 : 0.7 - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: modelData.text - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: currentTab === index ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: tabMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: currentTab = index - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - } - } - } - } - } - - Item { - Layout.fillWidth: true - } - - DankButtonGroup { - id: processFilterGroup - model: [I18n.tr("All"), I18n.tr("User"), I18n.tr("System")] - currentIndex: 0 - checkEnabled: false - buttonHeight: Math.round(Theme.fontSizeSmall * 2.6) - minButtonWidth: 0 - buttonPadding: Theme.spacingS - textSize: Theme.fontSizeSmall - visible: currentTab === 0 - onSelectionChanged: (index, selected) => { - if (!selected) - return; - currentIndex = index; - switch (index) { - case 0: - processListModal.processFilter = "all"; - return; - case 1: - processListModal.processFilter = "user"; - return; - case 2: - processListModal.processFilter = "system"; - return; - } - } - } - - DankTextField { - id: searchField - Layout.fillWidth: true - Layout.maximumWidth: Math.round(Theme.fontSizeMedium * 18) - Layout.minimumWidth: Theme.fontSizeMedium * 4 - Layout.preferredHeight: Math.round(Theme.fontSizeMedium * 2.8) - placeholderText: I18n.tr("Search processes...", "process search placeholder") - leftIconName: "search" - showClearButton: true - text: searchText - visible: currentTab === 0 - onTextChanged: searchText = text - ignoreUpDownKeys: true - keyForwardTargets: [contentFocusScope] - } - } - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.margins: Theme.spacingL - Layout.topMargin: Theme.spacingM - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Theme.outlineLight - border.width: 1 - clip: true - - Loader { - id: processesTabLoader - anchors.fill: parent - anchors.margins: Theme.spacingS - active: processListModal.visible && currentTab === 0 - visible: currentTab === 0 - sourceComponent: ProcessesView { - searchText: processListModal.searchText - expandedPid: processListModal.expandedPid - processFilter: processListModal.processFilter - contextMenu: processContextMenu - onExpandedPidChanged: processListModal.expandedPid = expandedPid - } - } - - Loader { - id: performanceTabLoader - anchors.fill: parent - anchors.margins: Theme.spacingS - active: processListModal.visible && currentTab === 1 - visible: currentTab === 1 - sourceComponent: PerformanceView {} - } - - Loader { - id: disksTabLoader - anchors.fill: parent - anchors.margins: Theme.spacingS - active: processListModal.visible && currentTab === 2 - visible: currentTab === 2 - sourceComponent: DisksView {} - } - - Loader { - id: systemTabLoader - anchors.fill: parent - anchors.margins: Theme.spacingS - active: processListModal.visible && currentTab === 3 - visible: currentTab === 3 - sourceComponent: SystemView {} - } - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: Math.round(Theme.fontSizeSmall * 2.7) - Layout.leftMargin: Theme.spacingL - Layout.rightMargin: Theme.spacingL - Layout.bottomMargin: Theme.spacingM - color: "transparent" - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingL - - Row { - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Processes:", "process count label in footer") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: DgopService.processCount.toString() - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Bold - color: Theme.surfaceText - } - } - - Row { - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Uptime:", "uptime label in footer") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: DgopService.shortUptime || "--" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Bold - color: Theme.surfaceText - } - } - } - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingL - - Row { - spacing: Theme.spacingXS - - DankIcon { - name: "swap_horiz" - size: 14 - color: Theme.info - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: "↓" + formatBytes(DgopService.networkRxRate) + " ↑" + formatBytes(DgopService.networkTxRate) - font.pixelSize: Theme.fontSizeSmall - font.family: SettingsData.monoFontFamily - color: Theme.surfaceText - } - } - - Row { - spacing: Theme.spacingXS - - DankIcon { - name: "storage" - size: 14 - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: "↓" + formatBytes(DgopService.diskReadRate) + " ↑" + formatBytes(DgopService.diskWriteRate) - font.pixelSize: Theme.fontSizeSmall - font.family: SettingsData.monoFontFamily - color: Theme.surfaceText - } - } - - Row { - spacing: Theme.spacingXS - - DankIcon { - name: "memory" - size: 14 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: DgopService.cpuUsage.toFixed(1) + "%" - font.pixelSize: Theme.fontSizeSmall - font.family: SettingsData.monoFontFamily - font.weight: Font.Bold - color: DgopService.cpuUsage > 80 ? Theme.error : Theme.surfaceText - } - } - - Row { - spacing: Theme.spacingXS - - DankIcon { - name: "sd_card" - size: 14 - color: Theme.secondary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: DgopService.formatSystemMemory(DgopService.usedMemoryKB) + " / " + DgopService.formatSystemMemory(DgopService.totalMemoryKB) - font.pixelSize: Theme.fontSizeSmall - font.family: SettingsData.monoFontFamily - font.weight: Font.Bold - color: DgopService.memoryUsage > 90 ? Theme.error : Theme.surfaceText - } - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: processListModal - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml deleted file mode 100644 index 29b4961..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/ProfileSection.qml +++ /dev/null @@ -1,144 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - property var parentModal: null - - width: parent.width - Theme.spacingS * 2 - height: 110 - radius: Theme.cornerRadius - color: "transparent" - border.width: 0 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - Item { - id: profileImageContainer - - width: 80 - height: 80 - anchors.verticalCenter: parent.verticalCenter - - DankCircularImage { - id: profileImage - - anchors.fill: parent - imageSource: { - if (PortalService.profileImage === "") { - return ""; - } - if (PortalService.profileImage.startsWith("/")) { - return "file://" + PortalService.profileImage; - } - return PortalService.profileImage; - } - fallbackIcon: "person" - } - - Rectangle { - anchors.fill: parent - radius: width / 2 - color: Qt.rgba(0, 0, 0, 0.7) - visible: profileMouseArea.containsMouse - - Row { - anchors.centerIn: parent - spacing: 4 - - Rectangle { - width: 28 - height: 28 - radius: 14 - color: Qt.rgba(255, 255, 255, 0.9) - - DankIcon { - anchors.centerIn: parent - name: "edit" - size: 16 - color: "black" - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: () => { - if (root.parentModal) { - root.parentModal.allowFocusOverride = true; - root.parentModal.shouldHaveFocus = false; - root.parentModal.openProfileBrowser(); - } - } - } - } - - Rectangle { - width: 28 - height: 28 - radius: 14 - color: Qt.rgba(255, 255, 255, 0.9) - visible: profileImage.hasImage - - DankIcon { - anchors.centerIn: parent - name: "close" - size: 16 - color: "black" - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: () => { - return PortalService.setProfileImage(""); - } - } - } - } - } - - MouseArea { - id: profileMouseArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - propagateComposedEvents: true - acceptedButtons: Qt.NoButton - } - } - - Column { - width: 120 - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - StyledText { - text: UserInfoService.fullName || "User" - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Medium - color: Theme.surfaceText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: DgopService.hostname || "DMS" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml deleted file mode 100644 index 34cd51a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsContent.qml +++ /dev/null @@ -1,522 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modules.Settings - -FocusScope { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property int currentIndex: 0 - property var parentModal: null - - focus: true - - Rectangle { - anchors.fill: parent - anchors.leftMargin: Theme.spacingS - anchors.rightMargin: (parentModal && parentModal.isCompactMode) ? Theme.spacingS : (32 + Theme.spacingS) - anchors.bottomMargin: 0 - anchors.topMargin: 0 - color: "transparent" - - Loader { - id: wallpaperLoader - anchors.fill: parent - active: root.currentIndex === 0 - visible: active - focus: active - - sourceComponent: Component { - WallpaperTab { - parentModal: root.parentModal - } - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: timeWeatherLoader - anchors.fill: parent - active: root.currentIndex === 1 - visible: active - focus: active - - sourceComponent: TimeWeatherTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: keybindsLoader - anchors.fill: parent - active: root.currentIndex === 2 - visible: active - focus: active - - sourceComponent: KeybindsTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: topBarLoader - anchors.fill: parent - active: root.currentIndex === 3 - visible: active - focus: active - - sourceComponent: DankBarTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: workspacesLoader - anchors.fill: parent - active: root.currentIndex === 4 - visible: active - focus: active - - sourceComponent: WorkspacesTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: dockLoader - anchors.fill: parent - active: root.currentIndex === 5 - visible: active - focus: active - - sourceComponent: Component { - DockTab {} - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: displayConfigLoader - anchors.fill: parent - active: root.currentIndex === 24 - visible: active - focus: active - - sourceComponent: DisplayConfigTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: gammaControlLoader - anchors.fill: parent - active: root.currentIndex === 25 - visible: active - focus: active - - sourceComponent: GammaControlTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: displayWidgetsLoader - anchors.fill: parent - active: root.currentIndex === 26 - visible: active - focus: active - - sourceComponent: DisplayWidgetsTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: networkLoader - anchors.fill: parent - active: root.currentIndex === 7 - visible: active - focus: active - - sourceComponent: NetworkTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: printerLoader - anchors.fill: parent - active: root.currentIndex === 8 - visible: active - focus: active - - sourceComponent: PrinterTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: launcherLoader - anchors.fill: parent - active: root.currentIndex === 9 - visible: active - focus: active - - sourceComponent: LauncherTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: themeColorsLoader - anchors.fill: parent - active: root.currentIndex === 10 - visible: active - focus: active - - sourceComponent: ThemeColorsTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: lockScreenLoader - anchors.fill: parent - active: root.currentIndex === 11 - visible: active - focus: active - - sourceComponent: LockScreenTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: greeterLoader - anchors.fill: parent - active: root.currentIndex === 31 - visible: active - focus: active - - sourceComponent: GreeterTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: pluginsLoader - anchors.fill: parent - active: root.currentIndex === 12 - visible: active - focus: active - - sourceComponent: PluginsTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: aboutLoader - anchors.fill: parent - active: root.currentIndex === 13 - visible: active - focus: active - - sourceComponent: AboutTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: typographyMotionLoader - anchors.fill: parent - active: root.currentIndex === 14 - visible: active - focus: active - - sourceComponent: TypographyMotionTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: soundsLoader - anchors.fill: parent - active: root.currentIndex === 15 - visible: active - focus: active - - sourceComponent: SoundsTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: mediaPlayerLoader - anchors.fill: parent - active: root.currentIndex === 16 - visible: active - focus: active - - sourceComponent: MediaPlayerTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: notificationsLoader - anchors.fill: parent - active: root.currentIndex === 17 - visible: active - focus: active - - sourceComponent: NotificationsTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: osdLoader - anchors.fill: parent - active: root.currentIndex === 18 - visible: active - focus: active - - sourceComponent: OSDTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: runningAppsLoader - anchors.fill: parent - active: root.currentIndex === 19 - visible: active - focus: active - - sourceComponent: RunningAppsTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: systemUpdaterLoader - anchors.fill: parent - active: root.currentIndex === 20 - visible: active - focus: active - - sourceComponent: SystemUpdaterTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: powerSleepLoader - anchors.fill: parent - active: root.currentIndex === 21 - visible: active - focus: active - - sourceComponent: PowerSleepTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: widgetsLoader - anchors.fill: parent - active: root.currentIndex === 22 - visible: active - focus: active - - sourceComponent: WidgetsTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: clipboardLoader - anchors.fill: parent - active: root.currentIndex === 23 - visible: active - focus: active - - sourceComponent: ClipboardTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: desktopWidgetsLoader - anchors.fill: parent - active: root.currentIndex === 27 - visible: active - focus: active - - sourceComponent: DesktopWidgetsTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: windowRulesLoader - anchors.fill: parent - active: root.currentIndex === 28 - visible: active - focus: active - - sourceComponent: WindowRulesTab { - parentModal: root.parentModal - } - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: audioLoader - anchors.fill: parent - active: root.currentIndex === 29 - visible: active - focus: active - - sourceComponent: AudioTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: localeLoader - anchors.fill: parent - active: root.currentIndex === 30 - visible: active - focus: active - - sourceComponent: LocaleTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - - Loader { - id: muxLoader - anchors.fill: parent - active: root.currentIndex === 32 - visible: active - focus: active - - sourceComponent: MuxTab {} - - onActiveChanged: { - if (active && item) - Qt.callLater(() => item.forceActiveFocus()); - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml deleted file mode 100644 index 9ce9153..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsModal.qml +++ /dev/null @@ -1,382 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Modals.FileBrowser -import qs.Services -import qs.Widgets - -FloatingWindow { - id: settingsModal - - property bool disablePopupTransparency: true - property var profileBrowser: profileBrowserLoader.item - property var wallpaperBrowser: wallpaperBrowserLoader.item - - function openProfileBrowser(allowStacking) { - profileBrowserLoader.active = true; - if (!profileBrowserLoader.item) - return; - if (allowStacking !== undefined) - profileBrowserLoader.item.allowStacking = allowStacking; - profileBrowserLoader.item.open(); - } - - function openWallpaperBrowser(allowStacking) { - wallpaperBrowserLoader.active = true; - if (!wallpaperBrowserLoader.item) - return; - if (allowStacking !== undefined) - wallpaperBrowserLoader.item.allowStacking = allowStacking; - wallpaperBrowserLoader.item.open(); - } - property alias sidebar: sidebar - property int currentTabIndex: 0 - property bool shouldHaveFocus: visible - property bool allowFocusOverride: false - property alias shouldBeVisible: settingsModal.visible - property bool isCompactMode: width < 700 - property bool menuVisible: !isCompactMode - property bool enableAnimations: true - - signal closingModal - - function show() { - visible = true; - } - - function hide() { - visible = false; - } - - function toggle() { - visible = !visible; - } - - function showWithTab(tabIndex: int) { - if (tabIndex >= 0) { - currentTabIndex = tabIndex; - sidebar.autoExpandForTab(tabIndex); - } - visible = true; - } - - function showWithTabName(tabName: string) { - var idx = sidebar.resolveTabIndex(tabName); - if (idx >= 0) { - currentTabIndex = idx; - sidebar.autoExpandForTab(idx); - } - visible = true; - } - - function resolveTabIndex(tabName: string): int { - return sidebar.resolveTabIndex(tabName); - } - - function toggleMenu() { - enableAnimations = true; - menuVisible = !menuVisible; - } - - objectName: "settingsModal" - title: I18n.tr("Settings", "settings window title") - minimumSize: Qt.size(500, 400) - implicitWidth: 900 - implicitHeight: screen ? Math.min(940, screen.height - 100) : 940 - color: Theme.surfaceContainer - visible: false - - onIsCompactModeChanged: { - enableAnimations = false; - if (!isCompactMode) { - menuVisible = true; - } - Qt.callLater(() => { - enableAnimations = true; - }); - } - - onVisibleChanged: { - if (!visible) { - closingModal(); - } else { - Qt.callLater(() => { - sidebar.focusSearch(); - }); - } - } - - Loader { - active: settingsModal.visible - sourceComponent: Component { - Ref { - service: CupsService - } - } - } - - LazyLoader { - id: profileBrowserLoader - active: false - - FileBrowserModal { - id: profileBrowserItem - - allowStacking: true - parentModal: settingsModal - browserTitle: I18n.tr("Select Profile Image", "profile image file browser title") - browserIcon: "person" - browserType: "profile" - showHiddenFiles: true - fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif", "*.exr"] - onFileSelected: path => { - PortalService.setProfileImage(path); - close(); - } - onDialogClosed: () => { - allowStacking = true; - } - } - } - - LazyLoader { - id: wallpaperBrowserLoader - active: false - - FileBrowserModal { - id: wallpaperBrowserItem - - allowStacking: true - parentModal: settingsModal - browserTitle: I18n.tr("Select Wallpaper", "wallpaper file browser title") - browserIcon: "wallpaper" - browserType: "wallpaper" - showHiddenFiles: true - fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif", "*.exr"] - onFileSelected: path => { - SessionData.setWallpaper(path); - close(); - } - onDialogClosed: () => { - allowStacking = true; - } - } - } - - FocusScope { - id: contentFocusScope - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - anchors.fill: parent - focus: true - - Column { - anchors.fill: parent - spacing: 0 - - Item { - width: parent.width - height: 48 - z: 10 - - MouseArea { - anchors.fill: parent - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - Rectangle { - anchors.fill: parent - color: Theme.surfaceContainer - opacity: 0.5 - } - - Row { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingL - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankActionButton { - visible: settingsModal.isCompactMode - circular: false - iconName: "menu" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - onClicked: () => { - settingsModal.toggleMenu(); - } - } - - DankIcon { - name: "settings" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Settings") - font.pixelSize: Theme.fontSizeXLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Row { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.top: parent.top - anchors.topMargin: Theme.spacingM - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported - circular: false - iconName: settingsModal.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - circular: false - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: settingsModal.hide() - } - } - } - - Rectangle { - id: readOnlyBanner - - property bool showBanner: (SettingsData._isReadOnly && SettingsData._hasUnsavedChanges) || (SessionData._isReadOnly && SessionData._hasUnsavedChanges) - - width: parent.width - height: showBanner ? bannerContent.implicitHeight + Theme.spacingM * 2 : 0 - color: Theme.surfaceContainerHigh - visible: showBanner - clip: true - - Behavior on height { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - Row { - id: bannerContent - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingL - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - DankIcon { - name: "info" - size: Theme.iconSize - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - id: bannerText - - text: I18n.tr("Settings are read-only. Changes will not persist.", "read-only settings warning for NixOS home-manager users") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - width: Math.max(100, parent.width - (copySettingsButton.visible ? copySettingsButton.width + Theme.spacingM : 0) - (copySessionButton.visible ? copySessionButton.width + Theme.spacingM : 0) - Theme.spacingM * 2 - Theme.iconSize) - wrapMode: Text.WordWrap - } - - DankButton { - id: copySettingsButton - - visible: SettingsData._isReadOnly && SettingsData._hasUnsavedChanges - text: "settings.json" - iconName: "content_copy" - backgroundColor: Theme.primary - textColor: Theme.primaryText - buttonHeight: 32 - horizontalPadding: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - onClicked: { - Quickshell.execDetached(["dms", "cl", "copy", SettingsData.getCurrentSettingsJson()]); - ToastService.showInfo(I18n.tr("Copied to clipboard")); - } - } - - DankButton { - id: copySessionButton - - visible: SessionData._isReadOnly && SessionData._hasUnsavedChanges - text: "session.json" - iconName: "content_copy" - backgroundColor: Theme.primary - textColor: Theme.primaryText - buttonHeight: 32 - horizontalPadding: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - onClicked: { - Quickshell.execDetached(["dms", "cl", "copy", SessionData.getCurrentSessionJson()]); - ToastService.showInfo(I18n.tr("Copied to clipboard")); - } - } - } - } - - Item { - width: parent.width - height: parent.height - 48 - readOnlyBanner.height - clip: true - - SettingsSidebar { - id: sidebar - - anchors.left: parent.left - width: settingsModal.isCompactMode ? parent.width : sidebar.implicitWidth - visible: settingsModal.isCompactMode ? settingsModal.menuVisible : true - parentModal: settingsModal - currentIndex: settingsModal.currentTabIndex - onTabChangeRequested: tabIndex => { - settingsModal.currentTabIndex = tabIndex; - if (settingsModal.isCompactMode) { - settingsModal.enableAnimations = true; - settingsModal.menuVisible = false; - } - } - } - - Item { - anchors.left: settingsModal.isCompactMode ? (settingsModal.menuVisible ? sidebar.right : parent.left) : sidebar.right - anchors.right: parent.right - height: parent.height - clip: true - - SettingsContent { - id: content - - anchors.fill: parent - parentModal: settingsModal - currentIndex: settingsModal.currentTabIndex - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: settingsModal - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml deleted file mode 100644 index 092881c..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/Settings/SettingsSidebar.qml +++ /dev/null @@ -1,1023 +0,0 @@ -pragma ComponentBehavior: Bound - -import QtQuick -import Quickshell -import qs.Common -import qs.Modals.Settings -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property int currentIndex: 0 - property var parentModal: null - - signal tabChangeRequested(int tabIndex) - property string _expandedIds: "," - property string _collapsedIds: "," - property string _autoExpandedIds: "," - property bool searchActive: searchField.text.length > 0 - property int searchSelectedIndex: 0 - property int keyboardHighlightIndex: -1 - - function focusSearch() { - searchField.forceActiveFocus(); - } - - function highlightNext() { - var flatItems = getFlatNavigableItems(); - if (flatItems.length === 0) - return; - var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex); - if (currentPos === -1) { - currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); - } - var nextPos = (currentPos + 1) % flatItems.length; - keyboardHighlightIndex = flatItems[nextPos].tabIndex; - autoExpandForTab(keyboardHighlightIndex); - } - - function highlightPrevious() { - var flatItems = getFlatNavigableItems(); - if (flatItems.length === 0) - return; - var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex); - if (currentPos === -1) { - currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); - } - var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length; - keyboardHighlightIndex = flatItems[prevPos].tabIndex; - autoExpandForTab(keyboardHighlightIndex); - } - - function selectHighlighted() { - if (keyboardHighlightIndex < 0) - return; - var oldIndex = currentIndex; - var newIndex = keyboardHighlightIndex; - tabChangeRequested(newIndex); - autoCollapseIfNeeded(oldIndex, newIndex); - keyboardHighlightIndex = -1; - Qt.callLater(searchField.forceActiveFocus); - } - - readonly property var categoryStructure: [ - { - "id": "personalization", - "text": I18n.tr("Personalization"), - "icon": "palette", - "children": [ - { - "id": "wallpaper", - "text": I18n.tr("Wallpaper"), - "icon": "wallpaper", - "tabIndex": 0 - }, - { - "id": "theme", - "text": I18n.tr("Theme & Colors"), - "icon": "format_paint", - "tabIndex": 10 - }, - { - "id": "typography", - "text": I18n.tr("Typography & Motion"), - "icon": "text_fields", - "tabIndex": 14 - }, - { - "id": "time_weather", - "text": I18n.tr("Time & Weather"), - "icon": "schedule", - "tabIndex": 1 - }, - { - "id": "sounds", - "text": I18n.tr("Sounds"), - "icon": "volume_up", - "tabIndex": 15, - "soundsOnly": true - } - ] - }, - { - "id": "dankbar", - "text": I18n.tr("Dank Bar"), - "icon": "toolbar", - "children": [ - { - "id": "dankbar_settings", - "text": I18n.tr("Settings"), - "icon": "tune", - "tabIndex": 3 - }, - { - "id": "dankbar_widgets", - "text": I18n.tr("Widgets"), - "icon": "widgets", - "tabIndex": 22 - } - ] - }, - { - "id": "workspaces_widgets", - "text": I18n.tr("Workspaces & Widgets"), - "icon": "dashboard", - "collapsedByDefault": true, - "children": [ - { - "id": "workspaces", - "text": I18n.tr("Workspaces"), - "icon": "view_module", - "tabIndex": 4 - }, - { - "id": "media_player", - "text": I18n.tr("Media Player"), - "icon": "music_note", - "tabIndex": 16 - }, - { - "id": "notifications", - "text": I18n.tr("Notifications"), - "icon": "notifications", - "tabIndex": 17 - }, - { - "id": "osd", - "text": I18n.tr("On-screen Displays"), - "icon": "tune", - "tabIndex": 18 - }, - { - "id": "running_apps", - "text": I18n.tr("Running Apps"), - "icon": "app_registration", - "tabIndex": 19, - "hyprlandNiriOnly": true - }, - { - "id": "updater", - "text": I18n.tr("System Updater"), - "icon": "refresh", - "tabIndex": 20 - }, - { - "id": "desktop_widgets", - "text": I18n.tr("Desktop Widgets"), - "icon": "widgets", - "tabIndex": 27 - } - ] - }, - { - "id": "dock_launcher", - "text": I18n.tr("Dock & Launcher"), - "icon": "apps", - "collapsedByDefault": true, - "children": [ - { - "id": "dock", - "text": I18n.tr("Dock"), - "icon": "dock_to_bottom", - "tabIndex": 5 - }, - { - "id": "launcher", - "text": I18n.tr("Launcher"), - "icon": "grid_view", - "tabIndex": 9 - } - ] - }, - { - "id": "keybinds", - "text": I18n.tr("Keyboard Shortcuts"), - "icon": "keyboard", - "tabIndex": 2, - "shortcutsOnly": true - }, - { - "id": "displays", - "text": I18n.tr("Displays"), - "icon": "monitor", - "collapsedByDefault": true, - "children": [ - { - "id": "display_config", - "text": I18n.tr("Configuration"), - "icon": "display_settings", - "tabIndex": 24 - }, - { - "id": "display_gamma", - "text": I18n.tr("Gamma Control"), - "icon": "brightness_6", - "tabIndex": 25 - }, - { - "id": "display_widgets", - "text": I18n.tr("Widgets", "settings_displays"), - "icon": "widgets", - "tabIndex": 26 - } - ] - }, - { - "id": "network", - "text": I18n.tr("Network"), - "icon": "wifi", - "tabIndex": 7, - "dmsOnly": true - }, - { - "id": "system", - "text": I18n.tr("System"), - "icon": "memory", - "collapsedByDefault": true, - "children": [ - { - "id": "audio", - "text": I18n.tr("Audio"), - "icon": "headphones", - "tabIndex": 29 - }, - { - "id": "locale", - "text": I18n.tr("Locale"), - "icon": "language", - "tabIndex": 30 - }, - { - "id": "clipboard", - "text": I18n.tr("Clipboard"), - "icon": "content_paste", - "tabIndex": 23, - "clipboardOnly": true - }, - { - "id": "printers", - "text": I18n.tr("Printers"), - "icon": "print", - "tabIndex": 8, - "cupsOnly": true - }, - { - "id": "multiplexers", - "text": I18n.tr("Multiplexers"), - "icon": "terminal", - "tabIndex": 32 - }, - { - "id": "window_rules", - "text": I18n.tr("Window Rules"), - "icon": "select_window", - "tabIndex": 28, - "niriOnly": true - } - ] - }, - { - "id": "power_security", - "text": I18n.tr("Power & Security"), - "icon": "security", - "collapsedByDefault": true, - "children": [ - { - "id": "lock_screen", - "text": I18n.tr("Lock Screen"), - "icon": "lock", - "tabIndex": 11 - }, - { - "id": "greeter", - "text": I18n.tr("Greeter"), - "icon": "login", - "tabIndex": 31 - }, - { - "id": "power_sleep", - "text": I18n.tr("Power & Sleep"), - "icon": "power_settings_new", - "tabIndex": 21 - } - ] - }, - { - "id": "plugins", - "text": I18n.tr("Plugins"), - "icon": "extension", - "tabIndex": 12 - }, - { - "id": "separator", - "separator": true - }, - { - "id": "about", - "text": I18n.tr("About"), - "icon": "info", - "tabIndex": 13 - } - ] - - function isItemVisible(item) { - if (item.dmsOnly && NetworkService.usingLegacy) - return false; - if (item.cupsOnly && !CupsService.cupsAvailable) - return false; - if (item.shortcutsOnly && !KeybindsService.available) - return false; - if (item.soundsOnly && !AudioService.soundsAvailable) - return false; - if (item.hyprlandNiriOnly && !CompositorService.isNiri && !CompositorService.isHyprland) - return false; - if (item.niriOnly && !CompositorService.isNiri) - return false; - if (item.clipboardOnly && (!DMSService.isConnected || DMSService.apiVersion < 23)) - return false; - return true; - } - - function hasVisibleChildren(category) { - if (!category.children) - return false; - return category.children.some(child => isItemVisible(child)); - } - - function isCategoryVisible(category) { - if (category.separator) - return true; - if (!isItemVisible(category)) - return false; - if (category.children && !hasVisibleChildren(category)) - return false; - return true; - } - - function _setExpanded(id, expanded) { - var marker = "," + id + ","; - if (expanded) { - if (_expandedIds.indexOf(marker) < 0) - _expandedIds = _expandedIds + id + ","; - _collapsedIds = _collapsedIds.replace(marker, ","); - } else { - _expandedIds = _expandedIds.replace(marker, ","); - if (_collapsedIds.indexOf(marker) < 0) - _collapsedIds = _collapsedIds + id + ","; - } - SessionData.setSettingsSidebarState(_expandedIds, _collapsedIds); - } - - function _setAutoExpanded(id, value) { - var marker = "," + id + ","; - if (value) { - if (_autoExpandedIds.indexOf(marker) < 0) - _autoExpandedIds = _autoExpandedIds + id + ","; - } else { - _autoExpandedIds = _autoExpandedIds.replace(marker, ","); - } - } - - function _isAutoExpanded(id) { - return _autoExpandedIds.indexOf("," + id + ",") >= 0; - } - - function toggleCategory(categoryId) { - _setExpanded(categoryId, !isCategoryExpanded(categoryId)); - _setAutoExpanded(categoryId, false); - } - - function isCategoryExpanded(categoryId) { - if (_collapsedIds.indexOf("," + categoryId + ",") >= 0) - return false; - if (_expandedIds.indexOf("," + categoryId + ",") >= 0) - return true; - var category = categoryStructure.find(cat => cat.id === categoryId); - if (category && category.collapsedByDefault) - return false; - return true; - } - - function isChildActive(category) { - if (!category.children) - return false; - return category.children.some(child => child.tabIndex === currentIndex); - } - - function findParentCategory(tabIndex) { - for (var i = 0; i < categoryStructure.length; i++) { - var cat = categoryStructure[i]; - if (cat.children) { - for (var j = 0; j < cat.children.length; j++) { - if (cat.children[j].tabIndex === tabIndex) { - return cat; - } - } - } - } - return null; - } - - function autoExpandForTab(tabIndex) { - var parent = findParentCategory(tabIndex); - if (!parent) - return; - - if (!isCategoryExpanded(parent.id)) { - _setExpanded(parent.id, true); - _setAutoExpanded(parent.id, true); - } - } - - function autoCollapseIfNeeded(oldTabIndex, newTabIndex) { - var oldParent = findParentCategory(oldTabIndex); - var newParent = findParentCategory(newTabIndex); - - if (oldParent && oldParent !== newParent && _isAutoExpanded(oldParent.id)) { - _setExpanded(oldParent.id, false); - _setAutoExpanded(oldParent.id, false); - } - } - - function navigateNext() { - var flatItems = getFlatNavigableItems(); - var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); - var oldIndex = currentIndex; - var newIndex; - if (currentPos === -1) { - newIndex = flatItems[0]?.tabIndex ?? 0; - } else { - var nextPos = (currentPos + 1) % flatItems.length; - newIndex = flatItems[nextPos].tabIndex; - } - tabChangeRequested(newIndex); - autoCollapseIfNeeded(oldIndex, newIndex); - autoExpandForTab(newIndex); - } - - function navigatePrevious() { - var flatItems = getFlatNavigableItems(); - var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex); - var oldIndex = currentIndex; - var newIndex; - if (currentPos === -1) { - newIndex = flatItems[0]?.tabIndex ?? 0; - } else { - var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length; - newIndex = flatItems[prevPos].tabIndex; - } - tabChangeRequested(newIndex); - autoCollapseIfNeeded(oldIndex, newIndex); - autoExpandForTab(newIndex); - } - - function getFlatNavigableItems() { - var items = []; - for (var i = 0; i < categoryStructure.length; i++) { - var cat = categoryStructure[i]; - if (cat.separator || !isCategoryVisible(cat)) - continue; - - if (cat.tabIndex !== undefined && !cat.children) { - items.push(cat); - } - - if (cat.children) { - for (var j = 0; j < cat.children.length; j++) { - var child = cat.children[j]; - if (isItemVisible(child)) { - items.push(child); - } - } - } - } - return items; - } - - function resolveTabIndex(name: string): int { - if (!name) - return -1; - - var normalized = name.toLowerCase().replace(/[_\-\s]/g, ""); - - for (var i = 0; i < categoryStructure.length; i++) { - var cat = categoryStructure[i]; - if (cat.separator) - continue; - - var catId = (cat.id || "").toLowerCase().replace(/[_\-\s]/g, ""); - if (catId === normalized) { - if (cat.tabIndex !== undefined) - return cat.tabIndex; - if (cat.children && cat.children.length > 0) - return cat.children[0].tabIndex; - } - - if (cat.children) { - for (var j = 0; j < cat.children.length; j++) { - var child = cat.children[j]; - var childId = (child.id || "").toLowerCase().replace(/[_\-\s]/g, ""); - if (childId === normalized) - return child.tabIndex; - } - } - } - return -1; - } - - property real __maxTextWidth: Math.max(__m1.advanceWidth, __m2.advanceWidth, __m3.advanceWidth, __m4.advanceWidth, __m5.advanceWidth, __m6.advanceWidth) - property real __calculatedWidth: Math.max(270, __maxTextWidth + Theme.iconSize * 2 + Theme.spacingM * 4 + Theme.spacingS * 2) - - implicitWidth: __calculatedWidth - width: __calculatedWidth - height: parent.height - color: Theme.surfaceContainer - radius: Theme.cornerRadius - - Component.onCompleted: { - root._expandedIds = SessionData.settingsSidebarExpandedIds; - root._collapsedIds = SessionData.settingsSidebarCollapsedIds; - } - - StyledTextMetrics { - id: __m1 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Workspaces & Widgets") - } - StyledTextMetrics { - id: __m2 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Typography & Motion") - } - StyledTextMetrics { - id: __m3 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Keyboard Shortcuts") - } - StyledTextMetrics { - id: __m4 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Power & Security") - } - StyledTextMetrics { - id: __m5 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Dock & Launcher") - } - StyledTextMetrics { - id: __m6 - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - text: I18n.tr("Personalization") - } - - function selectSearchResult(result) { - if (!result) - return; - if (result.section) { - SettingsSearchService.navigateToSection(result.section); - } - var oldIndex = root.currentIndex; - tabChangeRequested(result.tabIndex); - autoCollapseIfNeeded(oldIndex, result.tabIndex); - autoExpandForTab(result.tabIndex); - searchField.text = ""; - SettingsSearchService.clear(); - searchSelectedIndex = 0; - keyboardHighlightIndex = -1; - Qt.callLater(searchField.forceActiveFocus); - } - - function navigateSearchResults(delta) { - if (SettingsSearchService.results.length === 0) - return; - searchSelectedIndex = Math.max(0, Math.min(searchSelectedIndex + delta, SettingsSearchService.results.length - 1)); - } - - DankFlickable { - anchors.fill: parent - clip: true - contentHeight: sidebarColumn.height - - Column { - id: sidebarColumn - width: parent.width - leftPadding: Theme.spacingS - rightPadding: Theme.spacingS - bottomPadding: Theme.spacingL - topPadding: Theme.spacingM + 2 - spacing: 2 - - ProfileSection { - width: parent.width - parent.leftPadding - parent.rightPadding - parentModal: root.parentModal - } - - Rectangle { - width: parent.width - parent.leftPadding - parent.rightPadding - height: 1 - color: Theme.outline - opacity: 0.2 - } - - Item { - width: parent.width - parent.leftPadding - parent.rightPadding - height: Theme.spacingXS - } - - DankTextField { - id: searchField - width: parent.width - parent.leftPadding - parent.rightPadding - placeholderText: I18n.tr("Search...") - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: "search" - leftIconSize: Theme.iconSize - 4 - showClearButton: text.length > 0 - usePopupTransparency: false - onTextChanged: { - SettingsSearchService.search(text); - root.searchSelectedIndex = 0; - } - keyForwardTargets: [keyHandler] - - Item { - id: keyHandler - function navNext() { - if (root.searchActive) { - root.navigateSearchResults(1); - } else { - root.highlightNext(); - } - } - function navPrev() { - if (root.searchActive) { - root.navigateSearchResults(-1); - } else { - root.highlightPrevious(); - } - } - function navSelect() { - if (root.searchActive && SettingsSearchService.results.length > 0) { - root.selectSearchResult(SettingsSearchService.results[root.searchSelectedIndex]); - } else if (root.keyboardHighlightIndex >= 0) { - root.selectHighlighted(); - } - } - Keys.onDownPressed: event => { - navNext(); - event.accepted = true; - } - Keys.onUpPressed: event => { - navPrev(); - event.accepted = true; - } - Keys.onTabPressed: event => { - navNext(); - event.accepted = true; - } - Keys.onBacktabPressed: event => { - navPrev(); - event.accepted = true; - } - Keys.onReturnPressed: event => { - navSelect(); - event.accepted = true; - } - Keys.onEscapePressed: event => { - if (root.searchActive) { - searchField.text = ""; - SettingsSearchService.clear(); - } else { - root.keyboardHighlightIndex = -1; - } - event.accepted = true; - } - } - } - - Column { - id: searchResultsColumn - width: parent.width - parent.leftPadding - parent.rightPadding - spacing: 2 - visible: root.searchActive - - Item { - width: parent.width - height: Theme.spacingS - } - - Repeater { - model: ScriptModel { - values: SettingsSearchService.results - } - - Rectangle { - id: resultDelegate - required property int index - required property var modelData - - width: searchResultsColumn.width - height: resultContent.height + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: { - if (root.searchSelectedIndex === index) - return Theme.buttonBg; - if (resultMouseArea.containsMouse) - return Theme.surfaceHover; - return "transparent"; - } - - DankRipple { - id: resultRipple - rippleColor: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText - cornerRadius: resultDelegate.radius - } - - Row { - id: resultContent - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: resultDelegate.modelData.icon || "settings" - size: Theme.iconSize - 2 - color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - width: parent.width - Theme.iconSize - Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: resultDelegate.modelData.label - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText - width: parent.width - wrapMode: Text.Wrap - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: resultDelegate.modelData.category - font.pixelSize: Theme.fontSizeSmall - 1 - color: root.searchSelectedIndex === resultDelegate.index ? Theme.withAlpha(Theme.buttonText, 0.7) : Theme.surfaceVariantText - width: parent.width - wrapMode: Text.Wrap - horizontalAlignment: Text.AlignLeft - } - } - } - - MouseArea { - id: resultMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => resultRipple.trigger(mouse.x, mouse.y) - onClicked: root.selectSearchResult(resultDelegate.modelData) - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - - StyledText { - width: parent.width - text: I18n.tr("No matches") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - horizontalAlignment: Text.AlignHCenter - visible: searchField.text.length > 0 && SettingsSearchService.results.length === 0 - topPadding: Theme.spacingM - } - } - - Item { - width: parent.width - parent.leftPadding - parent.rightPadding - height: Theme.spacingXS - visible: !root.searchActive - } - - Repeater { - model: root.categoryStructure - - delegate: Column { - id: categoryDelegate - required property int index - required property var modelData - - width: parent.width - parent.leftPadding - parent.rightPadding - visible: !root.searchActive && root.isCategoryVisible(modelData) - spacing: 2 - - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.15 - visible: categoryDelegate.modelData.separator === true - } - - Item { - width: parent.width - height: Theme.spacingS - visible: categoryDelegate.modelData.separator === true - } - - Rectangle { - id: categoryRow - width: parent.width - height: Math.max(Theme.iconSize, Theme.fontSizeMedium) + Theme.spacingS * 2 - radius: Theme.cornerRadius - visible: categoryDelegate.modelData.separator !== true - - readonly property bool hasTab: categoryDelegate.modelData.tabIndex !== undefined && !categoryDelegate.modelData.children - readonly property bool isActive: hasTab && root.currentIndex === categoryDelegate.modelData.tabIndex - readonly property bool isHighlighted: hasTab && root.keyboardHighlightIndex === categoryDelegate.modelData.tabIndex - - color: { - if (isActive) - return Theme.buttonBg; - if (isHighlighted) - return Theme.buttonHover; - if (categoryMouseArea.containsMouse) - return Theme.surfaceHover; - return "transparent"; - } - - DankRipple { - id: categoryRipple - rippleColor: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText - cornerRadius: categoryRow.radius - } - - Row { - id: categoryRowContent - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: categoryDelegate.modelData.icon || "" - size: Theme.iconSize - 2 - color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: categoryDelegate.modelData.text || "" - font.pixelSize: Theme.fontSizeMedium - font.weight: (categoryRow.isActive || root.isChildActive(categoryDelegate.modelData)) ? Font.Medium : Font.Normal - color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankIcon { - id: expandIcon - name: root.isCategoryExpanded(categoryDelegate.modelData.id) ? "expand_less" : "expand_more" - size: Theme.iconSize - 4 - color: Theme.surfaceVariantText - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - visible: categoryDelegate.modelData.children !== undefined && categoryDelegate.modelData.children.length > 0 - } - - MouseArea { - id: categoryMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => categoryRipple.trigger(mouse.x, mouse.y) - onClicked: { - root.keyboardHighlightIndex = -1; - if (categoryDelegate.modelData.children) { - root.toggleCategory(categoryDelegate.modelData.id); - } else if (categoryDelegate.modelData.tabIndex !== undefined) { - root.tabChangeRequested(categoryDelegate.modelData.tabIndex); - } - Qt.callLater(searchField.forceActiveFocus); - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - - Column { - id: childrenColumn - width: parent.width - spacing: 2 - visible: categoryDelegate.modelData.children !== undefined && root.isCategoryExpanded(categoryDelegate.modelData.id) - clip: true - - Repeater { - model: categoryDelegate.modelData.children || [] - - delegate: Rectangle { - id: childDelegate - required property int index - required property var modelData - - readonly property bool isActive: root.currentIndex === modelData.tabIndex - readonly property bool isHighlighted: root.keyboardHighlightIndex === modelData.tabIndex - - width: childrenColumn.width - height: Math.max(Theme.iconSize - 4, Theme.fontSizeSmall + 1) + Theme.spacingS * 2 - radius: Theme.cornerRadius - visible: root.isItemVisible(modelData) - color: { - if (isActive) - return Theme.buttonBg; - if (isHighlighted) - return Theme.buttonHover; - if (childMouseArea.containsMouse) - return Theme.surfaceHover; - return "transparent"; - } - - DankRipple { - id: childRipple - rippleColor: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText - cornerRadius: childDelegate.radius - } - - Row { - id: childRowContent - anchors.left: parent.left - anchors.leftMargin: Theme.spacingL + Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: childDelegate.modelData.icon || "" - size: Theme.iconSize - 4 - color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: childDelegate.modelData.text || "" - font.pixelSize: Theme.fontSizeSmall + 1 - font.weight: childDelegate.isActive ? Font.Medium : Font.Normal - color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: childMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => childRipple.trigger(mouse.x, mouse.y) - onClicked: { - root.keyboardHighlightIndex = -1; - root.tabChangeRequested(childDelegate.modelData.tabIndex); - Qt.callLater(searchField.forceActiveFocus); - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml deleted file mode 100644 index 92689f2..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiPasswordModal.qml +++ /dev/null @@ -1,764 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - property string wifiPasswordSSID: "" - property string wifiPasswordInput: "" - property string wifiUsernameInput: "" - property bool requiresEnterprise: false - property bool isHiddenNetwork: false - - property string wifiAnonymousIdentityInput: "" - property string wifiDomainInput: "" - - property bool isPromptMode: false - property string promptToken: "" - property string promptReason: "" - property var promptFields: [] - property string promptSetting: "" - - property bool isVpnPrompt: false - property string connectionName: "" - property string vpnServiceType: "" - property string connectionType: "" - property var fieldsInfo: [] - property var secretValues: ({}) - - readonly property bool showUsernameField: requiresEnterprise && !isVpnPrompt && fieldsInfo.length === 0 - readonly property bool showPasswordField: fieldsInfo.length === 0 - readonly property bool showAnonField: requiresEnterprise && !isVpnPrompt - readonly property bool showDomainField: requiresEnterprise && !isVpnPrompt - readonly property bool showSavePasswordCheckbox: (isVpnPrompt || fieldsInfo.length > 0) && promptReason !== "pkcs11" - - readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2 - readonly property int inputFieldWithSpacing: inputFieldHeight + Theme.spacingM - readonly property int checkboxRowHeight: Theme.fontSizeMedium + Theme.spacingS - readonly property int headerHeight: Theme.fontSizeLarge + Theme.fontSizeMedium + Theme.spacingM * 2 - readonly property int buttonRowHeight: 36 + Theme.spacingM - - property int calculatedHeight: { - let h = headerHeight + buttonRowHeight + Theme.spacingL * 2; - h += fieldsInfo.length * inputFieldWithSpacing; - if (isHiddenNetwork) - h += inputFieldWithSpacing; - if (showUsernameField) - h += inputFieldWithSpacing; - if (showPasswordField) - h += inputFieldWithSpacing; - if (showAnonField) - h += inputFieldWithSpacing; - if (showDomainField) - h += inputFieldWithSpacing; - if (showSavePasswordCheckbox) - h += checkboxRowHeight; - return h; - } - - function focusFirstField() { - if (fieldsInfo.length > 0) { - if (dynamicFieldsRepeater.count > 0) { - const firstItem = dynamicFieldsRepeater.itemAt(0); - if (firstItem) - firstItem.children[0].forceActiveFocus(); - } - return; - } - if (isHiddenNetwork) { - ssidInput.forceActiveFocus(); - return; - } - if (requiresEnterprise && !isVpnPrompt) { - usernameInput.forceActiveFocus(); - return; - } - passwordInput.forceActiveFocus(); - } - - function show(ssid) { - wifiPasswordSSID = ssid; - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - isPromptMode = false; - isHiddenNetwork = false; - promptToken = ""; - promptReason = ""; - promptFields = []; - promptSetting = ""; - isVpnPrompt = false; - connectionName = ""; - vpnServiceType = ""; - connectionType = ""; - fieldsInfo = []; - secretValues = {}; - - const network = NetworkService.wifiNetworks.find(n => n.ssid === ssid); - requiresEnterprise = network?.enterprise || false; - - visible = true; - Qt.callLater(focusFirstField); - } - - function showHidden() { - wifiPasswordSSID = ""; - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - isPromptMode = false; - isHiddenNetwork = true; - promptToken = ""; - promptReason = ""; - promptFields = []; - promptSetting = ""; - isVpnPrompt = false; - connectionName = ""; - vpnServiceType = ""; - connectionType = ""; - fieldsInfo = []; - secretValues = {}; - requiresEnterprise = false; - - visible = true; - Qt.callLater(focusFirstField); - } - - function showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService, fInfo) { - isPromptMode = true; - promptToken = token; - promptReason = reason; - promptFields = fields || []; - promptSetting = setting || "802-11-wireless-security"; - connectionType = connType || "802-11-wireless"; - connectionName = connName || ssid || ""; - vpnServiceType = vpnService || ""; - fieldsInfo = fInfo || []; - secretValues = {}; - - isVpnPrompt = (connectionType === "vpn" || connectionType === "wireguard"); - wifiPasswordSSID = isVpnPrompt ? connectionName : ssid; - - requiresEnterprise = setting === "802-1x"; - - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - - visible = true; - Qt.callLater(() => { - if (reason === "wrong-password" && fieldsInfo.length === 0) { - passwordInput.text = ""; - } - focusFirstField(); - }); - } - - function hide() { - visible = false; - } - - function getFieldLabel(fieldName) { - switch (fieldName) { - case "username": - case "identity": - return I18n.tr("Username"); - case "password": - return I18n.tr("Password"); - case "cert-pass": - case "certpass": - return I18n.tr("Certificate Password"); - case "private-key-password": - return I18n.tr("Private Key Password"); - case "pin": - case "key_pass": - return I18n.tr("PIN"); - case "psk": - return I18n.tr("Password"); - case "anonymous-identity": - return I18n.tr("Anonymous Identity"); - default: - return fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/-/g, " "); - } - } - - function submitCredentialsAndClose() { - if (fieldsInfo.length > 0) { - NetworkService.submitCredentials(promptToken, secretValues, savePasswordCheckbox.checked); - hide(); - secretValues = {}; - return; - } - - if (isPromptMode) { - const secrets = {}; - if (isVpnPrompt) { - if (passwordInput.text) - secrets["password"] = passwordInput.text; - } else if (promptSetting === "802-11-wireless-security") { - secrets["psk"] = passwordInput.text; - } else if (promptSetting === "802-1x") { - if (usernameInput.text) - secrets["identity"] = usernameInput.text; - if (passwordInput.text) - secrets["password"] = passwordInput.text; - if (wifiAnonymousIdentityInput) - secrets["anonymous-identity"] = wifiAnonymousIdentityInput; - } - NetworkService.submitCredentials(promptToken, secrets, savePasswordCheckbox.checked); - } else { - const ssid = isHiddenNetwork ? ssidInput.text : wifiPasswordSSID; - const username = requiresEnterprise ? usernameInput.text : ""; - NetworkService.connectToWifi(ssid, passwordInput.text, username, wifiAnonymousIdentityInput, wifiDomainInput, isHiddenNetwork); - } - - hide(); - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - passwordInput.text = ""; - if (requiresEnterprise) - usernameInput.text = ""; - if (isHiddenNetwork) - ssidInput.text = ""; - } - - function clearAndClose() { - if (isPromptMode) - NetworkService.cancelCredentials(promptToken); - hide(); - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - secretValues = {}; - } - - objectName: "wifiPasswordModal" - title: { - if (promptReason === "pkcs11") - return I18n.tr("Smartcard PIN"); - if (isVpnPrompt) - return I18n.tr("VPN Password"); - if (isHiddenNetwork) - return I18n.tr("Hidden Network"); - return I18n.tr("Wi-Fi Password"); - } - minimumSize: Qt.size(420, calculatedHeight) - maximumSize: Qt.size(420, calculatedHeight) - color: Theme.surfaceContainer - visible: false - - onVisibleChanged: { - if (visible) { - Qt.callLater(focusFirstField); - return; - } - wifiPasswordInput = ""; - wifiUsernameInput = ""; - wifiAnonymousIdentityInput = ""; - wifiDomainInput = ""; - secretValues = {}; - passwordInput.text = ""; - usernameInput.text = ""; - anonInput.text = ""; - domainMatchInput.text = ""; - ssidInput.text = ""; - for (var i = 0; i < dynamicFieldsRepeater.count; i++) { - const item = dynamicFieldsRepeater.itemAt(i); - if (item?.children[0]) - item.children[0].text = ""; - } - } - - Connections { - target: NetworkService - - function onPasswordDialogShouldReopenChanged() { - if (!NetworkService.passwordDialogShouldReopen || NetworkService.connectingSSID === "") - return; - wifiPasswordSSID = NetworkService.connectingSSID; - wifiPasswordInput = ""; - visible = true; - NetworkService.passwordDialogShouldReopen = false; - } - } - - FocusScope { - id: contentFocusScope - - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - clearAndClose(); - event.accepted = true; - } - - Column { - id: contentCol - anchors.centerIn: parent - width: parent.width - Theme.spacingL * 2 - spacing: Theme.spacingM - - Item { - width: contentCol.width - height: Math.max(headerCol.height, buttonRow.height) - - MouseArea { - anchors.left: parent.left - anchors.right: buttonRow.left - anchors.rightMargin: Theme.spacingM - height: headerCol.height - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - - Column { - id: headerCol - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: { - if (promptReason === "pkcs11") - return I18n.tr("Smartcard Authentication"); - if (isVpnPrompt) - return I18n.tr("Connect to VPN"); - if (isHiddenNetwork) - return I18n.tr("Connect to Hidden Network"); - return I18n.tr("Connect to Wi-Fi"); - } - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - Column { - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: { - if (promptReason === "pkcs11") - return I18n.tr("Enter PIN for ") + wifiPasswordSSID; - if (fieldsInfo.length > 0) - return I18n.tr("Enter credentials for ") + wifiPasswordSSID; - if (isVpnPrompt) - return I18n.tr("Enter password for ") + wifiPasswordSSID; - if (isHiddenNetwork) - return I18n.tr("Enter network name and password"); - const prefix = requiresEnterprise ? I18n.tr("Enter credentials for ") : I18n.tr("Enter password for "); - return prefix + wifiPasswordSSID; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - width: parent.width - elide: Text.ElideRight - } - - StyledText { - visible: isPromptMode && promptReason === "wrong-password" - text: I18n.tr("Incorrect password") - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - width: parent.width - } - } - } - } - - Row { - id: buttonRow - anchors.right: parent.right - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported && windowControls.canMaximize - iconName: root.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: clearAndClose() - } - } - } - - Rectangle { - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: ssidInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: ssidInput.activeFocus ? 2 : 1 - visible: isHiddenNetwork - - MouseArea { - anchors.fill: parent - onClicked: ssidInput.forceActiveFocus() - } - - DankTextField { - id: ssidInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - placeholderText: I18n.tr("Network Name (SSID)") - backgroundColor: "transparent" - enabled: root.visible - keyNavigationTab: passwordInput - onAccepted: passwordInput.forceActiveFocus() - } - } - - Repeater { - id: dynamicFieldsRepeater - model: fieldsInfo - - delegate: Rectangle { - required property var modelData - required property int index - - width: contentCol.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: fieldInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: fieldInput.activeFocus ? 2 : 1 - - DankTextField { - id: fieldInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - showPasswordToggle: modelData.isSecret - echoMode: modelData.isSecret && !passwordVisible ? TextInput.Password : TextInput.Normal - placeholderText: getFieldLabel(modelData.name) - backgroundColor: "transparent" - enabled: root.visible - - Keys.onTabPressed: event => { - if (index < fieldsInfo.length - 1) { - const nextItem = dynamicFieldsRepeater.itemAt(index + 1); - if (nextItem) - nextItem.children[0].forceActiveFocus(); - } else { - const firstItem = dynamicFieldsRepeater.itemAt(0); - if (firstItem) - firstItem.children[0].forceActiveFocus(); - } - event.accepted = true; - } - - Keys.onBacktabPressed: event => { - if (index > 0) { - const prevItem = dynamicFieldsRepeater.itemAt(index - 1); - if (prevItem) - prevItem.children[0].forceActiveFocus(); - } else { - const lastItem = dynamicFieldsRepeater.itemAt(fieldsInfo.length - 1); - if (lastItem) - lastItem.children[0].forceActiveFocus(); - } - event.accepted = true; - } - - onTextEdited: { - let updated = Object.assign({}, root.secretValues); - updated[modelData.name] = text; - root.secretValues = updated; - } - - onAccepted: { - if (index < fieldsInfo.length - 1) { - const nextItem = dynamicFieldsRepeater.itemAt(index + 1); - if (nextItem) - nextItem.children[0].forceActiveFocus(); - return; - } - submitCredentialsAndClose(); - } - } - } - } - - Rectangle { - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: usernameInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: usernameInput.activeFocus ? 2 : 1 - visible: showUsernameField - - MouseArea { - anchors.fill: parent - onClicked: usernameInput.forceActiveFocus() - } - - DankTextField { - id: usernameInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: wifiUsernameInput - placeholderText: I18n.tr("Username") - backgroundColor: "transparent" - enabled: root.visible - keyNavigationTab: passwordInput - keyNavigationBacktab: domainMatchInput - onTextEdited: wifiUsernameInput = text - onAccepted: passwordInput.forceActiveFocus() - } - } - - Rectangle { - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: passwordInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: passwordInput.activeFocus ? 2 : 1 - visible: showPasswordField - - MouseArea { - anchors.fill: parent - onClicked: passwordInput.forceActiveFocus() - } - - DankTextField { - id: passwordInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: wifiPasswordInput - showPasswordToggle: true - echoMode: passwordVisible ? TextInput.Normal : TextInput.Password - placeholderText: (requiresEnterprise && !isVpnPrompt) ? I18n.tr("Password") : "" - backgroundColor: "transparent" - enabled: root.visible - keyNavigationTab: (requiresEnterprise && !isVpnPrompt) ? anonInput : null - keyNavigationBacktab: (requiresEnterprise && !isVpnPrompt) ? usernameInput : null - onTextEdited: wifiPasswordInput = text - onAccepted: { - if (requiresEnterprise && !isVpnPrompt) { - anonInput.forceActiveFocus(); - return; - } - submitCredentialsAndClose(); - } - } - } - - Rectangle { - visible: showAnonField - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: anonInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: anonInput.activeFocus ? 2 : 1 - - MouseArea { - anchors.fill: parent - onClicked: anonInput.forceActiveFocus() - } - - DankTextField { - id: anonInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: wifiAnonymousIdentityInput - placeholderText: I18n.tr("Anonymous Identity (optional)") - backgroundColor: "transparent" - enabled: root.visible - keyNavigationTab: domainMatchInput - keyNavigationBacktab: passwordInput - onTextEdited: wifiAnonymousIdentityInput = text - onAccepted: domainMatchInput.forceActiveFocus() - } - } - - Rectangle { - visible: showDomainField - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: domainMatchInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: domainMatchInput.activeFocus ? 2 : 1 - - MouseArea { - anchors.fill: parent - onClicked: domainMatchInput.forceActiveFocus() - } - - DankTextField { - id: domainMatchInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - text: wifiDomainInput - placeholderText: I18n.tr("Domain (optional)") - backgroundColor: "transparent" - enabled: root.visible - keyNavigationTab: usernameInput - keyNavigationBacktab: anonInput - onTextEdited: wifiDomainInput = text - onAccepted: submitCredentialsAndClose() - } - } - - Row { - spacing: Theme.spacingS - visible: showSavePasswordCheckbox - - Rectangle { - id: savePasswordCheckbox - - property bool checked: !isVpnPrompt - - width: 20 - height: 20 - radius: 4 - color: checked ? Theme.primary : "transparent" - border.color: checked ? Theme.primary : Theme.outlineButton - border.width: 2 - - DankIcon { - anchors.centerIn: parent - name: "check" - size: 12 - color: Theme.background - visible: parent.checked - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: savePasswordCheckbox.checked = !savePasswordCheckbox.checked - } - } - - StyledText { - text: I18n.tr("Save password") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Item { - width: parent.width - height: 40 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - Rectangle { - width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - - StyledText { - id: cancelText - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: clearAndClose() - } - } - - Rectangle { - width: Math.max(80, connectText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: connectArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - enabled: { - if (fieldsInfo.length > 0) { - for (var i = 0; i < fieldsInfo.length; i++) { - if (!fieldsInfo[i].isSecret) - continue; - const fieldName = fieldsInfo[i].name; - if (!secretValues[fieldName] || secretValues[fieldName].length === 0) - return false; - } - return true; - } - if (isVpnPrompt) - return passwordInput.text.length > 0; - if (isHiddenNetwork) - return ssidInput.text.length > 0; - return requiresEnterprise ? (usernameInput.text.length > 0 && passwordInput.text.length > 0) : passwordInput.text.length > 0; - } - opacity: enabled ? 1 : 0.5 - - StyledText { - id: connectText - anchors.centerIn: parent - text: I18n.tr("Connect") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: connectArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: parent.enabled - onClicked: submitCredentialsAndClose() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml deleted file mode 100644 index 06ffab7..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WifiQRCodeModal.qml +++ /dev/null @@ -1,170 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import QtQuick.Effects -import Quickshell -import Quickshell.Io -import qs.Modals.Common -import qs.Modals.FileBrowser -import qs.Common -import qs.Services -import qs.Widgets - -DankModal { - id: root - visible: false - layerNamespace: "dms:wifi-qrcode" - - property bool disablePopupTransparency: true - property string wifiSSID: "" - property string themedQrCodePath: "" - property string normalQrCodePath: "" - modalWidth: 420 - modalHeight: 480 - onBackgroundClicked: hide() - onOpened: { - Qt.callLater(() => { - modalFocusScope.forceActiveFocus(); - contentLoader.item.wifiSSID = wifiSSID; - contentLoader.item.themedQrCodePath = themedQrCodePath; - contentLoader.item.saveBrowserLoader = saveBrowserLoader; - }); - } - - function show(ssid) { - wifiSSID = ssid; - fetchNetworkQRCode(ssid); - } - - function hide() { - if (themedQrCodePath !== "") { - deleteQRCodeFile(themedQrCodePath); - } - if (normalQrCodePath !== "") { - deleteQRCodeFile(normalQrCodePath); - } - close(); - } - - function fetchNetworkQRCode(ssid) { - // TODO: Add loading UI? - - DMSService.sendRequest("network.qrcode", { - ssid: ssid - }, response => { - if (response.error) { - ToastService.showError("Failed to fetch network QR code: ", JSON.stringify(response.error)); - } else if (response.result) { - themedQrCodePath = response.result[0]; - normalQrCodePath = response.result[1]; - open(); - } - }); - } - - function deleteQRCodeFile(path) { - DMSService.sendRequest("network.delete-qrcode", { - path: path - }, response => { - if (response.error) { - ToastService.showError(`Failed to remove QR code at ${path}: `, JSON.stringify(response.error)); - } - }) - } - - LazyLoader { - id: saveBrowserLoader - active: false - - FileBrowserSurfaceModal { - id: saveBrowser - - browserTitle: I18n.tr("Save QR Code") - browserIcon: "qr_code" - browserType: "default" - fileExtensions: ["*.png"] - allowStacking: true - saveMode: true - defaultFileName: `${root.wifiSSID ?? "wifi-qrcode"}.png` - onFileSelected: path => { - const cleanPath = decodeURI(path.toString().replace(/^file:\/\//, '')); - const fileName = cleanPath.split('/').pop(); - const fileUrl = "file://" + cleanPath; - - copyQrCodeProcess.exec(["cp", root.normalQrCodePath, cleanPath, "-f"]) - } - - Process { - id: copyQrCodeProcess - stdout: StdioCollector { - onStreamFinished: { - saveBrowser.close(); - } - } - } - } - } - - content: Component { - Item { - id: theItem - property alias themedQrCodePath: qrCodeImg.source - property var saveBrowserLoader: null - property string wifiSSID: "" - anchors.fill: parent - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingL - - RowLayout { - id: modalTitle - width: parent.width - - StyledText { - text: I18n.tr("WiFi QR code for ") + theItem.wifiSSID - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Bold - Layout.alignment: Qt.AlignLeft - } - - DankActionButton { - iconName: "save" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: { - saveBrowserLoader.active = true; - if (saveBrowserLoader.item) { - saveBrowserLoader.item.open(); - } - } - Layout.alignment: Qt.AlignRight - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: root.hide() - Layout.alignment: Qt.AlignRight - } - } - - Image { - id: qrCodeImg - height: parent.height - parent.spacing - modalTitle.height - width: height - anchors.horizontalCenter: parent.horizontalCenter - - MultiEffect { - source: qrCodeImg - anchors.fill: source - colorization: 1.0 - colorizationColor: Theme.primary - } - } - } - } - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml deleted file mode 100644 index 6c9583a..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WindowRuleModal.qml +++ /dev/null @@ -1,1184 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - property var editingRule: null - property bool isEditMode: editingRule !== null - property bool isNiri: CompositorService.isNiri - property bool isHyprland: CompositorService.isHyprland - property bool submitting: false - property var targetWindow: null - - signal ruleSubmitted - - readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2 - readonly property int sectionSpacing: Theme.spacingL - - objectName: "windowRuleModal" - title: isEditMode ? I18n.tr("Edit Window Rule") : I18n.tr("Create Window Rule") - minimumSize: Qt.size(500, 600) - maximumSize: Qt.size(500, 600) - color: Theme.surfaceContainer - visible: false - - function resetForm() { - nameInput.text = ""; - appIdInput.text = ""; - titleInput.text = ""; - opacityEnabled.checked = false; - opacitySlider.value = 100; - floatingToggle.checked = false; - maximizedToggle.checked = false; - maximizedToEdgesToggle.checked = false; - fullscreenToggle.checked = false; - openFocusedToggle.checked = false; - outputInput.text = ""; - workspaceInput.text = ""; - columnWidthInput.text = ""; - windowHeightInput.text = ""; - vrrToggle.checked = false; - blockOutDropdown.currentValue = ""; - columnDisplayDropdown.currentValue = ""; - scrollFactorEnabled.checked = false; - scrollFactorSlider.value = 100; - cornerRadiusEnabled.checked = false; - cornerRadiusSlider.value = 12; - clipToGeometryToggle.checked = false; - tiledStateToggle.checked = false; - drawBorderBgToggle.checked = false; - minWidthInput.text = ""; - maxWidthInput.text = ""; - minHeightInput.text = ""; - maxHeightInput.text = ""; - tileToggle.checked = false; - noFocusToggle.checked = false; - noBorderToggle.checked = false; - noShadowToggle.checked = false; - noDimToggle.checked = false; - noBlurToggle.checked = false; - noAnimToggle.checked = false; - noRoundingToggle.checked = false; - pinToggle.checked = false; - opaqueToggle.checked = false; - sizeInput.text = ""; - moveInput.text = ""; - monitorInput.text = ""; - hyprWorkspaceInput.text = ""; - } - - function show(window) { - editingRule = null; - targetWindow = window || null; - resetForm(); - if (targetWindow) { - nameInput.text = targetWindow.appId || ""; - appIdInput.text = targetWindow.appId ? "^" + targetWindow.appId + "$" : ""; - } - visible = true; - Qt.callLater(() => nameInput.forceActiveFocus()); - } - - function showEdit(rule) { - if (!rule) { - show(); - return; - } - editingRule = rule; - resetForm(); - - nameInput.text = rule.name || ""; - const match = rule.matchCriteria || {}; - appIdInput.text = match.appId || ""; - titleInput.text = match.title || ""; - - const actions = rule.actions || {}; - const hasOpacity = actions.opacity !== undefined && actions.opacity !== null; - opacityEnabled.checked = hasOpacity; - opacitySlider.value = hasOpacity ? Math.round(actions.opacity * 100) : 100; - - floatingToggle.checked = actions.openFloating || false; - maximizedToggle.checked = actions.openMaximized || false; - maximizedToEdgesToggle.checked = actions.openMaximizedToEdges || false; - fullscreenToggle.checked = actions.openFullscreen || false; - - openFocusedToggle.checked = actions.openFocused || false; - - outputInput.text = actions.openOnOutput || ""; - workspaceInput.text = actions.openOnWorkspace || ""; - columnWidthInput.text = actions.defaultColumnWidth || ""; - windowHeightInput.text = actions.defaultWindowHeight || ""; - vrrToggle.checked = actions.variableRefreshRate || false; - - blockOutDropdown.currentValue = actions.blockOutFrom || ""; - columnDisplayDropdown.currentValue = actions.defaultColumnDisplay || ""; - - const hasScrollFactor = actions.scrollFactor !== undefined && actions.scrollFactor !== null; - scrollFactorEnabled.checked = hasScrollFactor; - scrollFactorSlider.value = hasScrollFactor ? Math.round(actions.scrollFactor * 100) : 100; - - const hasCornerRadius = actions.cornerRadius !== undefined && actions.cornerRadius !== null; - cornerRadiusEnabled.checked = hasCornerRadius; - cornerRadiusSlider.value = hasCornerRadius ? actions.cornerRadius : 12; - - clipToGeometryToggle.checked = actions.clipToGeometry || false; - tiledStateToggle.checked = actions.tiledState || false; - - drawBorderBgToggle.checked = actions.drawBorderWithBackground || false; - - minWidthInput.text = actions.minWidth !== undefined ? String(actions.minWidth) : ""; - maxWidthInput.text = actions.maxWidth !== undefined ? String(actions.maxWidth) : ""; - minHeightInput.text = actions.minHeight !== undefined ? String(actions.minHeight) : ""; - maxHeightInput.text = actions.maxHeight !== undefined ? String(actions.maxHeight) : ""; - - tileToggle.checked = actions.tile || false; - noFocusToggle.checked = actions.nofocus || false; - noBorderToggle.checked = actions.noborder || false; - noShadowToggle.checked = actions.noshadow || false; - noDimToggle.checked = actions.nodim || false; - noBlurToggle.checked = actions.noblur || false; - noAnimToggle.checked = actions.noanim || false; - noRoundingToggle.checked = actions.norounding || false; - pinToggle.checked = actions.pin || false; - opaqueToggle.checked = actions.opaque || false; - sizeInput.text = actions.size || ""; - moveInput.text = actions.move || ""; - monitorInput.text = actions.monitor || ""; - hyprWorkspaceInput.text = actions.workspace || ""; - - visible = true; - Qt.callLater(() => nameInput.forceActiveFocus()); - } - - function hide() { - visible = false; - editingRule = null; - targetWindow = null; - } - - function submitAndClose() { - const matchCriteria = {}; - if (appIdInput.text.trim()) - matchCriteria.appId = appIdInput.text.trim(); - if (titleInput.text.trim()) - matchCriteria.title = titleInput.text.trim(); - - const actions = {}; - - if (opacityEnabled.checked) - actions.opacity = opacitySlider.value / 100; - if (floatingToggle.checked) - actions.openFloating = true; - if (maximizedToggle.checked) - actions.openMaximized = true; - if (maximizedToEdgesToggle.checked && isNiri) - actions.openMaximizedToEdges = true; - if (fullscreenToggle.checked) - actions.openFullscreen = true; - if (openFocusedToggle.checked && isNiri) - actions.openFocused = true; - if (outputInput.text.trim()) - actions.openOnOutput = outputInput.text.trim(); - if (workspaceInput.text.trim()) - actions.openOnWorkspace = workspaceInput.text.trim(); - if (columnWidthInput.text.trim() && isNiri) - actions.defaultColumnWidth = columnWidthInput.text.trim(); - if (windowHeightInput.text.trim() && isNiri) - actions.defaultWindowHeight = windowHeightInput.text.trim(); - if (vrrToggle.checked && isNiri) - actions.variableRefreshRate = true; - if (blockOutDropdown.currentValue && isNiri) - actions.blockOutFrom = blockOutDropdown.currentValue; - if (columnDisplayDropdown.currentValue && isNiri) - actions.defaultColumnDisplay = columnDisplayDropdown.currentValue; - if (scrollFactorEnabled.checked && isNiri) - actions.scrollFactor = scrollFactorSlider.value / 100; - if (cornerRadiusEnabled.checked) - actions.cornerRadius = cornerRadiusSlider.value; - if (clipToGeometryToggle.checked && isNiri) - actions.clipToGeometry = true; - if (tiledStateToggle.checked && isNiri) - actions.tiledState = true; - if (drawBorderBgToggle.checked && isNiri) - actions.drawBorderWithBackground = true; - - const minW = parseInt(minWidthInput.text); - const maxW = parseInt(maxWidthInput.text); - const minH = parseInt(minHeightInput.text); - const maxH = parseInt(maxHeightInput.text); - if (!isNaN(minW)) - actions.minWidth = minW; - if (!isNaN(maxW)) - actions.maxWidth = maxW; - if (!isNaN(minH)) - actions.minHeight = minH; - if (!isNaN(maxH)) - actions.maxHeight = maxH; - - if (isHyprland) { - if (tileToggle.checked) - actions.tile = true; - if (noFocusToggle.checked) - actions.nofocus = true; - if (noBorderToggle.checked) - actions.noborder = true; - if (noShadowToggle.checked) - actions.noshadow = true; - if (noDimToggle.checked) - actions.nodim = true; - if (noBlurToggle.checked) - actions.noblur = true; - if (noAnimToggle.checked) - actions.noanim = true; - if (noRoundingToggle.checked) - actions.norounding = true; - if (pinToggle.checked) - actions.pin = true; - if (opaqueToggle.checked) - actions.opaque = true; - if (sizeInput.text.trim()) - actions.size = sizeInput.text.trim(); - if (moveInput.text.trim()) - actions.move = moveInput.text.trim(); - if (monitorInput.text.trim()) - actions.monitor = monitorInput.text.trim(); - if (hyprWorkspaceInput.text.trim()) - actions.workspace = hyprWorkspaceInput.text.trim(); - } - - const name = nameInput.text.trim() || matchCriteria.appId || I18n.tr("Rule"); - const compositor = CompositorService.compositor; - - const ruleData = { - name: name, - matchCriteria: matchCriteria, - actions: actions, - enabled: true - }; - - submitting = true; - - const shouldValidate = CompositorService.isNiri; - - if (isEditMode) { - const ruleJson = JSON.stringify(ruleData); - Proc.runCommand("update-windowrule", ["dms", "config", "windowrules", "update", compositor, editingRule.id, ruleJson], (output, exitCode) => { - root.submitting = false; - if (exitCode !== 0) - return; - if (shouldValidate) - NiriService.validate(); - root.ruleSubmitted(); - root.hide(); - }); - } else { - const ruleJson = JSON.stringify(ruleData); - Proc.runCommand("add-windowrule", ["dms", "config", "windowrules", "add", compositor, ruleJson], (output, exitCode) => { - root.submitting = false; - if (exitCode !== 0) - return; - if (shouldValidate) - NiriService.validate(); - root.ruleSubmitted(); - root.hide(); - }); - } - } - - onVisibleChanged: { - if (!visible) { - editingRule = null; - targetWindow = null; - } - } - - component SectionHeader: StyledText { - property string title - text: title - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.primary - topPadding: Theme.spacingM - bottomPadding: Theme.spacingXS - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - component CheckboxRow: Row { - property alias checked: checkbox.checked - property alias label: labelText.text - property bool indeterminate: false - spacing: Theme.spacingS - height: 24 - - Rectangle { - id: checkbox - property bool checked: false - width: 20 - height: 20 - radius: 4 - color: parent.indeterminate ? Theme.surfaceVariant : (checked ? Theme.primary : "transparent") - border.color: parent.indeterminate ? Theme.outlineButton : (checked ? Theme.primary : Theme.outlineButton) - border.width: 2 - anchors.verticalCenter: parent.verticalCenter - - DankIcon { - anchors.centerIn: parent - name: parent.parent.indeterminate ? "remove" : "check" - size: 12 - color: parent.parent.indeterminate ? Theme.surfaceVariantText : Theme.background - visible: parent.checked || parent.parent.indeterminate - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - if (parent.parent.indeterminate) { - parent.parent.indeterminate = false; - parent.checked = true; - } else { - parent.checked = !parent.checked; - } - } - } - } - - StyledText { - id: labelText - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - component InputField: Rectangle { - id: inputFieldRect - default property alias contentData: inputFieldRect.data - property bool hasFocus: false - width: parent.width - height: root.inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: hasFocus ? Theme.primary : Theme.outlineStrong - border.width: hasFocus ? 2 : 1 - } - - FocusScope { - anchors.fill: parent - focus: true - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - Keys.onEscapePressed: event => { - hide(); - event.accepted = true; - } - - Item { - id: header - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingL - height: Math.max(headerCol.height, closeBtn.height) - - MouseArea { - anchors.left: parent.left - anchors.right: closeBtn.left - anchors.rightMargin: Theme.spacingM - height: headerCol.height - onPressed: windowControls.tryStartMove() - - Column { - id: headerCol - width: parent.width - spacing: Theme.spacingXS - - StyledText { - text: root.isEditMode ? I18n.tr("Edit Window Rule") : I18n.tr("New Window Rule") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: I18n.tr("Configure match criteria and actions") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - - DankActionButton { - id: closeBtn - anchors.right: parent.right - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: hide() - } - } - - DankFlickable { - id: flickable - anchors.top: header.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: footer.top - anchors.margins: Theme.spacingL - anchors.topMargin: Theme.spacingM - contentWidth: width - contentHeight: contentCol.implicitHeight - clip: true - - Column { - id: contentCol - width: flickable.width - Theme.spacingM - spacing: Theme.spacingXS - - InputField { - hasFocus: nameInput.activeFocus - DankTextField { - id: nameInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: I18n.tr("Rule Name") - backgroundColor: "transparent" - enabled: root.visible - } - } - - SectionHeader { - title: I18n.tr("Match Criteria") - } - - InputField { - hasFocus: appIdInput.activeFocus - DankTextField { - id: appIdInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: isNiri ? I18n.tr("App ID regex (e.g. ^firefox$)") : I18n.tr("Class regex (e.g. ^firefox$)") - backgroundColor: "transparent" - enabled: root.visible - } - } - - Row { - width: parent.width - spacing: Theme.spacingS - - InputField { - width: addTitleBtn.visible ? parent.width - addTitleBtn.width - Theme.spacingS : parent.width - hasFocus: titleInput.activeFocus - DankTextField { - id: titleInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: I18n.tr("Title regex (optional)") - backgroundColor: "transparent" - enabled: root.visible - } - } - - DankActionButton { - id: addTitleBtn - width: root.inputFieldHeight - height: root.inputFieldHeight - circular: false - iconName: "add" - iconSize: 16 - iconColor: Theme.surfaceVariantText - visible: !root.isEditMode && !!root.targetWindow?.title - tooltipText: I18n.tr("Add Title") - tooltipSide: "left" - onClicked: { - if (!root.targetWindow?.title) - return; - titleInput.text = "^" + root.targetWindow.title + "$"; - } - } - } - - SectionHeader { - title: I18n.tr("Window Opening") - } - - Flow { - width: parent.width - spacing: Theme.spacingL - - CheckboxRow { - id: floatingToggle - label: I18n.tr("Float") - } - CheckboxRow { - id: maximizedToggle - label: I18n.tr("Maximize") - } - CheckboxRow { - id: fullscreenToggle - label: I18n.tr("Fullscreen") - } - CheckboxRow { - id: maximizedToEdgesToggle - label: I18n.tr("Max to Edges") - visible: isNiri - } - CheckboxRow { - id: openFocusedToggle - label: I18n.tr("Focus") - visible: isNiri - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: true - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Output") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: outputInput.activeFocus - DankTextField { - id: outputInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "HDMI-A-1" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Workspace") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: workspaceInput.activeFocus - DankTextField { - id: workspaceInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "chat" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: isNiri - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Column Width") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: columnWidthInput.activeFocus - DankTextField { - id: columnWidthInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "800" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Window Height") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: windowHeightInput.activeFocus - DankTextField { - id: windowHeightInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "600" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - } - - SectionHeader { - title: I18n.tr("Dynamic Properties") - } - - Row { - width: parent.width - spacing: Theme.spacingM - - CheckboxRow { - id: opacityEnabled - label: I18n.tr("Opacity") - anchors.verticalCenter: parent.verticalCenter - } - - DankSlider { - id: opacitySlider - width: parent.width - 100 - minimum: 10 - maximum: 100 - value: 100 - enabled: opacityEnabled.checked - opacity: enabled ? 1 : 0.4 - } - } - - Flow { - width: parent.width - spacing: Theme.spacingL - visible: isNiri - - CheckboxRow { - id: vrrToggle - label: I18n.tr("VRR On-Demand") - } - CheckboxRow { - id: clipToGeometryToggle - label: I18n.tr("Clip to Geometry") - } - CheckboxRow { - id: tiledStateToggle - label: I18n.tr("Tiled State") - } - CheckboxRow { - id: drawBorderBgToggle - label: I18n.tr("Border with BG") - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: isNiri - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Block Out From") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - DankDropdown { - id: blockOutDropdown - width: parent.width - dropdownWidth: parent.width - compactMode: true - options: ["", "screencast", "screen-capture"] - emptyText: I18n.tr("None") - } - } - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Column Display") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - DankDropdown { - id: columnDisplayDropdown - width: parent.width - dropdownWidth: parent.width - compactMode: true - options: ["", "tabbed"] - emptyText: I18n.tr("Normal") - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: isNiri - - CheckboxRow { - id: scrollFactorEnabled - label: I18n.tr("Scroll Factor") - anchors.verticalCenter: parent.verticalCenter - } - - DankSlider { - id: scrollFactorSlider - width: parent.width - 120 - minimum: 10 - maximum: 200 - value: 100 - enabled: scrollFactorEnabled.checked - opacity: enabled ? 1 : 0.4 - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - - CheckboxRow { - id: cornerRadiusEnabled - label: I18n.tr("Corner Radius") - anchors.verticalCenter: parent.verticalCenter - } - - DankSlider { - id: cornerRadiusSlider - width: parent.width - 130 - minimum: 0 - maximum: 24 - value: 12 - enabled: cornerRadiusEnabled.checked - opacity: enabled ? 1 : 0.4 - } - } - - SectionHeader { - title: I18n.tr("Size Constraints") - } - - Row { - width: parent.width - spacing: Theme.spacingM - - Column { - width: (parent.width - Theme.spacingM * 3) / 4 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Min W") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: minWidthInput.activeFocus - DankTextField { - id: minWidthInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "px" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM * 3) / 4 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Max W") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: maxWidthInput.activeFocus - DankTextField { - id: maxWidthInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "px" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM * 3) / 4 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Min H") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: minHeightInput.activeFocus - DankTextField { - id: minHeightInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "px" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM * 3) / 4 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Max H") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: maxHeightInput.activeFocus - DankTextField { - id: maxHeightInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "px" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - } - - SectionHeader { - title: I18n.tr("Hyprland Options") - visible: isHyprland - } - - Flow { - width: parent.width - spacing: Theme.spacingL - visible: isHyprland - - CheckboxRow { - id: tileToggle - label: I18n.tr("Tile") - } - CheckboxRow { - id: noFocusToggle - label: I18n.tr("No Focus") - } - CheckboxRow { - id: noBorderToggle - label: I18n.tr("No Border") - } - CheckboxRow { - id: noShadowToggle - label: I18n.tr("No Shadow") - } - CheckboxRow { - id: noDimToggle - label: I18n.tr("No Dim") - } - CheckboxRow { - id: noBlurToggle - label: I18n.tr("No Blur") - } - CheckboxRow { - id: noAnimToggle - label: I18n.tr("No Anim") - } - CheckboxRow { - id: noRoundingToggle - label: I18n.tr("No Rounding") - } - CheckboxRow { - id: pinToggle - label: I18n.tr("Pin") - } - CheckboxRow { - id: opaqueToggle - label: I18n.tr("Opaque") - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: isHyprland - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Size") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: sizeInput.activeFocus - DankTextField { - id: sizeInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "800 600" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Move") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: moveInput.activeFocus - DankTextField { - id: moveInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "100 100" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: isHyprland - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Monitor") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: monitorInput.activeFocus - DankTextField { - id: monitorInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "DP-1" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - - Column { - width: (parent.width - Theme.spacingM) / 2 - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Workspace") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - InputField { - width: parent.width - hasFocus: hyprWorkspaceInput.activeFocus - DankTextField { - id: hyprWorkspaceInput - anchors.fill: parent - font.pixelSize: Theme.fontSizeSmall - textColor: Theme.surfaceText - placeholderText: "1" - backgroundColor: "transparent" - enabled: root.visible - } - } - } - } - - Item { - width: 1 - height: Theme.spacingM - } - } - } - - Item { - id: footer - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingL - height: 44 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - Rectangle { - width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - - StyledText { - id: cancelText - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: hide() - } - } - - Rectangle { - width: Math.max(80, createText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: root.submitting ? Theme.surfaceVariant : (createArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary) - - StyledText { - id: createText - anchors.centerIn: parent - text: root.submitting ? I18n.tr("Saving...") : (root.isEditMode ? I18n.tr("Update") : I18n.tr("Create")) - font.pixelSize: Theme.fontSizeMedium - color: root.submitting ? Theme.surfaceVariantText : Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: createArea - anchors.fill: parent - hoverEnabled: true - cursorShape: root.submitting ? Qt.ArrowCursor : Qt.PointingHandCursor - enabled: !root.submitting - onClicked: submitAndClose() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } -} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml deleted file mode 100644 index 6519ac3..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modals/WorkspaceRenameModal.qml +++ /dev/null @@ -1,230 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Common -import qs.Services -import qs.Widgets - -FloatingWindow { - id: root - - property bool disablePopupTransparency: true - readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2 - - objectName: "workspaceRenameModal" - title: I18n.tr("Rename Workspace") - minimumSize: Qt.size(400, 160) - maximumSize: Qt.size(400, 160) - color: Theme.surfaceContainer - visible: false - - function show(name) { - nameInput.text = name; - visible = true; - Qt.callLater(() => nameInput.forceActiveFocus()); - } - - function hide() { - visible = false; - } - - function submitAndClose() { - renameWorkspace(nameInput.text); - hide(); - } - - function renameWorkspace(name) { - if (CompositorService.isNiri) { - NiriService.renameWorkspace(name); - } else if (CompositorService.isHyprland) { - HyprlandService.renameWorkspace(name); - } else { - console.warn("WorkspaceRenameModal: rename not supported for this compositor"); - } - } - - onVisibleChanged: { - if (visible) { - Qt.callLater(() => nameInput.forceActiveFocus()); - return; - } - nameInput.text = ""; - } - - FocusScope { - id: contentFocusScope - - anchors.fill: parent - focus: true - - Keys.onEscapePressed: event => { - hide(); - event.accepted = true; - } - - Column { - id: contentCol - anchors.centerIn: parent - width: parent.width - Theme.spacingL * 2 - spacing: Theme.spacingM - - Item { - width: contentCol.width - height: Math.max(headerText.height, buttonRow.height) - - MouseArea { - anchors.left: parent.left - anchors.right: buttonRow.left - anchors.rightMargin: Theme.spacingM - height: parent.height - onPressed: windowControls.tryStartMove() - onDoubleClicked: windowControls.tryToggleMaximize() - } - - StyledText { - id: headerText - text: I18n.tr("Enter a new name for this workspace") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceTextMedium - anchors.verticalCenter: parent.verticalCenter - width: parent.width - buttonRow.width - Theme.spacingM - } - - Row { - id: buttonRow - anchors.right: parent.right - spacing: Theme.spacingXS - - DankActionButton { - visible: windowControls.supported && windowControls.canMaximize - iconName: root.maximized ? "fullscreen_exit" : "fullscreen" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: windowControls.tryToggleMaximize() - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - onClicked: hide() - } - } - } - - Rectangle { - width: parent.width - height: inputFieldHeight - radius: Theme.cornerRadius - color: Theme.surfaceHover - border.color: nameInput.activeFocus ? Theme.primary : Theme.outlineStrong - border.width: nameInput.activeFocus ? 2 : 1 - - MouseArea { - anchors.fill: parent - onClicked: nameInput.forceActiveFocus() - } - - DankTextField { - id: nameInput - - anchors.fill: parent - font.pixelSize: Theme.fontSizeMedium - textColor: Theme.surfaceText - placeholderText: I18n.tr("Workspace name") - backgroundColor: "transparent" - enabled: root.visible - onAccepted: submitAndClose() - } - } - - Item { - width: parent.width - height: 40 - - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - Rectangle { - width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent" - border.color: Theme.surfaceVariantAlpha - border.width: 1 - - StyledText { - id: cancelText - anchors.centerIn: parent - text: I18n.tr("Cancel") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - } - - MouseArea { - id: cancelArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: hide() - } - } - - Rectangle { - width: Math.max(80, renameText.contentWidth + Theme.spacingM * 2) - height: 36 - radius: Theme.cornerRadius - color: renameArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary - - StyledText { - id: renameText - anchors.centerIn: parent - text: I18n.tr("Rename") - font.pixelSize: Theme.fontSizeMedium - color: Theme.background - font.weight: Font.Medium - } - - MouseArea { - id: renameArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: submitAndClose() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - } - } - } - } - } - - FloatingWindowControls { - id: windowControls - targetWindow: root - } - - IpcHandler { - target: "workspace-rename" - - function open(): string { - const ws = NiriService.workspaces[NiriService.focusedWorkspaceId]; - show(ws?.name || ""); - return "WORKSPACE_RENAME_MODAL_OPENED"; - } - - function close(): string { - hide(); - return "WORKSPACE_RENAME_MODAL_CLOSED"; - } - } -} |