Add animations everywhere

This commit is contained in:
Ly-sec 2025-08-13 15:08:54 +02:00
parent e2a0e491a0
commit bf94ebe46d
11 changed files with 618 additions and 28 deletions

View file

@ -133,13 +133,19 @@ Variants {
const localCenterX = width / 2
const localCenterY = height / 2
const globalPoint = mapToItem(null, localCenterX, localCenterY)
if (sidePanel.isLoaded)
sidePanel.isLoaded = false
else if (sidePanel.openAt)
if (sidePanel.isLoaded) {
// Call hide() instead of directly setting isLoaded to false
if (sidePanel.item && sidePanel.item.hide) {
sidePanel.item.hide()
} else {
sidePanel.isLoaded = false
}
} else if (sidePanel.openAt) {
sidePanel.openAt(globalPoint.x, screen)
else
} else {
// Fallback: toggle if API unavailable
sidePanel.isLoaded = true
}
}
}
}

View file

@ -19,7 +19,17 @@ NIconButton {
notificationHistoryPanelLoader.isLoaded = true
}
if (notificationHistoryPanelLoader.item) {
notificationHistoryPanelLoader.item.visible = !notificationHistoryPanelLoader.item.visible
if (notificationHistoryPanelLoader.item.visible) {
// Panel is visible, hide it with animation
if (notificationHistoryPanelLoader.item.hide) {
notificationHistoryPanelLoader.item.hide()
} else {
notificationHistoryPanelLoader.item.visible = false
}
} else {
// Panel is hidden, show it
notificationHistoryPanelLoader.item.visible = true
}
}
}

View file

