163 lines
4.3 KiB
QML
163 lines
4.3 KiB
QML
import Quickshell
|
|
import QtQuick
|
|
import QtQuick.Shapes
|
|
import "../components"
|
|
|
|
PopupWindow {
|
|
id: self
|
|
|
|
property string popupName: ""
|
|
property string activePopup: ""
|
|
|
|
visible: false
|
|
color: "transparent"
|
|
|
|
default property alias content: contentSlot.data
|
|
|
|
readonly property int bw: Theme.borderWidth
|
|
readonly property real r: Theme.radius
|
|
|
|
readonly property bool _open: activePopup === popupName
|
|
on_OpenChanged: {
|
|
if (_open) {
|
|
hideTimer.stop();
|
|
self.visible = true;
|
|
fade.opacity = 1.0;
|
|
} else {
|
|
fade.opacity = 0.0;
|
|
hideTimer.start();
|
|
}
|
|
}
|
|
Timer {
|
|
id: hideTimer
|
|
interval: 200
|
|
onTriggered: self.visible = false
|
|
}
|
|
|
|
Item {
|
|
id: fade
|
|
anchors.fill: parent
|
|
opacity: 0.0
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: 180
|
|
easing.type: Easing.InOutCubic
|
|
}
|
|
}
|
|
|
|
// Background + border in one Shape so fill matches stroke exactly
|
|
Shape {
|
|
id: pbs
|
|
anchors.fill: parent
|
|
|
|
ShapePath {
|
|
strokeWidth: self.bw
|
|
strokeColor: Theme.border
|
|
fillColor: Theme.bg
|
|
|
|
// Start flush at top-left, hidden under bar
|
|
startX: 0
|
|
startY: self.r
|
|
|
|
// Left side down to bottom-left corner
|
|
PathLine {
|
|
x: 0
|
|
y: pbs.height - self.r
|
|
}
|
|
|
|
// Bottom-left corner — Counterclockwise for outward curve
|
|
PathArc {
|
|
x: self.r
|
|
y: pbs.height
|
|
radiusX: self.r
|
|
radiusY: self.r
|
|
direction: PathArc.Counterclockwise
|
|
}
|
|
|
|
// Bottom edge
|
|
PathLine {
|
|
x: pbs.width - self.r
|
|
y: pbs.height
|
|
}
|
|
|
|
// Bottom-right corner — Counterclockwise for outward curve
|
|
PathArc {
|
|
x: pbs.width
|
|
y: pbs.height - self.r
|
|
radiusX: self.r
|
|
radiusY: self.r
|
|
direction: PathArc.Counterclockwise
|
|
}
|
|
|
|
// Right side up, flush to top, hidden under bar
|
|
PathLine {
|
|
x: pbs.width
|
|
y: self.r
|
|
}
|
|
}
|
|
}
|
|
|
|
// // Top-left concave corner
|
|
// Shape {
|
|
// x: 0
|
|
// y: 0
|
|
// width: self.r
|
|
// height: self.r
|
|
// ShapePath {
|
|
// fillColor: Theme.bg
|
|
// strokeColor: "transparent"
|
|
// startX: 0
|
|
// startY: 0
|
|
// PathLine {
|
|
// x: self.r
|
|
// y: 0
|
|
// }
|
|
// PathArc {
|
|
// x: 0
|
|
// y: self.r
|
|
// radiusX: self.r
|
|
// radiusY: self.r
|
|
// direction: PathArc.Clockwise
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// // Top-right concave corner
|
|
// Shape {
|
|
// x: parent.width - self.r
|
|
// y: 0
|
|
// width: self.r
|
|
// height: self.r
|
|
// ShapePath {
|
|
// fillColor: Theme.bg
|
|
// strokeColor: "transparent"
|
|
// startX: self.r
|
|
// startY: 0
|
|
// PathLine {
|
|
// x: 0
|
|
// y: 0
|
|
// }
|
|
// PathArc {
|
|
// x: self.r
|
|
// y: self.r
|
|
// radiusX: self.r
|
|
// radiusY: self.r
|
|
// direction: PathArc.Counterclockwise
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
Item {
|
|
id: contentSlot
|
|
anchors {
|
|
top: parent.top
|
|
topMargin: self.r + self.bw
|
|
left: parent.left
|
|
leftMargin: self.bw
|
|
right: parent.right
|
|
rightMargin: self.bw
|
|
}
|
|
}
|
|
}
|
|
}
|