even more deltarune

This commit is contained in:
2026-03-24 20:27:19 +02:00
parent 64797aedd4
commit 1deeda7f1a
6 changed files with 327 additions and 26 deletions

236
Startup/shell.qml Normal file
View File

@@ -0,0 +1,236 @@
import Quickshell
import Quickshell.Bluetooth
import Quickshell.Wayland
import Quickshell.Hyprland
import QtQuick
import QtMultimedia
PanelWindow {
id: overlay
anchors {
top: true
left: true
right: true
bottom: true
}
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.focusable: true
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
WlrLayershell.namespace: "deltarune-startup-overlay"
color: "#000000"
exclusionMode: ExclusionMode.Ignore
aboveWindows: true
focusable: true
property string bluetoothTargetName: "JBL Tune 525BT"
property int bluetoothTimeoutMs: 5000
property bool waitingForBluetooth: true
property bool animationLaunchScheduled: false
property bool animationStarted: false
function bluetoothModelCount() {
if (!Bluetooth.devices)
return 0;
if (typeof Bluetooth.devices.count === "function")
return Bluetooth.devices.count();
if (Bluetooth.devices.count !== undefined)
return Bluetooth.devices.count;
if (Bluetooth.devices.length !== undefined)
return Bluetooth.devices.length;
return 0;
}
function bluetoothModelGet(index) {
if (!Bluetooth.devices || index < 0 || index >= bluetoothModelCount())
return null;
if (Bluetooth.devices.get)
return Bluetooth.devices.get(index);
if (Bluetooth.devices.length !== undefined)
return Bluetooth.devices[index];
return null;
}
function bluetoothDeviceName(device) {
if (!device)
return "";
if (device.name && device.name.length > 0)
return String(device.name);
if (device.deviceName && device.deviceName.length > 0)
return String(device.deviceName);
return "";
}
function findTargetBluetoothDevice() {
for (var i = 0; i < bluetoothModelCount(); i++) {
var device = bluetoothModelGet(i);
if (bluetoothDeviceName(device) === bluetoothTargetName)
return device;
}
return null;
}
function beginAnimation() {
if (animationStarted || animationLaunchScheduled)
return;
waitingForBluetooth = false;
bluetoothRetryTimer.stop();
bluetoothTimeoutTimer.stop();
animationLaunchScheduled = true;
startupDelayTimer.restart();
}
function handlePrimaryAction() {
if (!animationStarted)
beginAnimation();
else
finishStartup();
}
function finishStartup() {
if (player.playbackState !== MediaPlayer.StoppedState)
player.stop();
else
Qt.quit();
}
HyprlandFocusGrab {
active: true
windows: [overlay]
}
FocusScope {
id: overlayFocus
anchors.fill: parent
focus: true
Component.onCompleted: overlayFocus.forceActiveFocus()
onVisibleChanged: if (visible)
overlayFocus.forceActiveFocus()
onFocusChanged: if (focus)
overlayFocus.forceActiveFocus()
Keys.onReleased: function (event) {
switch (event.key) {
case Qt.Key_Z:
case Qt.Key_Return:
case Qt.Key_Enter:
event.accepted = true;
overlay.handlePrimaryAction();
return;
}
}
}
Connections {
target: Bluetooth.devices
ignoreUnknownSignals: true
function onCountChanged() {
if (overlay.waitingForBluetooth)
bluetoothRetryTimer.restart();
}
function onModelReset() {
if (overlay.waitingForBluetooth)
bluetoothRetryTimer.restart();
}
function onRowsInserted() {
if (overlay.waitingForBluetooth)
bluetoothRetryTimer.restart();
}
}
MediaPlayer {
id: player
source: "deltarune.webm" // Local file or URL
autoPlay: false
videoOutput: videoOutput
playbackRate: 1
audioOutput: AudioOutput {}
onPlaybackStateChanged: a => {
if (player.playbackState === MediaPlayer.StoppedState)
overlay.finishStartup();
}
}
Timer {
id: startupDelayTimer
interval: 1000
repeat: false
onTriggered: {
overlay.animationLaunchScheduled = false;
overlay.animationStarted = true;
player.play();
}
}
Timer {
id: bluetoothRetryTimer
interval: 250
running: true
repeat: true
onTriggered: {
if (!overlay.waitingForBluetooth) {
stop();
return;
}
const device = overlay.findTargetBluetoothDevice();
if (!device)
return;
if (device.connected) {
overlay.beginAnimation();
return;
}
device.connect();
}
}
Timer {
id: bluetoothTimeoutTimer
interval: overlay.bluetoothTimeoutMs
running: true
repeat: false
onTriggered: overlay.beginAnimation()
}
VideoOutput {
id: videoOutput
anchors.fill: parent
}
Text {
visible: overlay.waitingForBluetooth
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "#ffffff"
font.family: "Determination Mono"
font.pixelSize: 28
text: "CONNECTING TO " + overlay.bluetoothTargetName.toUpperCase()
z: 1
}
Text {
visible: !overlay.animationStarted
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 56
color: "#ffffff"
font.family: "Determination Mono"
font.pixelSize: 28
text: overlay.waitingForBluetooth ? "PRESS Z OR ENTER TO SKIP WAIT" : "STARTING..."
z: 1
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
cursorShape: Qt.BlankCursor
}
}