launcher overhaul

This commit is contained in:
Zacharias-Brohn
2026-02-17 16:32:43 +01:00
parent e818ac5515
commit dbb930f39a
31 changed files with 1603 additions and 1145 deletions
+70
View File
@@ -0,0 +1,70 @@
import QtQuick
import qs.Modules.Launcher.Services
import qs.Components
import qs.Helpers
import qs.Config
Item {
id: root
required property var modelData
required property var list
implicitHeight: Config.launcher.sizes.itemHeight
anchors.left: parent?.left
anchors.right: parent?.right
StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void {
root.modelData?.onClicked(root.list);
}
}
Item {
anchors.fill: parent
anchors.leftMargin: Appearance.padding.larger
anchors.rightMargin: Appearance.padding.larger
anchors.margins: Appearance.padding.smaller
MaterialIcon {
id: icon
text: root.modelData?.icon ?? ""
font.pointSize: Appearance.font.size.extraLarge
anchors.verticalCenter: parent.verticalCenter
}
Item {
anchors.left: icon.right
anchors.leftMargin: Appearance.spacing.normal
anchors.verticalCenter: icon.verticalCenter
implicitWidth: parent.width - icon.width
implicitHeight: name.implicitHeight + desc.implicitHeight
CustomText {
id: name
text: root.modelData?.name ?? ""
font.pointSize: Appearance.font.size.normal
}
CustomText {
id: desc
text: root.modelData?.desc ?? ""
font.pointSize: Appearance.font.size.small
color: DynamicColors.palette.m3outline
elide: Text.ElideRight
width: root.width - icon.width - Appearance.rounding.normal * 2
anchors.top: name.bottom
}
}
}
}
+74
View File
@@ -0,0 +1,74 @@
import Quickshell
import Quickshell.Widgets
import QtQuick
import qs.Modules.Launcher.Services
import qs.Components
import qs.Helpers
import qs.Config
import qs.Modules
Item {
id: root
required property DesktopEntry modelData
required property PersistentProperties visibilities
implicitHeight: Config.launcher.sizes.itemHeight
anchors.left: parent?.left
anchors.right: parent?.right
StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void {
Apps.launch(root.modelData);
root.visibilities.launcher = false;
}
}
Item {
anchors.fill: parent
anchors.leftMargin: Appearance.padding.larger
anchors.rightMargin: Appearance.padding.larger
anchors.margins: Appearance.padding.smaller
IconImage {
id: icon
source: Quickshell.iconPath(root.modelData?.icon, "image-missing")
implicitSize: parent.height * 0.8
anchors.verticalCenter: parent.verticalCenter
}
Item {
anchors.left: icon.right
anchors.leftMargin: Appearance.spacing.normal
anchors.verticalCenter: icon.verticalCenter
implicitWidth: parent.width - icon.width
implicitHeight: name.implicitHeight + comment.implicitHeight
CustomText {
id: name
text: root.modelData?.name ?? ""
font.pointSize: Appearance.font.size.normal
}
CustomText {
id: comment
text: (root.modelData?.comment || root.modelData?.genericName || root.modelData?.name) ?? ""
font.pointSize: Appearance.font.size.small
color: DynamicColors.palette.m3outline
elide: Text.ElideRight
width: root.width - icon.width - Appearance.rounding.normal * 2
anchors.top: name.bottom
}
}
}
}
+124
View File
@@ -0,0 +1,124 @@
import ZShell
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Components
import qs.Modules
import qs.Helpers
import qs.Config
Item {
id: root
required property var list
readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length)
function onClicked(): void {
Quickshell.execDetached(["wl-copy", Qalculator.eval(math, false)]);
root.list.visibilities.launcher = false;
}
implicitHeight: Config.launcher.sizes.itemHeight
anchors.left: parent?.left
anchors.right: parent?.right
StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void {
root.onClicked();
}
}
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Appearance.padding.larger
spacing: Appearance.spacing.normal
MaterialIcon {
text: "function"
font.pointSize: Appearance.font.size.extraLarge
Layout.alignment: Qt.AlignVCenter
}
CustomText {
id: result
color: {
if (text.includes("error: ") || text.includes("warning: "))
return DynamicColors.palette.m3error;
if (!root.math)
return DynamicColors.palette.m3onSurfaceVariant;
return DynamicColors.palette.m3onSurface;
}
text: root.math.length > 0 ? Qalculator.eval(root.math) : qsTr("Type an expression to calculate")
elide: Text.ElideLeft
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
CustomRect {
color: DynamicColors.palette.m3tertiary
radius: Appearance.rounding.normal
clip: true
implicitWidth: (stateLayer.containsMouse ? label.implicitWidth + label.anchors.rightMargin : 0) + icon.implicitWidth + Appearance.padding.normal * 2
implicitHeight: Math.max(label.implicitHeight, icon.implicitHeight) + Appearance.padding.small * 2
Layout.alignment: Qt.AlignVCenter
StateLayer {
id: stateLayer
color: DynamicColors.palette.m3onTertiary
function onClicked(): void {
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]);
root.list.visibilities.launcher = false;
}
}
CustomText {
id: label
anchors.verticalCenter: parent.verticalCenter
anchors.right: icon.left
anchors.rightMargin: Appearance.spacing.small
text: qsTr("Open in calculator")
color: DynamicColors.palette.m3onTertiary
font.pointSize: Appearance.font.size.normal
opacity: stateLayer.containsMouse ? 1 : 0
Behavior on opacity {
Anim {}
}
}
MaterialIcon {
id: icon
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Appearance.padding.normal
text: "open_in_new"
color: DynamicColors.palette.m3onTertiary
font.pointSize: Appearance.font.size.large
}
Behavior on implicitWidth {
Anim {
easing.bezierCurve: Appearance.anim.curves.expressiveEffects
}
}
}
}
}
+97
View File
@@ -0,0 +1,97 @@
import ZShell.Models
import Quickshell
import QtQuick
import qs.Components
import qs.Helpers
import qs.Config
import qs.Modules
Item {
id: root
required property FileSystemEntry modelData
required property PersistentProperties visibilities
scale: 0.5
opacity: 0
z: PathView.z ?? 0
Component.onCompleted: {
scale = Qt.binding(() => PathView.isCurrentItem ? 1 : PathView.onPath ? 0.8 : 0);
opacity = Qt.binding(() => PathView.onPath ? 1 : 0);
}
implicitWidth: image.width + Appearance.padding.larger * 2
implicitHeight: image.height + label.height + Appearance.spacing.small / 2 + Appearance.padding.large + Appearance.padding.normal
StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void {
Wallpapers.setWallpaper(root.modelData.path);
root.visibilities.launcher = false;
}
}
Elevation {
anchors.fill: image
radius: image.radius
opacity: root.PathView.isCurrentItem ? 1 : 0
level: 4
Behavior on opacity {
Anim {}
}
}
CustomClippingRect {
id: image
anchors.horizontalCenter: parent.horizontalCenter
y: Appearance.padding.large
color: DynamicColors.tPalette.m3surfaceContainer
radius: Appearance.rounding.normal
implicitWidth: Config.launcher.sizes.wallpaperWidth
implicitHeight: implicitWidth / 16 * 9
MaterialIcon {
anchors.centerIn: parent
text: "image"
color: DynamicColors.tPalette.m3outline
font.pointSize: Appearance.font.size.extraLarge * 2
font.weight: 600
}
CachingImage {
path: root.modelData.path
smooth: !root.PathView.view.moving
cache: true
anchors.fill: parent
}
}
CustomText {
id: label
anchors.top: image.bottom
anchors.topMargin: Appearance.spacing.small / 2
anchors.horizontalCenter: parent.horizontalCenter
width: image.width - Appearance.padding.normal * 2
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
renderType: Text.QtRendering
text: root.modelData.relativePath
font.pointSize: Appearance.font.size.normal
}
Behavior on scale {
Anim {}
}
Behavior on opacity {
Anim {}
}
}