import Quickshell import QtQuick import qs.Services MouseArea { id: root anchors.centerIn: parent height: parent.implicitHeight width: musicRow.implicitWidth state: "POPUP_CLOSED" hoverEnabled: true onEntered: state = "POPUP_OPEN" property string fontFamily: "FiraCode Nerd Font" property int fontSize: 14 property int contractAnimDuration: 150 states: [ State { name: "POPUP_CLOSED" PropertyChanges { target: popup; visible: false } PropertyChanges { target: musicRow; visible: true; spacing: 4 } PropertyChanges { target: songContainer; bottomRightRadius: 4; topRightRadius: 4 } PropertyChanges { target: cavaContainer; bottomLeftRadius: 4; topLeftRadius: 4 } PropertyChanges { target: song; opacity: 1 } PropertyChanges { target: cava; opacity: 1 } PropertyChanges { target: popupRect width: musicRow.width height: 36 border.color: Flexoki.bg } }, State { name: "POPUP_OPEN" PropertyChanges { target: popup; visible: true } PropertyChanges { target: musicRow; visible: false; spacing: -1 } PropertyChanges { target: songContainer; bottomRightRadius: 0; topRightRadius: 0 } PropertyChanges { target: cavaContainer; bottomLeftRadius: 0; topLeftRadius: 0 } PropertyChanges { target: song; opacity: 0 } PropertyChanges { target: cava; opacity: 0 } PropertyChanges { target: popupRect width: 700 height: 500 border.color: Flexoki.ui2 } } ] transitions: [ Transition { from: "POPUP_CLOSED" to: "POPUP_OPEN" SequentialAnimation { ParallelAnimation { NumberAnimation { target: songContainer properties: "bottomRightRadius,topRightRadius" duration: root.contractAnimDuration easing.type: Easing.InQuad } NumberAnimation { target: cavaContainer properties: "bottomLeftRadius,topLeftRadius" duration: root.contractAnimDuration easing.type: Easing.InQuad } NumberAnimation { target: musicRow property: "spacing" duration: root.contractAnimDuration easing.type: Easing.OutQuad } NumberAnimation { targets: [song, cava] property: "opacity" duration: root.contractAnimDuration easing.type: Easing.OutQuad } } PropertyAction { target: popup; property: "visible" } PropertyAction { target: musicRow; property: "visible" } ParallelAnimation { NumberAnimation { target: popupRect property: "width" duration: 250 easing.type: Easing.OutQuad } SpringAnimation { target: popupRect property: "height" spring: 5 mass: 0.5 damping: 0.2 epsilon: 0.25 } ColorAnimation { target: popupRect property: "border.color" duration: 250 easing.type: Easing.OutQuad } } } }, Transition { from: "POPUP_OPEN" to: "POPUP_CLOSED" SequentialAnimation { ParallelAnimation { NumberAnimation { target: popupRect property: "width" duration: 250 easing.type: Easing.OutQuad } NumberAnimation { target: popupRect property: "height" duration: 250 easing.type: Easing.OutQuad } ColorAnimation { target: popupRect property: "border.color" duration: 250 easing.type: Easing.OutQuad } } PropertyAction { target: musicRow; property: "visible" } PropertyAction { target: popup; property: "visible" } ParallelAnimation { NumberAnimation { target: songContainer properties: "bottomRightRadius,topRightRadius" duration: root.contractAnimDuration easing.type: Easing.InQuad } NumberAnimation { target: cavaContainer properties: "bottomLeftRadius,topLeftRadius" duration: root.contractAnimDuration easing.type: Easing.InQuad } NumberAnimation { target: musicRow property: "spacing" duration: root.contractAnimDuration easing.type: Easing.OutQuad } NumberAnimation { targets: [song, cava] property: "opacity" duration: root.contractAnimDuration easing.type: Easing.OutQuad } } } }, ] PopupWindow { id: popup anchor.item: root anchor.rect.x: root.width / 2 - width / 2 anchor.rect.y: 0 implicitWidth: 1920 implicitHeight: 600 color: "transparent" visible: false Rectangle { id: popupRect anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top width: 700 height: 36 color: Flexoki.bg border.color: Flexoki.ui border.width: 2 radius: 18 MouseArea { anchors.fill: parent hoverEnabled: true onExited: root.state = "POPUP_CLOSED" } Text { visible: false anchors.centerIn: parent color: Flexoki.tx text: "Hello world!" } } } Row { id: musicRow anchors.centerIn: parent height: parent.height spacing: 4 Rectangle { id: songContainer implicitWidth: song.implicitWidth + 16*2 height: parent.height color: Flexoki.bg bottomLeftRadius: 18 topLeftRadius: 18 bottomRightRadius: 4 topRightRadius: 4 Text { id: song anchors.centerIn: parent text: { if (!Song.file) return "Not playing" var text = Song.file if (Song.title) { if (Song.artist) { text = Song.artist + " – " + Song.title } else { text = Song.title } } if (text.length > 60) { text = text.substring(0, 60) + "…" } return text } color: Flexoki.tx font { family: root.fontFamily; pixelSize: root.fontSize } } } Rectangle { id: cavaContainer implicitWidth: cava.implicitWidth + 16*2 height: parent.height color: Flexoki.bg bottomLeftRadius: 4 topLeftRadius: 4 bottomRightRadius: 18 topRightRadius: 18 Row { id: cava anchors.centerIn: parent height: 15 + 4 spacing: 2 Repeater { model: Cava.heights delegate: Rectangle { required property int modelData y: 15 - modelData width: 8 height: modelData + 4 radius: 4 color: Flexoki.tx Behavior on height { NumberAnimation { duration: 1000 / 30; easing.type: Easing.Linear } } Behavior on y { NumberAnimation { duration: 1000 / 30; easing.type: Easing.Linear } } } } } } } }