1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00
Files
DankMaterialShell/quickshell/Modals/Spotlight/SpotlightResults.qml
2025-12-01 09:31:57 -05:00

231 lines
8.7 KiB
QML

import QtQuick
import qs.Common
import qs.Widgets
Rectangle {
id: resultsContainer
property var appLauncher: null
signal itemRightClicked(int index, var modelData, real mouseX, real mouseY)
function resetScroll() {
resultsList.contentY = 0;
if (gridLoader.item) {
gridLoader.item.contentY = 0;
}
}
function getSelectedItemPosition() {
if (!appLauncher)
return {
x: 0,
y: 0
};
const selectedIndex = appLauncher.selectedIndex;
if (appLauncher.viewMode === "list") {
const itemY = selectedIndex * (resultsList.itemHeight + resultsList.itemSpacing) - resultsList.contentY;
return {
x: resultsList.width / 2,
y: itemY + resultsList.itemHeight / 2
};
} else if (gridLoader.item) {
const grid = gridLoader.item;
const row = Math.floor(selectedIndex / grid.actualColumns);
const col = selectedIndex % grid.actualColumns;
const itemX = col * grid.cellWidth + grid.leftMargin + grid.cellWidth / 2;
const itemY = row * grid.cellHeight - grid.contentY + grid.cellHeight / 2;
return {
x: itemX,
y: itemY
};
}
return {
x: 0,
y: 0
};
}
radius: Theme.cornerRadius
color: "transparent"
clip: true
DankListView {
id: resultsList
property int itemHeight: 60
property int iconSize: 40
property bool showDescription: true
property int itemSpacing: Theme.spacingS
property bool hoverUpdatesSelection: false
property bool keyboardNavigationActive: appLauncher ? appLauncher.keyboardNavigationActive : false
signal keyboardNavigationReset
signal itemClicked(int index, var modelData)
signal itemRightClicked(int index, var modelData, real mouseX, real mouseY)
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.margins: Theme.spacingS
visible: appLauncher && appLauncher.viewMode === "list"
model: appLauncher ? appLauncher.model : null
currentIndex: appLauncher ? appLauncher.selectedIndex : -1
clip: true
spacing: itemSpacing
focus: true
interactive: true
cacheBuffer: Math.max(0, Math.min(height * 2, 1000))
reuseItems: true
onCurrentIndexChanged: {
if (keyboardNavigationActive)
ensureVisible(currentIndex);
}
onItemClicked: (index, modelData) => {
if (appLauncher)
appLauncher.launchApp(modelData);
}
onItemRightClicked: (index, modelData, mouseX, mouseY) => {
resultsContainer.itemRightClicked(index, modelData, mouseX, mouseY);
}
onKeyboardNavigationReset: () => {
if (appLauncher)
appLauncher.keyboardNavigationActive = false;
}
delegate: AppLauncherListDelegate {
listView: resultsList
itemHeight: resultsList.itemHeight
iconSize: resultsList.iconSize
showDescription: resultsList.showDescription
hoverUpdatesSelection: resultsList.hoverUpdatesSelection
keyboardNavigationActive: resultsList.keyboardNavigationActive
isCurrentItem: ListView.isCurrentItem
iconMaterialSizeAdjustment: 0
iconUnicodeScale: 0.8
onItemClicked: (idx, modelData) => resultsList.itemClicked(idx, modelData)
onItemRightClicked: (idx, modelData, mouseX, mouseY) => {
resultsList.itemRightClicked(idx, modelData, mouseX, mouseY);
}
onKeyboardNavigationReset: resultsList.keyboardNavigationReset
}
}
Loader {
id: gridLoader
property real _lastWidth: 0
anchors.fill: parent
anchors.margins: Theme.spacingS
visible: appLauncher && appLauncher.viewMode === "grid"
active: appLauncher && appLauncher.viewMode === "grid"
asynchronous: false
onLoaded: {
if (item) {
item.appLauncher = Qt.binding(() => resultsContainer.appLauncher);
}
}
onWidthChanged: {
if (visible && Math.abs(width - _lastWidth) > 1) {
_lastWidth = width;
active = false;
Qt.callLater(() => {
active = true;
});
}
}
sourceComponent: Component {
DankGridView {
id: resultsGrid
property var appLauncher: null
property int currentIndex: appLauncher ? appLauncher.selectedIndex : -1
property int columns: appLauncher ? appLauncher.gridColumns : 4
property bool adaptiveColumns: false
property int minCellWidth: 120
property int maxCellWidth: 160
property real iconSizeRatio: 0.55
property int maxIconSize: 48
property int minIconSize: 32
property bool hoverUpdatesSelection: false
property bool keyboardNavigationActive: appLauncher ? appLauncher.keyboardNavigationActive : false
property real baseCellWidth: adaptiveColumns ? Math.max(minCellWidth, Math.min(maxCellWidth, width / columns)) : width / columns
property real baseCellHeight: baseCellWidth + 20
property int actualColumns: adaptiveColumns ? Math.floor(width / cellWidth) : columns
property int remainingSpace: width - (actualColumns * cellWidth)
signal keyboardNavigationReset
signal itemClicked(int index, var modelData)
signal itemRightClicked(int index, var modelData, real mouseX, real mouseY)
function ensureVisible(index) {
if (index < 0 || index >= count)
return;
const itemY = Math.floor(index / actualColumns) * cellHeight;
const itemBottom = itemY + cellHeight;
if (itemY < contentY)
contentY = itemY;
else if (itemBottom > contentY + height)
contentY = itemBottom - height;
}
anchors.fill: parent
model: appLauncher ? appLauncher.model : null
clip: true
cellWidth: baseCellWidth
cellHeight: baseCellHeight
focus: true
interactive: true
cacheBuffer: Math.max(0, Math.min(height * 2, 1000))
reuseItems: true
onCurrentIndexChanged: {
if (keyboardNavigationActive)
ensureVisible(currentIndex);
}
onItemClicked: (index, modelData) => {
if (appLauncher)
appLauncher.launchApp(modelData);
}
onItemRightClicked: (index, modelData, mouseX, mouseY) => {
resultsContainer.itemRightClicked(index, modelData, mouseX, mouseY);
}
onKeyboardNavigationReset: () => {
if (appLauncher)
appLauncher.keyboardNavigationActive = false;
}
delegate: AppLauncherGridDelegate {
gridView: resultsGrid
cellWidth: resultsGrid.cellWidth
cellHeight: resultsGrid.cellHeight
minIconSize: resultsGrid.minIconSize
maxIconSize: resultsGrid.maxIconSize
iconSizeRatio: resultsGrid.iconSizeRatio
hoverUpdatesSelection: resultsGrid.hoverUpdatesSelection
keyboardNavigationActive: resultsGrid.keyboardNavigationActive
currentIndex: resultsGrid.currentIndex
onItemClicked: (idx, modelData) => resultsGrid.itemClicked(idx, modelData)
onItemRightClicked: (idx, modelData, mouseX, mouseY) => {
resultsGrid.itemRightClicked(idx, modelData, mouseX, mouseY);
}
onKeyboardNavigationReset: resultsGrid.keyboardNavigationReset
}
}
}
}
}