115 lines
2.7 KiB
QML
115 lines
2.7 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import "." as M
|
|
|
|
// Shared flyout popup window — slides down from the bar, dismisses on
|
|
// click outside. Created on demand via Loader; animates in on creation,
|
|
// animates out then emits dismissed() for the Loader to deactivate.
|
|
PanelWindow {
|
|
id: root
|
|
|
|
default property alias content: contentCol.children
|
|
required property var screen
|
|
required property real anchorX
|
|
property real panelWidth: 220
|
|
|
|
signal dismissed
|
|
|
|
visible: true
|
|
color: "transparent"
|
|
|
|
WlrLayershell.layer: WlrLayer.Overlay
|
|
WlrLayershell.exclusiveZone: 0
|
|
WlrLayershell.namespace: "nova-popup"
|
|
|
|
anchors.top: true
|
|
anchors.left: true
|
|
anchors.right: true
|
|
anchors.bottom: true
|
|
|
|
Component.onCompleted: showAnim.start()
|
|
|
|
function dismiss() {
|
|
showAnim.stop();
|
|
hideAnim.start();
|
|
}
|
|
|
|
// Click outside → dismiss
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: root.dismiss()
|
|
}
|
|
|
|
Item {
|
|
id: panel
|
|
|
|
x: Math.max(0, Math.min(Math.round(root.anchorX - contentCol.width / 2), root.width - contentCol.width))
|
|
y: 0
|
|
width: contentCol.width
|
|
height: contentCol.height
|
|
opacity: 0
|
|
|
|
// Eat clicks inside the panel
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: M.Theme.base01
|
|
opacity: Math.max(M.Theme.barOpacity, 0.85)
|
|
topLeftRadius: 0
|
|
topRightRadius: 0
|
|
bottomLeftRadius: M.Theme.radius
|
|
bottomRightRadius: M.Theme.radius
|
|
}
|
|
|
|
Column {
|
|
id: contentCol
|
|
width: root.panelWidth
|
|
topPadding: 4
|
|
bottomPadding: 4
|
|
spacing: 2
|
|
}
|
|
}
|
|
|
|
ParallelAnimation {
|
|
id: showAnim
|
|
NumberAnimation {
|
|
target: panel
|
|
property: "opacity"
|
|
from: 0
|
|
to: 1
|
|
duration: 150
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
NumberAnimation {
|
|
target: panel
|
|
property: "y"
|
|
from: -panel.height
|
|
to: 0
|
|
duration: 200
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
ParallelAnimation {
|
|
id: hideAnim
|
|
NumberAnimation {
|
|
target: panel
|
|
property: "opacity"
|
|
to: 0
|
|
duration: 150
|
|
easing.type: Easing.InCubic
|
|
}
|
|
NumberAnimation {
|
|
target: panel
|
|
property: "y"
|
|
to: -panel.height
|
|
duration: 150
|
|
easing.type: Easing.InCubic
|
|
}
|
|
onFinished: root.dismissed()
|
|
}
|
|
}
|