tray menu refresh
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
// CustomTrayMenu.qml
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import QtQuick.Window // for Window, flags
|
||||
import qs.Modules
|
||||
|
||||
PopupWindow {
|
||||
id: popup
|
||||
color: "#00202020"
|
||||
|
||||
required property QsMenuOpener trayMenu
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
anchors.fill: parent
|
||||
spacing: 4
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: popup.trayMenu.children
|
||||
Row {
|
||||
id: entryRow
|
||||
anchors.fill: parent
|
||||
property var entry: modelData
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (entryRow.entry.triggered) {
|
||||
entryRow.entry.triggered()
|
||||
}
|
||||
popup.visible = false
|
||||
}
|
||||
}
|
||||
Image {
|
||||
source: entryRow.entry.icon
|
||||
width: 20; height: 20
|
||||
visible: entryRow.entry.icon !== ""
|
||||
}
|
||||
Text {
|
||||
text: entryRow.entry.text
|
||||
color: "black"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ Item {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.family: "Material Symbols Rounded"
|
||||
font.pixelSize: 16
|
||||
text: ""
|
||||
text: "\ue30f"
|
||||
color: "#ffffff"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Hyprland
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
required property QsMenuHandle menu
|
||||
property int height: entryCount * ( entryHeight + 3 )
|
||||
property int entryHeight: 30
|
||||
property int entryCount: 0
|
||||
implicitWidth: 300
|
||||
implicitHeight: height
|
||||
color: "transparent"
|
||||
|
||||
QsMenuOpener {
|
||||
id: menuOpener
|
||||
menu: root.menu
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [ root ]
|
||||
onCleared: {
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
grab.active = root.visible;
|
||||
}
|
||||
Rectangle {
|
||||
id: menuRect
|
||||
anchors.fill: parent
|
||||
color: "#90000000"
|
||||
radius: 8
|
||||
border.color: "#10FFFFFF"
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: 5
|
||||
spacing: 2
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: menuOpener.children
|
||||
Rectangle {
|
||||
id: menuItem
|
||||
width: root.implicitWidth
|
||||
Layout.maximumWidth: parent.width
|
||||
Layout.fillHeight: true
|
||||
height: root.entryHeight
|
||||
color: mouseArea.containsMouse && !modelData.isSeparator ? "#15FFFFFF" : "transparent"
|
||||
radius: 4
|
||||
visible: modelData.isSeparator ? false : true
|
||||
required property QsMenuEntry modelData
|
||||
|
||||
Component.onCompleted: {
|
||||
if ( !modelData.isSeparator ) {
|
||||
root.entryCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
preventStealing: true
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: {
|
||||
if ( !menuItem.modelData.hasChildren ) {
|
||||
menuItem.modelData.triggered();
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
text: menuItem.modelData.text
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -48,7 +48,7 @@ Item {
|
||||
|
||||
Process {
|
||||
id: swayncProcess
|
||||
command: ["swaync-client", "-t", "-sw"]
|
||||
command: ["sh", "-c", "qs -p /home/zach/GitProjects/z-bar-qt/notification-test/shell.qml ipc call root showCenter"]
|
||||
running: false
|
||||
}
|
||||
|
||||
|
||||
+13
-18
@@ -3,8 +3,8 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import Caelestia
|
||||
import Quickshell
|
||||
import Quickshell.DBusMenu
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Services.SystemTray
|
||||
@@ -38,35 +38,30 @@ MouseArea {
|
||||
smooth: false
|
||||
asynchronous: true
|
||||
|
||||
ImageAnalyser {
|
||||
id: analyser
|
||||
sourceItem: icon
|
||||
rescaleSize: 22
|
||||
}
|
||||
|
||||
TrayMenu {
|
||||
id: trayMenu
|
||||
menu: menuOpener
|
||||
trayMenu: root.item?.menu
|
||||
trayItemRect: root.globalPos
|
||||
bar: root.bar
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: trayMenu
|
||||
function onVisibleChanged() {
|
||||
if ( !trayMenu.visible ) {
|
||||
trayMenu.trayMenu = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if ( mouse.button === Qt.LeftButton ) {
|
||||
root.item.activate();
|
||||
} else if ( mouse.button === Qt.RightButton ) {
|
||||
if ( trayMenu.menu != menuOpener ) {
|
||||
trayMenu.menu = menuOpener;
|
||||
}
|
||||
trayMenu.trayMenu = root.item?.menu;
|
||||
trayMenu.visible = !trayMenu.visible;
|
||||
console.log(root.x);
|
||||
trayMenu.focusGrab = true;
|
||||
}
|
||||
}
|
||||
|
||||
QsMenuOpener {
|
||||
id: menuOpener
|
||||
|
||||
menu: root.item?.menu
|
||||
}
|
||||
}
|
||||
|
||||
+118
-136
@@ -1,24 +1,34 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.DBusMenu
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell.Hyprland
|
||||
import QtQml
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
signal menuActionTriggered()
|
||||
required property QsMenuOpener menu
|
||||
required property QsMenuHandle trayMenu
|
||||
required property point trayItemRect
|
||||
required property PanelWindow bar
|
||||
property var menuStack: []
|
||||
property real scaleValue: 0
|
||||
|
||||
property int height: calcSize("h")
|
||||
property alias focusGrab: grab.active
|
||||
property int entryHeight: 30
|
||||
property int maxWidth: calcSize("w")
|
||||
property int biggestWidth: 0
|
||||
|
||||
QsMenuOpener {
|
||||
id: menuOpener
|
||||
menu: root.trayMenu
|
||||
}
|
||||
|
||||
// onTrayMenuChanged: {
|
||||
// listLayout.forceLayout();
|
||||
// }
|
||||
|
||||
visible: false
|
||||
color: "transparent"
|
||||
@@ -29,61 +39,29 @@ PanelWindow {
|
||||
bottom: true
|
||||
}
|
||||
|
||||
function calcSize(String) {
|
||||
if ( String === "w" ) {
|
||||
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;
|
||||
}
|
||||
if ( String === "h" ) {
|
||||
let count = 0;
|
||||
let separatorCount = 0;
|
||||
for (let i = 0; i < listLayout.count; i++) {
|
||||
if (!listLayout.model.values[i].isSeparator) {
|
||||
count++;
|
||||
} else {
|
||||
separatorCount++;
|
||||
}
|
||||
}
|
||||
if ( root.menuStack.length > 0 ) {
|
||||
backEntry.visible = true;
|
||||
count++;
|
||||
}
|
||||
return (count * entryHeight) + ((count - 1) * 2) + (separatorCount * 3) + 10;
|
||||
}
|
||||
}
|
||||
mask: Region { id: mask; item: menuRect }
|
||||
|
||||
function goBack() {
|
||||
if ( root.menuStack.length > 0 ) {
|
||||
root.menu = root.menuStack.pop();
|
||||
menuChangeAnimation.start();
|
||||
root.biggestWidth = 0;
|
||||
root.trayMenu = root.menuStack.pop();
|
||||
listLayout.positionViewAtBeginning();
|
||||
backEntry.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateMask() {
|
||||
root.mask.changed();
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if ( !visible ) {
|
||||
goBack();
|
||||
} else {
|
||||
if ( visible ) {
|
||||
scaleValue = 0;
|
||||
scaleAnimation.start();
|
||||
}
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: tempMetrics
|
||||
text: ""
|
||||
}
|
||||
|
||||
|
||||
NumberAnimation {
|
||||
id: scaleAnimation
|
||||
target: root
|
||||
@@ -92,90 +70,85 @@ PanelWindow {
|
||||
to: 1
|
||||
duration: 150
|
||||
easing.type: Easing.OutCubic
|
||||
onStopped: {
|
||||
root.updateMask();
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: {
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [ root ]
|
||||
active: false
|
||||
onCleared: {
|
||||
root.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
SequentialAnimation {
|
||||
id: menuChangeAnimation
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
duration: MaterialEasing.standardTime / 2
|
||||
easing.bezierCurve: MaterialEasing.expressiveEffects
|
||||
from: 0
|
||||
property: "x"
|
||||
target: translateAnim
|
||||
to: -listLayout.width / 2
|
||||
}
|
||||
|
||||
PropertyAction {
|
||||
property: "menu"
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
NumberAnimation {
|
||||
duration: MaterialEasing.standardTime / 2
|
||||
easing.bezierCurve: MaterialEasing.expressiveEffects
|
||||
from: listLayout.width / 2
|
||||
property: "x"
|
||||
target: translateAnim
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMenuActionTriggered: {
|
||||
if ( root.menuStack.length > 0 ) {
|
||||
backEntry.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: menuRect
|
||||
x: root.trayItemRect.x - ( menuRect.implicitWidth / 2 ) + 11
|
||||
y: root.trayItemRect.y - 5
|
||||
implicitHeight: root.height
|
||||
implicitWidth: root.maxWidth + 20
|
||||
x: Math.round( root.trayItemRect.x - ( menuRect.implicitWidth / 2 ) + 11 )
|
||||
y: Math.round( root.trayItemRect.y - 5 )
|
||||
implicitWidth: listLayout.contentWidth + 10
|
||||
implicitHeight: listLayout.contentHeight + ( root.menuStack.length > 0 ? root.entryHeight + 10 : 10 )
|
||||
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
|
||||
@@ -185,6 +158,19 @@ PanelWindow {
|
||||
}
|
||||
]
|
||||
|
||||
Behavior on implicitWidth {
|
||||
NumberAnimation {
|
||||
duration: MaterialEasing.standardTime
|
||||
easing.bezierCurve: MaterialEasing.standard
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitHeight {
|
||||
NumberAnimation {
|
||||
duration: MaterialEasing.standardTime
|
||||
easing.bezierCurve: MaterialEasing.standard
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
@@ -201,31 +187,11 @@ PanelWindow {
|
||||
ListView {
|
||||
id: listLayout
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.height - ( root.menuStack.length > 0 ? root.entryHeight + 10 : 0 )
|
||||
Layout.preferredHeight: contentHeight
|
||||
spacing: 2
|
||||
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
|
||||
}
|
||||
}
|
||||
contentWidth: root.biggestWidth
|
||||
contentHeight: contentItem.childrenRect.height
|
||||
model: menuOpener.children
|
||||
|
||||
delegate: Rectangle {
|
||||
id: menuItem
|
||||
@@ -235,7 +201,7 @@ PanelWindow {
|
||||
}
|
||||
property bool containsMouseAndEnabled: mouseArea.containsMouse && menuItem.modelData.enabled
|
||||
property bool containsMouseAndNotEnabled: mouseArea.containsMouse && !menuItem.modelData.enabled
|
||||
width: root.implicitWidth
|
||||
width: widthMetrics.width + (menuItem.modelData.icon ?? "" ? 30 : 0) + (menuItem.modelData.hasChildren ? 30 : 0) + 20
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: menuItem.modelData.isSeparator ? 1 : root.entryHeight
|
||||
@@ -243,6 +209,19 @@ PanelWindow {
|
||||
radius: 4
|
||||
visible: true
|
||||
|
||||
Component.onCompleted: {
|
||||
var biggestWidth = root.biggestWidth;
|
||||
var currentWidth = widthMetrics.width + (menuItem.modelData.icon ?? "" ? 30 : 0) + (menuItem.modelData.hasChildren ? 30 : 0) + 20;
|
||||
if ( currentWidth > biggestWidth ) {
|
||||
root.biggestWidth = currentWidth;
|
||||
}
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: widthMetrics
|
||||
text: menuItem.modelData.text
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
@@ -254,12 +233,15 @@ PanelWindow {
|
||||
if ( !menuItem.modelData.hasChildren ) {
|
||||
if ( menuItem.modelData.enabled ) {
|
||||
menuItem.modelData.triggered();
|
||||
root.menuActionTriggered();
|
||||
root.visible = false;
|
||||
}
|
||||
} else {
|
||||
root.menuStack.push(root.menu);
|
||||
root.menu = menuItem.child;
|
||||
root.menuStack.push(root.trayMenu);
|
||||
menuChangeAnimation.start();
|
||||
root.biggestWidth = 0;
|
||||
root.trayMenu = menuItem.modelData;
|
||||
listLayout.positionViewAtBeginning();
|
||||
root.menuActionTriggered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user