import QtQuick 2.12 // Boot splash: plays resources/splash/splash.gif once over the UI, then fades // into it. Also hides button icons popping in while they load. // GIF on purpose: AnimatedImage needs only QtGui's gif plugin, while mp4 would // pull in QtMultimedia + gstreamer. The GIF starts and ends on black. // // The root is a plain black cover that exists from the very first frame, so // the UI never flashes before the GIF starts. It goes away only after the // GIF has finished (or right away, with a fade, if the splash is disabled). // Config: splash.enabled (read once at startup). Rectangle { id: splash anchors.fill: parent color: "black" readonly property bool active: visible function finish() { if (!visible || fadeOut.running) return fadeOut.start() } // Swallow touches until the UI is visible. The recovery gesture works // anyway: it listens at window level in C++. MouseArea { anchors.fill: parent } Loader { id: loader anchors.fill: parent active: settingsContainer.splashEnabled sourceComponent: AnimatedImage { // Square GIF: cover the screen and crop its thin grey frame. width: Math.max(splash.width, splash.height) * 1.02 height: width x: (splash.width - width) / 2 y: (splash.height - height) / 2 fillMode: Image.PreserveAspectFit source: "qrc:/splash/splash.gif" asynchronous: false cache: false smooth: true playing: true onStatusChanged: { if (status === Image.Error) { console.warn("Splash: cannot load gif, skipping") splash.finish() } } onCurrentFrameChanged: { if (frameCount > 1 && currentFrame === frameCount - 1) { playing = false splash.finish() } } } } // Splash disabled: keep the cover a moment so icons can load, then fade. Timer { interval: 600 running: !loader.active onTriggered: splash.finish() } // Safety net: never keep the UI hidden if the gif stalls. Timer { interval: 10000 running: true onTriggered: splash.finish() } NumberAnimation { id: fadeOut target: splash property: "opacity" to: 0 duration: 450 easing.type: Easing.InOutQuad onStopped: { splash.visible = false loader.active = false // frees the decoder and textures } } }