diff --git a/quickshell/Modals/DankLauncherV2/GridItem.qml b/quickshell/Modals/DankLauncherV2/GridItem.qml index 9d40e549..27f9a91b 100644 --- a/quickshell/Modals/DankLauncherV2/GridItem.qml +++ b/quickshell/Modals/DankLauncherV2/GridItem.qml @@ -16,6 +16,25 @@ Rectangle { 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.primaryPressed : "transparent" @@ -25,88 +44,15 @@ Rectangle { spacing: Theme.spacingS width: parent.width - Theme.spacingM - Item { - width: iconSize - height: iconSize + AppIconRenderer { + width: root.computedIconSize + height: root.computedIconSize anchors.horizontalCenter: parent.horizontalCenter - - property int iconSize: Math.min(48, Math.max(32, root.width * 0.45)) - - Image { - id: appIcon - anchors.fill: parent - visible: root.item?.iconType === "image" - asynchronous: true - source: root.item?.iconType === "image" ? "image://icon/" + (root.item?.icon || "application-x-executable") : "" - sourceSize.width: parent.iconSize - sourceSize.height: parent.iconSize - fillMode: Image.PreserveAspectFit - cache: false - } - - DankIcon { - anchors.centerIn: parent - visible: root.item?.iconType === "material" || root.item?.iconType === "nerd" - name: root.item?.icon ?? "apps" - size: parent.iconSize * 0.7 - color: root.isSelected ? Theme.primary : Theme.surfaceText - } - - StyledText { - anchors.centerIn: parent - visible: root.item?.iconType === "unicode" - text: root.item?.icon ?? "" - font.pixelSize: parent.iconSize * 0.7 - color: root.isSelected ? Theme.primary : Theme.surfaceText - } - - Item { - anchors.fill: parent - visible: root.item?.iconType === "composite" - - Image { - anchors.fill: parent - asynchronous: true - source: { - if (!root.item || root.item.iconType !== "composite") - return ""; - var iconFull = root.item.iconFull || ""; - if (iconFull.startsWith("svg+corner:")) { - var parts = iconFull.substring(11).split("|"); - return parts[0] || ""; - } - return ""; - } - sourceSize.width: parent.width - sourceSize.height: parent.height - fillMode: Image.PreserveAspectFit - } - - Rectangle { - anchors.right: parent.right - anchors.bottom: parent.bottom - width: 16 - height: 16 - radius: 8 - color: Theme.surfaceContainer - - DankIcon { - anchors.centerIn: parent - name: { - if (!root.item || root.item.iconType !== "composite") - return ""; - var iconFull = root.item.iconFull || ""; - if (iconFull.startsWith("svg+corner:")) { - var parts = iconFull.substring(11).split("|"); - return parts[1] || ""; - } - return ""; - } - size: 12 - color: root.isSelected ? Theme.primary : Theme.surfaceText - } - } - } + 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 } StyledText { diff --git a/quickshell/Modals/DankLauncherV2/ResultItem.qml b/quickshell/Modals/DankLauncherV2/ResultItem.qml index 33cb8ea2..3822e3ac 100644 --- a/quickshell/Modals/DankLauncherV2/ResultItem.qml +++ b/quickshell/Modals/DankLauncherV2/ResultItem.qml @@ -16,6 +16,23 @@ Rectangle { 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.primaryPressed : "transparent" @@ -27,86 +44,14 @@ Rectangle { anchors.rightMargin: Theme.spacingM spacing: Theme.spacingM - Item { + AppIconRenderer { width: 36 height: 36 anchors.verticalCenter: parent.verticalCenter - - Image { - id: appIcon - anchors.fill: parent - visible: root.item?.iconType === "image" - asynchronous: true - source: root.item?.iconType === "image" ? "image://icon/" + (root.item?.icon || "application-x-executable") : "" - sourceSize.width: 36 - sourceSize.height: 36 - fillMode: Image.PreserveAspectFit - cache: false - } - - DankIcon { - anchors.centerIn: parent - visible: root.item?.iconType === "material" || root.item?.iconType === "nerd" - name: root.item?.icon ?? "apps" - size: 24 - color: Theme.surfaceText - } - - StyledText { - anchors.centerIn: parent - visible: root.item?.iconType === "unicode" - text: root.item?.icon ?? "" - font.pixelSize: 24 - color: Theme.surfaceText - } - - Item { - anchors.fill: parent - visible: root.item?.iconType === "composite" - - Image { - anchors.fill: parent - asynchronous: true - source: { - if (!root.item || root.item.iconType !== "composite") - return ""; - var iconFull = root.item.iconFull || ""; - if (iconFull.startsWith("svg+corner:")) { - var parts = iconFull.substring(11).split("|"); - return parts[0] || ""; - } - return ""; - } - sourceSize.width: 36 - sourceSize.height: 36 - fillMode: Image.PreserveAspectFit - } - - Rectangle { - anchors.right: parent.right - anchors.bottom: parent.bottom - width: 16 - height: 16 - radius: 8 - color: Theme.surfaceContainer - - DankIcon { - anchors.centerIn: parent - name: { - if (!root.item || root.item.iconType !== "composite") - return ""; - var iconFull = root.item.iconFull || ""; - if (iconFull.startsWith("svg+corner:")) { - var parts = iconFull.substring(11).split("|"); - return parts[1] || ""; - } - return ""; - } - size: 12 - color: Theme.surfaceText - } - } - } + iconValue: root.iconValue + iconSize: 36 + fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?" + materialIconSizeAdjustment: 12 } Column { diff --git a/quickshell/Modals/DankLauncherV2/TileItem.qml b/quickshell/Modals/DankLauncherV2/TileItem.qml index bcd2c073..e01d9719 100644 --- a/quickshell/Modals/DankLauncherV2/TileItem.qml +++ b/quickshell/Modals/DankLauncherV2/TileItem.qml @@ -35,7 +35,23 @@ Rectangle { } readonly property bool useImage: imageSource.length > 0 - readonly property bool useIconProvider: !useImage && item?.iconType === "image" + + readonly property string iconValue: { + if (!item || useImage) + return ""; + 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) @@ -62,32 +78,15 @@ Rectangle { maxCacheSize: 256 } - Image { - id: iconImage - anchors.fill: parent - visible: root.useIconProvider - source: root.useIconProvider ? "image://icon/" + (root.item?.icon || "application-x-executable") : "" - sourceSize.width: parent.width * 2 - sourceSize.height: parent.height * 2 - fillMode: Image.PreserveAspectCrop - cache: false - asynchronous: true - } - - DankIcon { + AppIconRenderer { anchors.centerIn: parent - visible: !root.useImage && !root.useIconProvider && root.item?.iconType !== "unicode" - name: root.item?.icon ?? "image" - size: Math.min(parent.width, parent.height) * 0.4 - color: Theme.surfaceVariantText - } - - StyledText { - anchors.centerIn: parent - visible: root.item?.iconType === "unicode" - text: root.item?.icon ?? "" - font.pixelSize: Math.min(parent.width, parent.height) * 0.4 - color: Theme.surfaceVariantText + visible: !root.useImage + width: Math.min(parent.width, parent.height) * 0.6 + height: width + iconValue: root.iconValue + iconSize: width + fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?" + materialIconSizeAdjustment: width * 0.3 } Rectangle { diff --git a/quickshell/Widgets/AppIconRenderer.qml b/quickshell/Widgets/AppIconRenderer.qml index be3db340..64062368 100644 --- a/quickshell/Widgets/AppIconRenderer.qml +++ b/quickshell/Widgets/AppIconRenderer.qml @@ -71,7 +71,8 @@ Item { anchors.fill: parent source: root.iconPath - smooth: true + backer.sourceSize: Qt.size(root.iconSize, root.iconSize) + mipmap: true asynchronous: true visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && root.iconPath !== "" && status === Image.Ready }