animations...

This commit is contained in:
Zacharias-Brohn
2025-11-03 14:47:25 +01:00
parent 2da31b485e
commit 2fea7d56bc
4 changed files with 171 additions and 38 deletions
+1
View File
@@ -29,6 +29,7 @@ Scope {
color: "transparent" color: "transparent"
Rectangle { Rectangle {
id: backgroundRect
anchors.fill: parent anchors.fill: parent
color: "#801a1a1a" color: "#801a1a1a"
radius: 0 radius: 0
+9 -18
View File
@@ -14,6 +14,8 @@ MouseArea {
id: root id: root
required property SystemTrayItem item required property SystemTrayItem item
required property PanelWindow bar
property point globalPos
implicitWidth: 22 implicitWidth: 22
implicitHeight: 22 implicitHeight: 22
@@ -21,6 +23,10 @@ MouseArea {
hoverEnabled: true hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onPositionChanged: {
globalPos = root.mapToItem(root.bar.backgroundRect, 0, 0);
}
IconImage { IconImage {
id: icon id: icon
@@ -51,23 +57,8 @@ MouseArea {
TrayMenu { TrayMenu {
id: trayMenu id: trayMenu
menu: menuOpener menu: menuOpener
anchor.item: root trayItemRect: root.globalPos
anchor.edges: Edges.Bottom bar: root.bar
anchor.rect.x: 11
anchor.rect.y: 25
onVisibleChanged: {
if ( grab.active && !visible ) {
grab.active = false;
}
}
HyprlandFocusGrab {
id: grab
windows: [ trayMenu ]
onCleared: {
trayMenu.visible = false;
}
}
} }
} }
@@ -79,7 +70,7 @@ MouseArea {
trayMenu.menu = menuOpener; trayMenu.menu = menuOpener;
} }
trayMenu.visible = !trayMenu.visible; trayMenu.visible = !trayMenu.visible;
grab.active = true; console.log(root.x);
} }
} }
+159 -20
View File
@@ -6,12 +6,41 @@ import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import Quickshell.Hyprland import Quickshell.Hyprland
PopupWindow { PanelWindow {
id: root id: root
signal menuActionTriggered() signal menuActionTriggered()
required property QsMenuOpener menu required property QsMenuOpener menu
required property point trayItemRect
required property PanelWindow bar
property var menuStack: [] property var menuStack: []
property real scaleValue: 0
property int height: calcHeight()
property int entryHeight: 30
property int maxWidth: {
let menuWidth = 0;
for ( let i = 0; i < listLayout.count; i++ ) {
if ( !listLayout.model.values[i].isSeparator ) {
let entry = listLayout.model.values[i];
tempMetrics.text = entry.text;
let textWidth = tempMetrics.width + 20 + (entry.icon ?? "" ? 30 : 0) + (entry.hasChildren ? 30 : 0);
if ( textWidth > menuWidth ) {
menuWidth = textWidth;
}
}
}
return menuWidth;
}
visible: false
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
function calcHeight() { function calcHeight() {
let count = 0; let count = 0;
@@ -24,6 +53,7 @@ PopupWindow {
} }
} }
if ( root.menuStack.length > 0 ) { if ( root.menuStack.length > 0 ) {
backEntry.visible = true;
count++; count++;
} }
return (count * entryHeight) + ((count - 1) * 2) + (separatorCount * 3) + 10; return (count * entryHeight) + ((count - 1) * 2) + (separatorCount * 3) + 10;
@@ -47,12 +77,16 @@ PopupWindow {
function goBack() { function goBack() {
if ( root.menuStack.length > 0 ) { if ( root.menuStack.length > 0 ) {
root.menu = root.menuStack.pop(); root.menu = root.menuStack.pop();
backEntry.visible = false;
} }
} }
onVisibleChanged: { onVisibleChanged: {
if ( visible ) { if ( !visible ) {
root.menuStack = []; goBack();
} else {
scaleValue = 0;
scaleAnimation.start();
} }
} }
@@ -61,38 +95,121 @@ PopupWindow {
text: "" text: ""
} }
property int height: calcHeight()
property int entryHeight: 30
property int maxWidth: calcWidth()
implicitWidth: maxWidth + 20
implicitHeight: height
color: "transparent"
anchor.gravity: Edges.Bottom
Behavior on implicitHeight { NumberAnimation {
NumberAnimation { id: scaleAnimation
duration: MaterialEasing.standardTime target: root
easing.bezierCurve: MaterialEasing.standard property: "scaleValue"
from: 0
to: 1
duration: 150
easing.type: Easing.OutCubic
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
root.visible = false;
} }
} }
Behavior on implicitWidth {
NumberAnimation { Behavior on menu {
duration: MaterialEasing.standardTime SequentialAnimation {
easing.bezierCurve: MaterialEasing.standard ParallelAnimation {
NumberAnimation {
duration: MaterialEasing.standardTime / 2
easing.bezierCurve: MaterialEasing.expressiveEffects
from: 0
property: "x"
target: translateAnim
to: -listLayout.width / 2
}
NumberAnimation {
duration: MaterialEasing.standardTime / 2
easing.bezierCurve: MaterialEasing.standard
from: 1
property: "opacity"
target: columnLayout
to: 0
}
}
PropertyAction {
property: "menu"
target: columnLayout
}
ParallelAnimation {
NumberAnimation {
duration: MaterialEasing.standardTime / 2
easing.bezierCurve: MaterialEasing.standard
from: 0
property: "opacity"
target: columnLayout
to: 1
}
NumberAnimation {
duration: MaterialEasing.standardTime / 2
easing.bezierCurve: MaterialEasing.expressiveEffects
from: listLayout.width / 2
property: "x"
target: translateAnim
to: 0
}
}
} }
} }
Rectangle { Rectangle {
id: menuRect id: menuRect
anchors.fill: parent x: root.trayItemRect.x - ( menuRect.implicitWidth / 2 ) + 10
y: root.trayItemRect.y - 5
implicitHeight: root.height
implicitWidth: root.maxWidth + 20
color: "#80151515" color: "#80151515"
radius: 8 radius: 8
border.color: "#40FFFFFF" border.color: "#40FFFFFF"
clip: true
Behavior on implicitHeight {
NumberAnimation {
duration: MaterialEasing.standardTime
easing.bezierCurve: MaterialEasing.standard
}
}
Behavior on implicitWidth {
NumberAnimation {
duration: MaterialEasing.standardTime
easing.bezierCurve: MaterialEasing.standard
}
}
transform: [
Scale {
origin.x: menuRect.width / 2
origin.y: 0
xScale: root.scaleValue
yScale: root.scaleValue
}
]
ColumnLayout { ColumnLayout {
id: columnLayout
anchors.fill: parent anchors.fill: parent
anchors.margins: 5 anchors.margins: 5
spacing: 0 spacing: 0
transform: [
Translate {
id: translateAnim
x: 0
y: 0
}
]
ListView { ListView {
id: listLayout id: listLayout
Layout.fillWidth: true Layout.fillWidth: true
@@ -101,6 +218,27 @@ PopupWindow {
model: ScriptModel { model: ScriptModel {
values: [...root.menu?.children.values] values: [...root.menu?.children.values]
} }
add: Transition {
NumberAnimation {
property: "x"
from: listLayout.width
to: 0
duration: 200
easing.type: Easing.OutCubic
}
}
move: Transition {
NumberAnimation {
property: "x"
from: 0
to: -listLayout.width
duration: 200
easing.type: Easing.InCubic
}
}
delegate: Rectangle { delegate: Rectangle {
id: menuItem id: menuItem
required property QsMenuEntry modelData required property QsMenuEntry modelData
@@ -177,7 +315,8 @@ PopupWindow {
} }
} }
Rectangle { Rectangle {
visible: true id: backEntry
visible: false
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: root.entryHeight Layout.preferredHeight: root.entryHeight
color: mouseAreaBack.containsMouse ? "#15FFFFFF" : "transparent" color: mouseAreaBack.containsMouse ? "#15FFFFFF" : "transparent"
+2
View File
@@ -20,8 +20,10 @@ Rectangle {
id: repeater id: repeater
model: SystemTray.items model: SystemTray.items
TrayItem { TrayItem {
id: trayItem
required property SystemTrayItem modelData required property SystemTrayItem modelData
item: modelData item: modelData
bar: root.bar
} }
} }
} }