polish: add fade-out exit animation to ConsoleGameDetail

Add startClose() which plays a 160ms InCubic fade-out before emitting close(). Back/Escape triggers now call startClose() instead of close() directly. visible keeps the item rendered during the exit animation via isClosing flag. Launch path bypasses animation (immediate).
This commit is contained in:
Marco Allegretti 2026-03-23 11:58:42 +01:00
parent 5e88cc4f41
commit a74f2a0211

View file

@ -19,15 +19,24 @@ Item {
signal editRequested() signal editRequested()
signal removeRequested() signal removeRequested()
visible: game !== null property bool isClosing: false
visible: game !== null || isClosing
focus: visible focus: visible
Keys.onEscapePressed: detailRoot.close() function startClose() {
if (isClosing) return
isClosing = true
fadeIn.stop()
fadeOut.start()
}
Keys.onEscapePressed: detailRoot.startClose()
Connections { Connections {
target: GamepadManager target: GamepadManager
function onBackPressed() { function onBackPressed() {
if (detailRoot.visible) detailRoot.close() if (detailRoot.visible) detailRoot.startClose()
} }
function onSelectPressed() { function onSelectPressed() {
if (detailRoot.visible) detailRoot.launch() if (detailRoot.visible) detailRoot.launch()
@ -364,16 +373,32 @@ Item {
} }
} }
NumberAnimation on opacity { NumberAnimation {
id: fadeIn id: fadeIn
running: detailRoot.visible target: detailRoot
property: "opacity"
from: 0; to: 1 from: 0; to: 1
duration: 220 duration: 220
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
NumberAnimation {
id: fadeOut
target: detailRoot
property: "opacity"
from: 1; to: 0
duration: 160
easing.type: Easing.InCubic
onStopped: {
detailRoot.isClosing = false
detailRoot.close()
}
}
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible && !isClosing) {
detailRoot.opacity = 0
fadeIn.start()
Qt.callLater(function() { playBtn.forceActiveFocus() }) Qt.callLater(function() { playBtn.forceActiveFocus() })
} }
} }