animations...
This commit is contained in:
+159
-20
@@ -6,12 +6,41 @@ import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell.Hyprland
|
||||
|
||||
PopupWindow {
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
signal menuActionTriggered()
|
||||
required property QsMenuOpener menu
|
||||
required property point trayItemRect
|
||||
required property PanelWindow bar
|
||||
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() {
|
||||
let count = 0;
|
||||
@@ -24,6 +53,7 @@ PopupWindow {
|
||||
}
|
||||
}
|
||||
if ( root.menuStack.length > 0 ) {
|
||||
backEntry.visible = true;
|
||||
count++;
|
||||
}
|
||||
return (count * entryHeight) + ((count - 1) * 2) + (separatorCount * 3) + 10;
|
||||
@@ -47,12 +77,16 @@ PopupWindow {
|
||||
function goBack() {
|
||||
if ( root.menuStack.length > 0 ) {
|
||||
root.menu = root.menuStack.pop();
|
||||
backEntry.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if ( visible ) {
|
||||
root.menuStack = [];
|
||||
if ( !visible ) {
|
||||
goBack();
|
||||
} else {
|
||||
scaleValue = 0;
|
||||
scaleAnimation.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,38 +95,121 @@ PopupWindow {
|
||||
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 {
|
||||
duration: MaterialEasing.standardTime
|
||||
easing.bezierCurve: MaterialEasing.standard
|
||||
NumberAnimation {
|
||||
id: scaleAnimation
|
||||
target: root
|
||||
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 {
|
||||
duration: MaterialEasing.standardTime
|
||||
easing.bezierCurve: MaterialEasing.standard
|
||||
|
||||
Behavior on menu {
|
||||
SequentialAnimation {
|
||||
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 {
|
||||
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"
|
||||
radius: 8
|
||||
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 {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
spacing: 0
|
||||
transform: [
|
||||
Translate {
|
||||
id: translateAnim
|
||||
x: 0
|
||||
y: 0
|
||||
}
|
||||
]
|
||||
ListView {
|
||||
id: listLayout
|
||||
Layout.fillWidth: true
|
||||
@@ -101,6 +218,27 @@ PopupWindow {
|
||||
model: ScriptModel {
|
||||
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 {
|
||||
id: menuItem
|
||||
required property QsMenuEntry modelData
|
||||
@@ -177,7 +315,8 @@ PopupWindow {
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
visible: true
|
||||
id: backEntry
|
||||
visible: false
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.entryHeight
|
||||
color: mouseAreaBack.containsMouse ? "#15FFFFFF" : "transparent"
|
||||
|
||||
Reference in New Issue
Block a user