**animations** #5

Merged
Zacharias-Brohn merged 2 commits from ListView-NC-testing into main 2025-11-17 15:03:39 +01:00
6 changed files with 275 additions and 219 deletions
Showing only changes of commit d8199f792a - Show all commits
+4
View File
@@ -17,6 +17,10 @@ Scope {
screen: modelData
property var root: Quickshell.shellDir
NotificationCenter {
bar: bar
}
Process {
id: ncProcess
command: ["sh", "-c", `qs -p ${bar.root}/shell.qml ipc call root showCenter`]
-7
View File
@@ -237,13 +237,6 @@ Singleton {
}
}
Component {
id: notificationPopup
TrackedNotification {
centerX: NotificationCenter.posX
}
}
Component {
id: notifComp
+16
View File
@@ -0,0 +1,16 @@
pragma Singleton
import Quickshell
import Quickshell.Io
Singleton {
id: root
property alias centerX: notifCenterSpacing.centerX
JsonAdapter {
id: notifCenterSpacing
property int centerX
}
}
+92 -86
View File
@@ -2,6 +2,7 @@ import Quickshell
import Quickshell.Hyprland
import Quickshell.Widgets
import Quickshell.Io
import Quickshell.Wayland
import QtQuick.Layouts
import QtQuick.Controls.FluentWinUI3
import QtQuick.Effects
@@ -20,9 +21,11 @@ PanelWindow {
left: true
bottom: true
}
WlrLayershell.layer: WlrLayer.Overlay
required property PanelWindow bar
property bool centerShown: false
property alias posX: backgroundRect.x
property alias doNotDisturb: dndSwitch.checked
visible: false
mask: Region { item: backgroundRect }
@@ -61,10 +64,10 @@ PanelWindow {
id: showAnimation
target: backgroundRect
property: "x"
from: Screen.width
to: Screen.width - backgroundRect.implicitWidth - 10
duration: 300
easing.type: Easing.OutCubic
to: root.bar.screen.width - backgroundRect.implicitWidth - 10
from: root.bar.screen.width
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
onStopped: {
focusGrab.active = true;
}
@@ -74,10 +77,10 @@ PanelWindow {
id: closeAnimation
target: backgroundRect
property: "x"
from: Screen.width - backgroundRect.implicitWidth - 10
to: Screen.width
duration: 300
easing.type: Easing.OutCubic
from: root.bar.screen.width - backgroundRect.implicitWidth - 10
to: root.bar.screen.width
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
HyprlandFocusGrab {
@@ -89,10 +92,16 @@ PanelWindow {
}
}
TrackedNotification {
centerShown: root.centerShown
bar: root.bar
}
Rectangle {
id: backgroundRect
y: 10
x: Screen.width
z: 1
implicitWidth: 400
implicitHeight: root.height - 20
color: Config.baseBgColor
@@ -114,6 +123,9 @@ PanelWindow {
focus: false
activeFocusOnTab: false
focusPolicy: Qt.NoFocus
onCheckedChanged: {
NotifServer.dnd = dndSwitch.checked;
}
}
RowLayout {
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
@@ -176,7 +188,7 @@ PanelWindow {
move: Transition {
NumberAnimation {
properties: "y,x";
properties: "x";
duration: 200;
easing.type: Easing.OutCubic
}
@@ -215,31 +227,45 @@ PanelWindow {
Anim {}
}
// add: Transition {
// id: addTrans
// SequentialAnimation {
// PauseAnimation {
// duration: ( addTrans.ViewTransition.index - addTrans.ViewTransition.targetIndexes[ 0 ]) * 50
// }
// ParallelAnimation {
// NumberAnimation {
// properties: "y";
// from: addTrans.ViewTransition.destination.y - (height / 2);
// to: addTrans.ViewTransition.destination.y;
// duration: 100;
// easing.type: Easing.OutCubic
// }
// NumberAnimation {
// properties: "opacity";
// from: 0;
// to: 1;
// duration: 100;
// easing.type: Easing.OutCubic
// }
// }
// }
// }
//
Behavior on y {
Anim {
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
add: Transition {
id: addTrans
SequentialAnimation {
PauseAnimation {
duration: ( addTrans.ViewTransition.index - addTrans.ViewTransition.targetIndexes[ 0 ]) * 50
}
ParallelAnimation {
NumberAnimation {
properties: "y";
from: addTrans.ViewTransition.destination.y - (height / 2);
to: addTrans.ViewTransition.destination.y;
duration: 100;
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "opacity";
from: 0;
to: 1;
duration: 100;
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "scale";
from: 0.7;
to: 1.0;
duration: 100
easing.type: Easing.InOutQuad
}
}
}
}
move: Transition {
id: moveTrans
NumberAnimation {
@@ -281,79 +307,35 @@ PanelWindow {
anchors.fill: parent
hoverEnabled: true
onClicked: {
groupColumn.isExpanded = false;
groupColumn.shouldShow = false;
}
}
}
}
ListView {
Repeater {
id: groupListView
model: ScriptModel {
id: groupModel
values: groupColumn.isExpanded ? groupColumn.notifications : groupColumn.notifications.slice( 0, 1 )
}
width: parent.width
spacing: 10
height: contentHeight
contentHeight: childrenRect.height
clip: false
pixelAligned: true
boundsBehavior: Flickable.StopAtBounds
displayMarginBeginning: 0
displayMarginEnd: 5000
Behavior on height {
Anim {
duration: 20;
}
}
add: Transition {
id: add
NumberAnimation {
properties: "y,opacity";
duration: 100 * ( add.ViewTransition.targetIndexes.length / ( add.ViewTransition.targetIndexes.length < 3 ? 1 : 3 ));
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
}
}
remove: Transition {
NumberAnimation {
properties: "opacity";
from: 1;
to: 0;
duration: 300;
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
}
}
displaced: Transition {
NumberAnimation {
properties: "y";
duration: 200;
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
}
}
delegate: Rectangle {
Rectangle {
id: groupHeader
required property int index
required property NotifServer.Notif modelData
property alias notifHeight: groupHeader.height
property bool previewHidden: !groupColumn.isExpanded && index > 0
property bool previewHidden: groupColumn.shouldShow && index > 0
width: groupListView.width
width: parent.width
height: contentColumn.height + 20
color: Config.baseBgColor
border.color: "#555555"
border.width: 1
radius: 8
opacity: 1
scale: 1.0
opacity: previewHidden ? 0 : 1.0
scale: previewHidden ? 0.7 : 1.0
Component.onCompleted: modelData.lock(this);
Component.onDestruction: modelData.unlock(this);
@@ -366,11 +348,35 @@ PanelWindow {
groupHeader.modelData.actions[0].invoke();
}
} else {
groupColumn.shouldShow = true;
groupColumn.isExpanded = true;
}
}
}
ParallelAnimation {
id: collapseAnim
running: !groupColumn.shouldShow && index > 0
Anim {
target: groupHeader
property: "opacity"
duration: 100
from: 1
to: index > 0 ? 0 : 1.0
}
Anim {
target: groupHeader
property: "scale"
duration: 100
from: 1
to: index > 0 ? 0.7 : 1.0
}
onFinished: {
groupColumn.isExpanded = false;
}
}
ParallelAnimation {
running: groupHeader.modelData.closed
onFinished: groupHeader.modelData.unlock(groupHeader)
+80 -43
View File
@@ -1,85 +1,122 @@
import Quickshell
import Quickshell.Widgets
import Quickshell.Wayland
import Quickshell.Hyprland
import QtQuick.Layouts
import QtQuick
import Quickshell.Services.Notifications
import qs.Config
import qs.Daemons
import qs.Helpers
PanelWindow {
id: root
color: "transparent"
screen: root.bar.screen
anchors {
top: true
right: true
left: true
bottom: true
}
mask: Region { item: backgroundRect }
mask: Region { regions: root.notifRegions }
exclusionMode: ExclusionMode.Ignore
WlrLayershell.layer: WlrLayer.Overlay
required property Notification notif
required property int centerX
required property list<int> notifIndex
property int index: notifIndex.indexOf(notif.id)
property alias y: backgroundRect.y
property alias notifHeight: backgroundRect.implicitHeight
signal notifDestroy()
property list<Region> notifRegions: []
required property bool centerShown
required property PanelWindow bar
visible: Hyprland.monitorFor(screen).focused
Component.onCompleted: {
openAnim.start();
console.log(root.index);
console.log(NotifServer.list.filter( n => n.popup ).length + " notification popups loaded.");
}
Timer {
id: timeout
interval: 5000
onTriggered: {
closeAnim.start();
ListView {
id: notifListView
model: ScriptModel {
values: NotifServer.list.filter( n => n.popup )
}
anchors.top: parent.top
anchors.bottom: parent.bottom
x: root.centerShown ? root.bar.width - width - 420 : root.bar.width - width - 20
z: 0
anchors.topMargin: 54
width: 400
spacing: 10
Behavior on x {
NumberAnimation {
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
displaced: Transition {
NumberAnimation {
property: "y"
duration: 100
easing.type: Easing.InOutQuad
}
}
remove: Transition {
id: hideTransition
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 1
to: 0
duration: 200
easing.type: Easing.InOutQuad
}
NumberAnimation {
id: openAnim
target: backgroundRect
property: "x"
from: root.centerX
to: root.centerX - backgroundRect.implicitWidth - 20
to: hideTransition.ViewTransition.destination.x + 200
duration: 200
easing.type: Easing.InOutQuad
}
}
}
add: Transition {
id: showTransition
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 0
to: 1
duration: 200
easing.type: Easing.InOutQuad
onStopped: { timeout.start(); }
}
NumberAnimation {
id: closeAnim
target: backgroundRect
property: "x"
from: root.centerX - backgroundRect.implicitWidth - 20
to: root.centerX
from: showTransition.ViewTransition.destination.x + 200
to: showTransition.ViewTransition.destination.x
duration: 200
easing.type: Easing.InOutQuad
onStopped: {
root.destroy();
root.notifDestroy();
}
}
}
Rectangle {
component NotifRegion: Region { }
Component {
id: notifRegion
NotifRegion {}
}
delegate: Rectangle {
id: backgroundRect
required property NotifServer.Notif modelData
implicitWidth: 400
implicitHeight: contentLayout.childrenRect.height + 16
x: root.centerX - implicitWidth - 20
y: !root.notifList[ root.index - 1 ] ? 34 + 20 : root.notifList[ root.index - 1 ].y + root.notifList[ root.index - 1 ].notifHeight + 10
color: Config.baseBgColor
border.color: "#555555"
radius: 8
Behavior on y {
NumberAnimation {
duration: 200
easing.type: Easing.InOutQuad
}
Component.onCompleted: {
root.notifRegions.push( notifRegion.createObject(root, { item: backgroundRect }));
}
Column {
@@ -92,11 +129,11 @@ PanelWindow {
RowLayout {
spacing: 12
IconImage {
source: root.notif.image
source: backgroundRect.modelData.image
Layout.preferredWidth: 48
Layout.preferredHeight: 48
Layout.alignment: Qt.AlignHCenter | Qt.AlignLeft
visible: root.notif.image !== ""
visible: backgroundRect.modelData.image !== ""
}
ColumnLayout {
@@ -106,7 +143,7 @@ PanelWindow {
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Text {
text: root.notif.appName
text: backgroundRect.modelData.appName
color: "white"
font.bold: true
font.pointSize: 14
@@ -116,7 +153,7 @@ PanelWindow {
}
Text {
text: root.notif.summary
text: backgroundRect.modelData.summary
color: "white"
font.pointSize: 12
font.bold: true
@@ -128,7 +165,7 @@ PanelWindow {
}
}
Text {
text: root.notif.body
text: backgroundRect.modelData.body
color: "#dddddd"
font.pointSize: 14
elide: Text.ElideRight
@@ -160,8 +197,8 @@ PanelWindow {
anchors.fill: parent
hoverEnabled: true
onClicked: {
root.notif.dismiss();
root.visible = false;
backgroundRect.modelData.close();
}
}
}
}
+1 -1
View File
@@ -6,6 +6,6 @@ import qs.Modules
Scope {
Bar {}
Wallpaper {}
NotificationCenter {}
// NotificationCenter {}
Launcher {}
}