mirror of
https://github.com/kossLAN/dots.git
synced 2025-11-04 22:49:50 -05:00
160 lines
4.4 KiB
QML
160 lines
4.4 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Hyprland
|
|
import qs.widgets
|
|
|
|
Scope {
|
|
id: root
|
|
|
|
required property var bar
|
|
|
|
property real gaps: 5
|
|
|
|
property Item parentItem
|
|
property PopupItem activeItem
|
|
property PopupItem lastActiveItem
|
|
|
|
property PopupItem shownItem: activeItem ?? lastActiveItem
|
|
|
|
onActiveItemChanged: {
|
|
if (activeItem != null) {
|
|
activeItem.targetVisible = true;
|
|
|
|
if (parentItem) {
|
|
activeItem.parent = parentItem;
|
|
}
|
|
}
|
|
|
|
if (lastActiveItem != null && lastActiveItem != activeItem) {
|
|
lastActiveItem.targetVisible = false;
|
|
}
|
|
}
|
|
|
|
function setItem(item: PopupItem) {
|
|
if (activeItem != null) {
|
|
lastActiveItem = activeItem;
|
|
}
|
|
|
|
activeItem = item;
|
|
}
|
|
|
|
function removeItem(item: PopupItem) {
|
|
if (activeItem == item) {
|
|
activeItem = null;
|
|
}
|
|
}
|
|
|
|
function onHidden(item: PopupItem) {
|
|
if (item == lastActiveItem) {
|
|
lastActiveItem = null;
|
|
}
|
|
}
|
|
|
|
LazyLoader {
|
|
id: popupLoader
|
|
activeAsync: root.shownItem != null
|
|
|
|
PopupWindow {
|
|
id: popup
|
|
visible: true
|
|
color: "transparent"
|
|
implicitWidth: root.bar.width
|
|
implicitHeight: Math.max(800, parentItem.targetHeight)
|
|
|
|
anchor {
|
|
window: root.bar
|
|
rect: Qt.rect(0, 0, root.bar.width, root.bar.height)
|
|
edges: Edges.Bottom | Edges.Left
|
|
gravity: Edges.Bottom | Edges.Right
|
|
adjustment: PopupAdjustment.None
|
|
}
|
|
|
|
mask: Region {
|
|
item: parentItem
|
|
}
|
|
|
|
HyprlandFocusGrab {
|
|
id: grab
|
|
active: true
|
|
windows: [popup, root.bar]
|
|
onCleared: {
|
|
root.shownItem.closed();
|
|
}
|
|
}
|
|
|
|
HyprlandWindow.visibleMask: Region {
|
|
id: mask
|
|
item: parentItem
|
|
}
|
|
|
|
StyledRectangle {
|
|
id: parentItem
|
|
width: targetWidth
|
|
height: targetHeight
|
|
x: targetX
|
|
y: root.gaps
|
|
clip: true
|
|
|
|
readonly property var targetWidth: root.shownItem?.implicitWidth ?? 0
|
|
readonly property var targetHeight: root.shownItem?.implicitHeight ?? 0
|
|
|
|
readonly property var targetX: {
|
|
if (root.shownItem == null) {
|
|
return 0;
|
|
}
|
|
|
|
let owner = root.shownItem.owner;
|
|
let bar = root.bar;
|
|
let xPos = owner.mapToItem(bar.contentItem, 0, bar.height, owner.width, 0).x;
|
|
|
|
let rightEdge = xPos + targetWidth;
|
|
let maxRightEdge = popup.width;
|
|
|
|
if (rightEdge > maxRightEdge) {
|
|
// touching right edge, reposition
|
|
// console.log("touching right edge");
|
|
return maxRightEdge - targetWidth - root.gaps;
|
|
}
|
|
|
|
return xPos;
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
root.parentItem = this;
|
|
|
|
if (root.activeItem) {
|
|
root.activeItem.parent = this;
|
|
}
|
|
}
|
|
|
|
// TODO: Make a close animation, a little complicated, will need to track if an animation is running
|
|
// and stop unload from occuring until its done, in the LazyLoader.
|
|
|
|
Behavior on width {
|
|
enabled: root.lastActiveItem != null
|
|
SmoothedAnimation {
|
|
duration: 300
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on height {
|
|
SmoothedAnimation {
|
|
duration: 300
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on x {
|
|
enabled: root.lastActiveItem != null
|
|
SmoothedAnimation {
|
|
duration: 300
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|