mirror of
https://github.com/kossLAN/dots.git
synced 2025-11-04 22:49:50 -05:00
151 lines
3.9 KiB
QML
151 lines
3.9 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import Quickshell
|
|
import Quickshell.Widgets
|
|
import Quickshell.Hyprland
|
|
import QtQuick
|
|
import qs
|
|
|
|
PopupWindow {
|
|
id: root
|
|
visible: false
|
|
color: "transparent"
|
|
implicitWidth: bar.width
|
|
implicitHeight: Math.max(1000, bar.height)
|
|
mask: Region {
|
|
item: surface
|
|
}
|
|
|
|
anchor {
|
|
window: bar
|
|
rect: Qt.rect(0, 0, bar.width, bar.height)
|
|
edges: Edges.Bottom | Edges.Left
|
|
gravity: Edges.Bottom | Edges.Right
|
|
adjustment: PopupAdjustment.None
|
|
}
|
|
|
|
required property var bar
|
|
property var currentMenu
|
|
property real padding: 5
|
|
|
|
function set(item) {
|
|
|
|
// Clear surface
|
|
if (content.children.includes(item.menu)) {
|
|
console.log("Clearing popup surface.");
|
|
root.currentMenu = undefined;
|
|
content.children = [];
|
|
// surface.implicitHeight = 0;
|
|
surface.opacity = 0;
|
|
contentOpacity.restart();
|
|
grab.active = false;
|
|
return;
|
|
}
|
|
|
|
// Set surface
|
|
console.log("Setting popup surface.");
|
|
root.visible = true;
|
|
root.currentMenu = item.menu
|
|
content.children = [item.menu];
|
|
// content.implicitWidth = item.menu.implicitWidth;
|
|
// content.implicitHeight = item.menu.implicitHeight;
|
|
|
|
let itemPos = item.mapToItem(root.bar.contentItem, 0, root.bar.height, item.width, 0).x;
|
|
|
|
// Check right edge
|
|
let rightEdge = itemPos + surface.implicitWidth;
|
|
let maxRightEdge = root.width - padding;
|
|
let isTouchingRightEdge = rightEdge > maxRightEdge;
|
|
|
|
if (isTouchingRightEdge) {
|
|
// touching right edge, reposition
|
|
surface.x = maxRightEdge - surface.implicitWidth;
|
|
surface.y = padding;
|
|
} else {
|
|
// not touching right edge
|
|
surface.x = itemPos;
|
|
surface.y = padding;
|
|
}
|
|
|
|
surface.opacity = 1;
|
|
contentOpacity.restart();
|
|
grab.active = true;
|
|
}
|
|
|
|
HyprlandFocusGrab {
|
|
id: grab
|
|
windows: [root, root.bar]
|
|
onCleared: {
|
|
surface.opacity = 0;
|
|
contentOpacity.restart();
|
|
root.currentMenu = undefined;
|
|
content.children = [];
|
|
}
|
|
}
|
|
|
|
WrapperRectangle {
|
|
id: surface
|
|
opacity: 0
|
|
visible: opacity > 0
|
|
color: ShellSettings.colors.surface_translucent
|
|
clip: true
|
|
margin: 5
|
|
radius: 12
|
|
|
|
border {
|
|
width: 1
|
|
color: ShellSettings.colors.active_translucent
|
|
}
|
|
|
|
// Animating implicit widht/height causes issues, this works but
|
|
// is kind of cursed, but fuck it. Better solutions welcome.
|
|
width: implicitWidth
|
|
height: implicitHeight
|
|
|
|
Item {
|
|
id: content
|
|
implicitWidth: Math.max(root.currentMenu?.width, 60)
|
|
implicitHeight: root.currentMenu?.height ?? 0
|
|
|
|
NumberAnimation {
|
|
id: contentOpacity
|
|
target: content
|
|
property: "opacity"
|
|
from: 0
|
|
to: 1
|
|
duration: 300
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: 250
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on width {
|
|
enabled: root.visible
|
|
SmoothedAnimation {
|
|
duration: 250
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on height {
|
|
SmoothedAnimation {
|
|
duration: 250
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
|
|
Behavior on x {
|
|
enabled: root.visible
|
|
SmoothedAnimation {
|
|
duration: 250
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
}
|
|
}
|