diff options
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml')
| -rw-r--r-- | raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/KeybindsModal.qml deleted file mode 100644 index e1d6765..0000000 --- a/raveos-theme/hyprland/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 - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } -} |