diff --git a/Launcher.qml b/Launcher.qml index 788be0f..b87961b 100644 --- a/Launcher.qml +++ b/Launcher.qml @@ -6,15 +6,49 @@ import QtQuick.Effects import "./emojis.mjs" as Emojis PanelWindow { + id: root anchors { top: true } + visible: false implicitHeight: 400 implicitWidth: 1000 exclusionMode: ExclusionMode.Ignore color: "transparent" WlrLayershell.layer: WlrLayershell.Overlay WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive + + IpcHandler { + target: "launcher" + function open() {root.open()} + function clone() {root.close()} + function toggle() {root.visible ? root.close() : root.open()} + } + function open() { + input.text = "" + visible = true + } + function close() { + input.text = "" + visible = false + } + + property var currentItems: { + if (input.text.length === 0 || input.text === ":") { + return [] + } + const searchEmojis = (input.text[0] === ':') + const items = searchEmojis + ? Emojis.emojis.emojis + : Array.from(DesktopEntries.applications.values) + for (let item of items) { + item.searchPos = item.name.toLowerCase().search(input.text.slice(searchEmojis)) + } + return items + .filter(item => item.searchPos !== -1) + .sort((a, b) => a.searchPos - b.searchPos) + } + Rectangle { anchors { top: parent.top @@ -22,10 +56,10 @@ PanelWindow { topMargin: 100 } color: "#181818" - Keys.onEscapePressed: Qt.quit() - height: 60 + height: currentItems.length ? 180 : 60 width: 700 radius: 12 + RectangularShadow { z: -1 anchors.fill: parent @@ -45,12 +79,87 @@ PanelWindow { TextInput { id: input anchors.verticalCenter: parent.verticalCenter - focus: true - font.pixelSize: 20 x: parent.width/2 - this.width/2 Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}} - cursorDelegate: Item {} + focus: true + font.pixelSize: 20 color: "white" + cursorDelegate: Item {} + onCursorPositionChanged: cursorPosition = text.length + Keys.onPressed: (event) => { switch (event.key) { + case Qt.Key_Escape: + root.close(); + break; + case Qt.Key_Return: + list.currentItem.execute(); + root.close(); + break; + case Qt.Key_Right: + list.incrementCurrentIndex(); + break; + case Qt.Key_Left: + list.decrementCurrentIndex(); + break; + }} + } + } + ListView { + id: list + anchors { + top: input.parent.bottom + left: parent.left + right: parent.right + margins: 6 + } + height: 114 + highlightFollowsCurrentItem: true + orientation: ListView.Horizontal + spacing: 6 + model: currentItems.slice(0, 5) + delegate: Rectangle { + anchors { + top: parent.top + bottom: parent.bottom + } + width: (700 - 6*6)/5 + color: ListView.isCurrentItem ? "#222222" : "#181818" + radius: 10 + function execute() { + modelData.emoji + ? Quickshell.clipboardText = modelData.emoji + : modelData.execute() + } + Column { + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + } + Image { + visible: !modelData.emoji + anchors.horizontalCenter: parent.horizontalCenter + width: 64 + height: width + source: Quickshell.iconPath(modelData.icon) + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 64 + text: modelData.emoji ?? "" + } + Text { + anchors { + left: parent.left + right: parent.right + } + width: parent.width - 12 + text: modelData.name + color: "white" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + } + } } } }