1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

launcher: reemove background from list and add a bottom fade

This commit is contained in:
bbedward
2025-12-05 10:04:19 -05:00
parent e56481f6d7
commit 5faa1a993a
4 changed files with 150 additions and 60 deletions

View File

@@ -10,12 +10,31 @@ Rectangle {
property var fileSearchController: null
function resetScroll() {
filesList.contentY = 0
filesList.contentY = 0;
}
color: "transparent"
clip: true
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 32
z: 100
visible: filesList.contentHeight > filesList.height && (filesList.currentIndex < filesList.count - 1 || filesList.contentY < filesList.contentHeight - filesList.height - 1)
gradient: Gradient {
GradientStop {
position: 0.0
color: "transparent"
}
GradientStop {
position: 1.0
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
}
}
}
DankListView {
id: filesList
@@ -30,18 +49,22 @@ Rectangle {
function ensureVisible(index) {
if (index < 0 || index >= count)
return
const itemY = index * (itemHeight + itemSpacing)
const itemBottom = itemY + itemHeight
return;
const itemY = index * (itemHeight + itemSpacing);
const itemBottom = itemY + itemHeight;
const fadeHeight = 32;
const isLastItem = index === count - 1;
if (itemY < contentY)
contentY = itemY
else if (itemBottom > contentY + height)
contentY = itemBottom - height
contentY = itemY;
else if (itemBottom > contentY + height - (isLastItem ? 0 : fadeHeight))
contentY = Math.min(itemBottom - height + (isLastItem ? 0 : fadeHeight), contentHeight - height);
}
anchors.fill: parent
anchors.margins: Theme.spacingS
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.topMargin: Theme.spacingS
anchors.bottomMargin: 1
model: fileSearchController ? fileSearchController.model : null
currentIndex: fileSearchController ? fileSearchController.selectedIndex : -1
clip: true
@@ -53,26 +76,26 @@ Rectangle {
onCurrentIndexChanged: {
if (keyboardNavigationActive)
ensureVisible(currentIndex)
ensureVisible(currentIndex);
}
onItemClicked: function (index) {
if (fileSearchController) {
const item = fileSearchController.model.get(index)
fileSearchController.openFile(item.filePath)
const item = fileSearchController.model.get(index);
fileSearchController.openFile(item.filePath);
}
}
onItemRightClicked: function (index) {
if (fileSearchController) {
const item = fileSearchController.model.get(index)
fileSearchController.openFolder(item.filePath)
const item = fileSearchController.model.get(index);
fileSearchController.openFolder(item.filePath);
}
}
onKeyboardNavigationReset: {
if (fileSearchController)
fileSearchController.keyboardNavigationActive = false
fileSearchController.keyboardNavigationActive = false;
}
delegate: Rectangle {
@@ -86,7 +109,7 @@ Rectangle {
width: ListView.view.width
height: filesList.itemHeight
radius: Theme.cornerRadius
color: ListView.isCurrentItem ? Theme.primaryPressed : fileMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
color: ListView.isCurrentItem ? Theme.widgetBaseHoverColor : fileMouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
Row {
anchors.fill: parent
@@ -109,16 +132,16 @@ Rectangle {
id: nerdIcon
anchors.centerIn: parent
name: {
const lowerName = fileName.toLowerCase()
const lowerName = fileName.toLowerCase();
if (lowerName.startsWith("dockerfile"))
return "docker"
return "docker";
if (lowerName.startsWith("makefile"))
return "makefile"
return "makefile";
if (lowerName.startsWith("license"))
return "license"
return "license";
if (lowerName.startsWith("readme"))
return "readme"
return fileExtension.toLowerCase()
return "readme";
return fileExtension.toLowerCase();
}
size: Theme.fontSizeXLarge
color: Theme.surfaceText
@@ -196,16 +219,16 @@ Rectangle {
z: 10
onEntered: {
if (filesList.hoverUpdatesSelection && !filesList.keyboardNavigationActive)
filesList.currentIndex = index
filesList.currentIndex = index;
}
onPositionChanged: {
filesList.keyboardNavigationReset()
filesList.keyboardNavigationReset();
}
onClicked: mouse => {
if (mouse.button === Qt.LeftButton) {
filesList.itemClicked(index)
filesList.itemClicked(index);
} else if (mouse.button === Qt.RightButton) {
filesList.itemRightClicked(index)
filesList.itemRightClicked(index);
}
}
}
@@ -219,21 +242,21 @@ Rectangle {
StyledText {
property string displayText: {
if (!fileSearchController) {
return ""
return "";
}
if (!DSearchService.dsearchAvailable) {
return I18n.tr("DankSearch not available")
return I18n.tr("DankSearch not available");
}
if (fileSearchController.isSearching) {
return I18n.tr("Searching...")
return I18n.tr("Searching...");
}
if (fileSearchController.searchQuery.length === 0) {
return I18n.tr("Enter a search query")
return I18n.tr("Enter a search query");
}
if (!fileSearchController.model || fileSearchController.model.count === 0) {
return I18n.tr("No files found")
return I18n.tr("No files found");
}
return ""
return "";
}
text: displayText

View File

@@ -51,6 +51,33 @@ Rectangle {
color: "transparent"
clip: true
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 32
z: 100
visible: {
if (!appLauncher)
return false;
const view = appLauncher.viewMode === "list" ? resultsList : (gridLoader.item || resultsList);
const isLastItem = appLauncher.viewMode === "list" ? view.currentIndex >= view.count - 1 : (gridLoader.item ? Math.floor(view.currentIndex / view.actualColumns) >= Math.floor((view.count - 1) / view.actualColumns) : false);
const hasOverflow = view.contentHeight > view.height;
const atBottom = view.contentY >= view.contentHeight - view.height - 1;
return hasOverflow && (!isLastItem || !atBottom);
}
gradient: Gradient {
GradientStop {
position: 0.0
color: "transparent"
}
GradientStop {
position: 1.0
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
}
}
}
DankListView {
id: resultsList
@@ -70,14 +97,19 @@ Rectangle {
return;
const itemY = index * (itemHeight + itemSpacing);
const itemBottom = itemY + itemHeight;
const fadeHeight = 32;
const isLastItem = index === count - 1;
if (itemY < contentY)
contentY = itemY;
else if (itemBottom > contentY + height)
contentY = itemBottom - height;
else if (itemBottom > contentY + height - (isLastItem ? 0 : fadeHeight))
contentY = Math.min(itemBottom - height + (isLastItem ? 0 : fadeHeight), contentHeight - height);
}
anchors.fill: parent
anchors.margins: Theme.spacingS
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.topMargin: Theme.spacingS
anchors.bottomMargin: 1
visible: appLauncher && appLauncher.viewMode === "list"
model: appLauncher ? appLauncher.model : null
currentIndex: appLauncher ? appLauncher.selectedIndex : -1
@@ -127,7 +159,10 @@ Rectangle {
property real _lastWidth: 0
anchors.fill: parent
anchors.margins: Theme.spacingS
anchors.leftMargin: Theme.spacingS
anchors.rightMargin: Theme.spacingS
anchors.topMargin: Theme.spacingS
anchors.bottomMargin: 1
visible: appLauncher && appLauncher.viewMode === "grid"
active: appLauncher && appLauncher.viewMode === "grid"
asynchronous: false
@@ -177,10 +212,12 @@ Rectangle {
return;
const itemY = Math.floor(index / actualColumns) * cellHeight;
const itemBottom = itemY + cellHeight;
const fadeHeight = 32;
const isLastRow = Math.floor(index / actualColumns) >= Math.floor((count - 1) / actualColumns);
if (itemY < contentY)
contentY = itemY;
else if (itemBottom > contentY + height)
contentY = itemBottom - height;
else if (itemBottom > contentY + height - (isLastRow ? 0 : fadeHeight))
contentY = Math.min(itemBottom - height + (isLastRow ? 0 : fadeHeight), contentHeight - height);
}
anchors.fill: parent

View File

@@ -406,6 +406,34 @@ DankPopout {
}
radius: Theme.cornerRadius
color: "transparent"
clip: true
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 32
z: 100
visible: {
if (appDrawerPopout.searchMode !== "apps")
return false;
const view = appLauncher.viewMode === "list" ? appList : appGrid;
const isLastItem = view.currentIndex >= view.count - 1;
const hasOverflow = view.contentHeight > view.height;
const atBottom = view.contentY >= view.contentHeight - view.height - 1;
return hasOverflow && (!isLastItem || !atBottom);
}
gradient: Gradient {
GradientStop {
position: 0.0
color: "transparent"
}
GradientStop {
position: 1.0
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
}
}
}
DankListView {
id: appList
@@ -426,14 +454,16 @@ DankPopout {
return;
var itemY = index * (itemHeight + itemSpacing);
var itemBottom = itemY + itemHeight;
var fadeHeight = 32;
var isLastItem = index === count - 1;
if (itemY < contentY)
contentY = itemY;
else if (itemBottom > contentY + height)
contentY = itemBottom - height;
else if (itemBottom > contentY + height - (isLastItem ? 0 : fadeHeight))
contentY = Math.min(itemBottom - height + (isLastItem ? 0 : fadeHeight), contentHeight - height);
}
anchors.fill: parent
anchors.bottomMargin: Theme.spacingS
anchors.bottomMargin: 1
visible: appDrawerPopout.searchMode === "apps" && appLauncher.viewMode === "list"
model: appLauncher.model
currentIndex: appLauncher.selectedIndex
@@ -511,14 +541,16 @@ DankPopout {
return;
var itemY = Math.floor(index / actualColumns) * cellHeight;
var itemBottom = itemY + cellHeight;
var fadeHeight = 32;
var isLastRow = Math.floor(index / actualColumns) >= Math.floor((count - 1) / actualColumns);
if (itemY < contentY)
contentY = itemY;
else if (itemBottom > contentY + height)
contentY = itemBottom - height;
else if (itemBottom > contentY + height - (isLastRow ? 0 : fadeHeight))
contentY = Math.min(itemBottom - height + (isLastRow ? 0 : fadeHeight), contentHeight - height);
}
anchors.fill: parent
anchors.bottomMargin: Theme.spacingS
anchors.bottomMargin: 1
visible: appDrawerPopout.searchMode === "apps" && appLauncher.viewMode === "grid"
model: appLauncher.model
clip: true

View File

@@ -1,6 +1,4 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import qs.Common
import qs.Widgets
@@ -29,12 +27,12 @@ Rectangle {
signal itemClicked(int index, var modelData)
signal itemRightClicked(int index, var modelData, real mouseX, real mouseY)
signal keyboardNavigationReset()
signal keyboardNavigationReset
width: listView.width
height: itemHeight
radius: Theme.cornerRadius
color: isCurrentItem ? Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) : mouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
color: isCurrentItem ? Theme.widgetBaseHoverColor : mouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
Row {
anchors.fill: parent
@@ -97,27 +95,27 @@ Rectangle {
z: 10
onEntered: {
if (root.hoverUpdatesSelection && !root.keyboardNavigationActive)
root.listView.currentIndex = root.index
root.listView.currentIndex = root.index;
}
onPositionChanged: {
root.keyboardNavigationReset()
root.keyboardNavigationReset();
}
onClicked: mouse => {
if (mouse.button === Qt.LeftButton) {
root.itemClicked(root.index, root.model)
root.itemClicked(root.index, root.model);
}
}
onPressAndHold: mouse => {
if (!root.isPlugin) {
const globalPos = mapToItem(null, mouse.x, mouse.y)
root.itemRightClicked(root.index, root.model, globalPos.x, globalPos.y)
const globalPos = mapToItem(null, mouse.x, mouse.y);
root.itemRightClicked(root.index, root.model, globalPos.x, globalPos.y);
}
}
onPressed: mouse => {
if (mouse.button === Qt.RightButton && !root.isPlugin) {
const globalPos = mapToItem(null, mouse.x, mouse.y)
root.itemRightClicked(root.index, root.model, globalPos.x, globalPos.y)
mouse.accepted = true
const globalPos = mapToItem(null, mouse.x, mouse.y);
root.itemRightClicked(root.index, root.model, globalPos.x, globalPos.y);
mouse.accepted = true;
}
}
}