From b58ce5f98271493cd851fdf090ed97e1e031dd5f Mon Sep 17 00:00:00 2001 From: lysec Date: Mon, 13 Oct 2025 15:52:19 +0200 Subject: [PATCH] Notification: better animations NIconPicker: fix width/height Autoformat --- Modules/Notification/Notification.qml | 83 +++++++++++++++++-- .../WidgetSettings/ActiveWindowSettings.qml | 6 +- .../Bar/WidgetSettings/MediaMiniSettings.qml | 6 +- Services/BarWidgetRegistry.qml | 10 ++- Widgets/NIconPicker.qml | 12 +-- 5 files changed, 87 insertions(+), 30 deletions(-) diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml index a8c9bc20..3c97971a 100644 --- a/Modules/Notification/Notification.qml +++ b/Modules/Notification/Notification.qml @@ -159,6 +159,16 @@ Variants { width: 360 visible: true + // Animate when notifications are added/removed + Behavior on implicitHeight { + SpringAnimation { + spring: 2.0 + damping: 0.4 + epsilon: 0.01 + mass: 0.8 + } + } + // Multiple notifications display Repeater { model: notificationModel @@ -232,8 +242,12 @@ Variants { // Animation properties property real scaleValue: 0.8 property real opacityValue: 0.0 + property real slideOffset: 0 property bool isRemoving: false + // Staggered animation delay based on index + readonly property int animationDelay: index * 100 + // Right-click to dismiss MouseArea { anchors.fill: parent @@ -245,14 +259,55 @@ Variants { } } - // Scale and fade-in animation + // Scale, fade, and slide animation scale: scaleValue opacity: opacityValue + // Slide animation based on notification position (vertical only for stacking) + y: slideOffset + + // Calculate slide direction based on notification location + readonly property real slideDistance: 300 + readonly property real slideInOffset: { + // For vertical stacking, always slide from top + if (parent.isTop) + return -slideDistance + if (parent.isBottom) + return slideDistance + return 0 + } + readonly property real slideOutOffset: { + // Slide out in the same direction as slide in + if (parent.isTop) + return -slideDistance + if (parent.isBottom) + return slideDistance + return 0 + } + // Animate in when the item is created Component.onCompleted: { - scaleValue = 1.0 - opacityValue = 1.0 + // Start from slide position + slideOffset = slideInOffset + scaleValue = 0.8 + opacityValue = 0.0 + + // Delay animation based on index for staggered effect + delayTimer.interval = animationDelay + delayTimer.start() + } + + // Timer for staggered animation start + Timer { + id: delayTimer + interval: 0 + repeat: false + onTriggered: { + // Animate to final position + slideOffset = 0 + scaleValue = 1.0 + opacityValue = 1.0 + } } // Animate out when being removed @@ -261,6 +316,7 @@ Variants { return // Prevent multiple animations isRemoving = true + slideOffset = slideOutOffset scaleValue = 0.8 opacityValue = 0.0 } @@ -282,18 +338,29 @@ Variants { } } - // Animation behaviors + // Animation behaviors with spring physics Behavior on scale { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.OutExpo + SpringAnimation { + spring: 3 + damping: 0.4 + epsilon: 0.01 + mass: 0.8 } } Behavior on opacity { NumberAnimation { duration: Style.animationNormal - easing.type: Easing.OutQuad + easing.type: Easing.OutCubic + } + } + + Behavior on y { + SpringAnimation { + spring: 2.5 + damping: 0.3 + epsilon: 0.01 + mass: 0.6 } } diff --git a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml index e6eb8191..643684dd 100644 --- a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml @@ -40,8 +40,7 @@ ColumnLayout { Layout.fillWidth: true label: I18n.tr("bar.widget-settings.active-window.hide-mode.label") description: I18n.tr("bar.widget-settings.active-window.hide-mode.description") - model: [ - { + model: [{ "key": "visible", "name": I18n.tr("options.hide-modes.visible") }, { @@ -50,8 +49,7 @@ ColumnLayout { }, { "key": "transparent", "name": I18n.tr("options.hide-modes.transparent") - } - ] + }] currentKey: root.valueHideMode onSelected: key => root.valueHideMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml index a7580143..1d03c87f 100644 --- a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml @@ -40,8 +40,7 @@ ColumnLayout { Layout.fillWidth: true label: I18n.tr("bar.widget-settings.media-mini.hide-mode.label") description: I18n.tr("bar.widget-settings.media-mini.hide-mode.description") - model: [ - { + model: [{ "key": "visible", "name": I18n.tr("options.hide-modes.visible") }, { @@ -50,8 +49,7 @@ ColumnLayout { }, { "key": "transparent", "name": I18n.tr("options.hide-modes.transparent") - } - ] + }] currentKey: root.valueHideMode onSelected: key => root.valueHideMode = key } diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index 260012ba..1bb0199c 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -41,8 +41,9 @@ Singleton { "ActiveWindow": { "allowUserSettings": true, "showIcon": true, - "hideMode": "hidden", // "visible", "hidden", "transparent" - "scrollingMode": "hover", + "hideMode": "hidden", + "scrollingMode"// "visible", "hidden", "transparent" + : "hover", "width": 145, "colorizeIcons": false }, @@ -84,8 +85,9 @@ Singleton { }, "MediaMini": { "allowUserSettings": true, - "hideMode": "hidden", // "visible", "hidden", "transparent" - "scrollingMode": "hover", + "hideMode": "hidden", + "scrollingMode"// "visible", "hidden", "transparent" + : "hover", "showAlbumArt": false, "showVisualizer": false, "visualizerType": "linear" diff --git a/Widgets/NIconPicker.qml b/Widgets/NIconPicker.qml index 7ae7a8f5..2a4916e9 100644 --- a/Widgets/NIconPicker.qml +++ b/Widgets/NIconPicker.qml @@ -15,16 +15,8 @@ Popup { signal iconSelected(string iconName) - width: { - var w = Math.round(Math.max(screen.width * 0.35, 900)) - w = Math.min(w, screen.width - Style.marginL * 2) - return w - } - height: { - var h = Math.round(Math.max(screen.height * 0.65, 700)) - h = Math.min(h, screen.height - Style.barHeight - Style.marginL * 2) - return h - } + width: 900 * Style.uiScaleRatio + height: 700 * Style.uiScaleRatio anchors.centerIn: Overlay.overlay padding: Style.marginXL