@ -15,17 +15,56 @@ NLoader {
NPanel {
id: notificationPanel
// Override hide function to animate first
function hide() {
// Start hide animation
notificationRect.scaleValue = 0.8
notificationRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
Connections {
target: notificationPanel
ignoreUnknownSignals: true
function onDismissed() {
// Start hide animation
notificationRect.scaleValue = 0.8
notificationRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && notificationRect.opacityValue > 0) {
// Start hide animation
notificationRect.scaleValue = 0.8
notificationRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
notificationPanel.visible = false
notificationPanel.dismissed()
}
}
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
Rectangle {
id: notificationRect
color: Colors.backgroundSecondary
radius: Style.radiusMedium * scaling
border.color: Colors.backgroundTertiary
@ -37,6 +76,36 @@ NLoader {
anchors.topMargin: Style.marginTiny * scaling
anchors.rightMargin: Style.marginTiny * scaling
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Style.marginLarge * scaling
@ -72,7 +141,7 @@ NLoader {
icon: "close"
sizeMultiplier: 0.8
onClicked: {
notificationPanel.visible = false
notificationPanel.hide()
}
}
}

View file

@ -122,16 +122,91 @@ Item {
NPanel {
id: trayPanel
showOverlay: false // no colors overlay even if activated in settings
// Override hide function to animate first
function hide() {
// Start hide animation
trayMenuRect.scaleValue = 0.8
trayMenuRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
Connections {
target: trayPanel
ignoreUnknownSignals: true
function onDismissed() {
function onDismissed() {
// Start hide animation
trayMenuRect.scaleValue = 0.8
trayMenuRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && trayMenuRect.opacityValue > 0) {
// Start hide animation
trayMenuRect.scaleValue = 0.8
trayMenuRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
trayPanel.visible = false
trayMenu.hideMenu()
}
}
TrayMenu {
id: trayMenu
Rectangle {
id: trayMenuRect
color: "transparent"
anchors.fill: parent
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
TrayMenu {
id: trayMenu
}
}
}
}

View file

@ -29,11 +29,18 @@ NIconButton {
wifiMenuLoader.isLoaded = true
}
if (wifiMenuLoader.item) {
wifiMenuLoader.item.visible = !wifiMenuLoader.item.visible
if (wifiMenuLoader.item.visible) {
network.onMenuOpened()
// Panel is visible, hide it with animation
if (wifiMenuLoader.item.hide) {
wifiMenuLoader.item.hide()
} else {
wifiMenuLoader.item.visible = false
network.onMenuClosed()
}
} else {
network.onMenuClosed()
// Panel is hidden, show it
wifiMenuLoader.item.visible = true
network.onMenuOpened()
}
}
}

View file

@ -18,11 +18,47 @@ NLoader {
property string passwordInput: ""
property bool showPasswordPrompt: false
function hide() {
wifiMenuRect.scaleValue = 0.8
wifiMenuRect.opacityValue = 0.0
hideTimer.start()
}
// Connect to NPanel's dismissed signal to handle external close events
Connections {
target: wifiPanel
ignoreUnknownSignals: true
function onDismissed() {
// Start hide animation
wifiMenuRect.scaleValue = 0.8
wifiMenuRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && wifiMenuRect.opacityValue > 0) {
// Start hide animation
wifiMenuRect.scaleValue = 0.8
wifiMenuRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
wifiPanel.visible = false
wifiPanel.dismissed()
network.onMenuClosed()
}
}
@ -30,6 +66,7 @@ NLoader {
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
Rectangle {
id: wifiMenuRect
color: Colors.backgroundSecondary
radius: Style.radiusMedium * scaling
border.color: Colors.backgroundTertiary
@ -41,6 +78,34 @@ NLoader {
anchors.topMargin: Style.marginTiny * scaling
anchors.rightMargin: Style.marginTiny * scaling
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Style.marginLarge * scaling
@ -87,8 +152,7 @@ NLoader {
icon: "close"
sizeMultiplier: 0.8
onClicked: {
wifiPanel.visible = false
network.onMenuClosed()
wifiPanel.hide()
}
}
}

View file

@ -15,7 +15,54 @@ NLoader {
readonly property real scaling: Scaling.scale(screen)
// Override hide function to animate first
function hide() {
// Start hide animation
calendarRect.scaleValue = 0.8
calendarRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
// Connect to NPanel's dismissed signal to handle external close events
Connections {
target: calendarPanel
function onDismissed() {
// Start hide animation
calendarRect.scaleValue = 0.8
calendarRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && calendarRect.opacityValue > 0) {
// Start hide animation
calendarRect.scaleValue = 0.8
calendarRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
calendarPanel.visible = false
calendarPanel.dismissed()
}
}
Rectangle {
id: calendarRect
color: Colors.backgroundSecondary
radius: Style.radiusMedium * scaling
border.color: Colors.backgroundTertiary
@ -27,11 +74,41 @@ NLoader {
anchors.topMargin: Style.marginTiny * scaling
anchors.rightMargin: Style.marginTiny * scaling
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Prevent closing when clicking in the panel bg
MouseArea {
anchors.fill: parent
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
// Main Column
ColumnLayout {
anchors.fill: parent

View file

@ -15,9 +15,54 @@ NLoader {
readonly property real scaling: Scaling.scale(screen)
// Override hide function to animate first
function hide() {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
// Connect to NPanel's dismissed signal to handle external close events
Connections {
target: demoPanel
function onDismissed() {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && bgRect.opacityValue > 0) {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
demoPanel.visible = false
demoPanel.dismissed()
}
}
// Ensure panel shows itself once created
Component.onCompleted: {
console.log("[DemoPanel] Component completed, showing panel")
show()
}
@ -31,11 +76,41 @@ NLoader {
height: 700 * scaling
anchors.centerIn: parent
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Prevent closing when clicking in the panel bg
MouseArea {
anchors.fill: parent
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: Style.marginXL * scaling

View file

@ -16,6 +16,40 @@ NLoader {
readonly property real scaling: Scaling.scale(screen)
// Override hide function to animate first
function hide() {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
// Connect to NPanel's dismissed signal to handle external close events
Connections {
target: panel
function onDismissed() {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
panel.visible = false
panel.dismissed()
}
}
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
property int currentTabIndex: 0
@ -65,9 +99,18 @@ NLoader {
"source": "Tabs/About.qml"
}]
// Combined visibility change handler
onVisibleChanged: {
if (visible)
if (visible) {
currentTabIndex = 0
} else if (bgRect.opacityValue > 0) {
// Start hide animation
bgRect.scaleValue = 0.8
bgRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
Component.onCompleted: show()
@ -83,10 +126,40 @@ NLoader {
height: (screen.height * 0.5) * scaling
anchors.centerIn: parent
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
MouseArea {
anchors.fill: parent
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
RowLayout {
anchors.fill: parent
anchors.margins: Style.marginLarge * scaling
@ -196,7 +269,7 @@ NLoader {
tooltipText: "Close"
Layout.alignment: Qt.AlignVCenter
onClicked: {
settingsPanel.isLoaded = !settingsPanel.isLoaded
panel.hide()
}
}
}

View file

@ -41,6 +41,41 @@ NLoader {
// Ensure this panel attaches to the intended screen
screen: root.targetScreen
// Override hide function to animate first
function hide() {
// Start hide animation
panelBackground.scaleValue = 0.8
panelBackground.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
// Connect to NPanel's dismissed signal to handle external close events
Connections {
target: sidePanel
function onDismissed() {
// Start hide animation
panelBackground.scaleValue = 0.8
panelBackground.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Also handle visibility changes from external sources
onVisibleChanged: {
if (!visible && panelBackground.opacityValue > 0) {
// Start hide animation
panelBackground.scaleValue = 0.8
panelBackground.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
}
// Ensure panel shows itself once created
Component.onCompleted: show()
@ -62,11 +97,54 @@ NLoader {
x: Math.max(Style.marginSmall * scaling, Math.min(parent.width - width - Style.marginSmall * scaling,
Math.round(anchorX - width / 2)))
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
scale: scaleValue
opacity: opacityValue
// Animate in when component is completed
Component.onCompleted: {
scaleValue = 1.0
opacityValue = 1.0
}
// Timer to hide panel after animation
Timer {
id: hideTimer
interval: Style.animationSlow
repeat: false
onTriggered: {
sidePanel.visible = false
sidePanel.dismissed()
}
}
// Prevent closing when clicking in the panel bg
MouseArea {
anchors.fill: parent
}
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationSlow
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
// Content wrapper to ensure childrenRect drives implicit height
Item {
id: content

View file

@ -55,11 +55,23 @@ Window {
x = pos.x - width / 2 + target.width / 2
y = pos.y + 12 // 12 px margin below
}
// Start with animation values
tooltipRect.scaleValue = 0.8
tooltipRect.opacityValue = 0.0
visible = true
// Use a timer to trigger the animation after the component is visible
showTimer.start()
}
function _hideNow() {
visible = false
// Start hide animation
tooltipRect.scaleValue = 0.8
tooltipRect.opacityValue = 0.0
// Hide after animation completes
hideTimer.start()
}
Connections {
@ -97,7 +109,30 @@ Window {
}
}
// Timer to hide tooltip after animation
Timer {
id: hideTimer
interval: Style.animationNormal
repeat: false
onTriggered: {
visible = false
}
}
// Timer to trigger show animation
Timer {
id: showTimer
interval: 10 // Very short delay to ensure component is visible
repeat: false
onTriggered: {
// Animate to final values
tooltipRect.scaleValue = 1.0
tooltipRect.opacityValue = 1.0
}
}
Rectangle {
id: tooltipRect
anchors.fill: parent
radius: Style.radiusMedium * scaling
gradient: Gradient {
@ -113,16 +148,37 @@ Window {
border.color: Colors.outline
border.width: Math.max(1, Style.borderThin * scaling)
z: 1
}
NText {
id: tooltipText
anchors.centerIn: parent
text: root.text
font.pointSize: Style.fontSizeMedium * scaling
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
z: 1
// Animation properties
property real scaleValue: 1.0
property real opacityValue: 1.0
scale: scaleValue
opacity: opacityValue
// Animation behaviors
Behavior on scale {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutExpo
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.OutQuad
}
}
NText {
id: tooltipText
anchors.centerIn: parent
text: root.text
font.pointSize: Style.fontSizeMedium * scaling
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
}