Merge status bar and launcher into morphing top bar

This commit is contained in:
2026-02-25 03:09:27 -08:00
parent ea9f96dab7
commit 86cf291663
7 changed files with 436 additions and 340 deletions

View File

@@ -5,37 +5,10 @@ import QtQuick
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 = ""
root.visible = true
exit.stop();
entry.start();
}
function close() {
input.text = ""
entry.stop();
exit.start();
}
Item {
height: currentItems.length ? 180 : 60
width: 700
property var show: input.text.length
property var currentItems: {
if (input.text.length === 0 || input.text === ":") {
return []
@@ -55,194 +28,142 @@ PanelWindow {
Rectangle {
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
topMargin: 100
left: parent.left
right: parent.right
margins: 6
}
height: 48
color: "#181818"
height: currentItems.length ? 180 : 60
Behavior on height { NumberAnimation {
duration: 300
easing.type: Easing.OutQuint
radius: 10
TextInput {
id: input
anchors.verticalCenter: parent.verticalCenter
x: parent.width/2 - this.width/2
Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}}
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
onCurrentIndexChanged: background.indexChanged()
orientation: ListView.Horizontal
spacing: 6
add: Transition { NumberAnimation {
property: "opacity"
from: 0
to: 1
duration: 150
}}
width: 700
radius: 12
RectangularShadow {
z: -1
anchors.fill: parent
radius: 12
blur: 10
spread: 2
}
Rectangle {
anchors {
top: parent.top
left: parent.left
right: parent.right
margins: 6
remove: Transition { NumberAnimation {
property: "opacity"
from: 1
to: 0
duration: 150
}}
displaced: Transition {
NumberAnimation {
property: "x"
duration: 300
easing.type: Easing.OutQuint
onStarted: console.log("displaced")
}
height: 48
color: "#222222"
radius: 10
TextInput {
id: input
anchors.verticalCenter: parent.verticalCenter
x: parent.width/2 - this.width/2
Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}}
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
add: Transition { NumberAnimation {
NumberAnimation {
property: "opacity"
from: 0
to: 1
duration: 150
}}
remove: Transition { NumberAnimation {
property: "opacity"
from: 1
to: 0
duration: 150
}}
displaced: Transition {
NumberAnimation {
property: "x"
duration: 300
easing.type: Easing.OutQuint
onStarted: console.log("displaced")
}
NumberAnimation {
property: "opacity"
to: 1
duration: 150
}
}
}
model: ScriptModel {values: currentItems.slice(0, 5)}
delegate: Rectangle {
id: item
model: ScriptModel {values: currentItems.slice(0, 5)}
delegate: Rectangle {
id: item
anchors {
top: parent?.top
bottom: parent?.bottom
}
width: (700 - 6*6)/5
color: "#20181818"
ListView.onIsCurrentItemChanged: ListView.isCurrentItem ? selectAnim.start() : deselectAnim.start()
property var selectAnim: ColorAnimation {
target: item
property: "color"
to: "#10ffffff"
duration: 200
easing.type: Easing.OutQuint
}
property var deselectAnim: ColorAnimation {
target: item
onStarted: selectAnim.stop()
property: "color"
to: "#00181818"
duration: 200
easing.type: Easing.InQuint
}
radius: 10
function execute() {
modelData.emoji
? Quickshell.clipboardText = modelData.emoji
: modelData.execute()
}
Column {
anchors {
top: parent?.top
bottom: parent?.bottom
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
width: (700 - 6*6)/5
color: "#20181818"
ListView.onIsCurrentItemChanged: ListView.isCurrentItem ? selectAnim.start() : deselectAnim.start()
property var selectAnim: ColorAnimation {
target: item
property: "color"
to: "#10ffffff"
duration: 200
easing.type: Easing.OutQuint
Image {
visible: !modelData.emoji
anchors.horizontalCenter: parent.horizontalCenter
width: 64
height: width
source: Quickshell.iconPath(modelData.icon)
}
property var deselectAnim: ColorAnimation {
target: item
onStarted: selectAnim.stop()
property: "color"
to: "#00181818"
duration: 200
easing.type: Easing.InQuint
Text {
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 64
text: modelData.emoji ?? ""
}
radius: 10
function execute() {
modelData.emoji
? Quickshell.clipboardText = modelData.emoji
: modelData.execute()
}
Column {
Text {
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
}
width: parent.width - 12
text: modelData.name
color: "white"
font.pixelSize: 16
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
}
}
}
transform: Translate {
y: -50
NumberAnimation on y {
id: entry
to: 0
duration: 300
easing.type: Easing.OutQuint
}
NumberAnimation on y {
id: exit
to: -50
duration: 300
easing.type: Easing.InQuint
onFinished: root.visible = false
}
}
opacity: 0
NumberAnimation on opacity {
running: entry.running
to: 1
duration: entry.duration/2
}
SequentialAnimation on opacity {
running: exit.running
PauseAnimation {duration: exit.duration/2}
NumberAnimation {
to: 0
duration: exit.duration/2
}
}
}
}