Files
darklithium 8f9dc7f1a6 feat: dynamische Cookie-Bilder je nach Liste
- Füge listenspezifische PNGs hinzu (famous quotes, farmer wisdom, UNfortune, idioms, sandman, unicorn, vegan recipes)
- Implementiere dynamische Bildauswahl basierend auf currentFortuneListName
- Cookie-Bild aktualisiert sich sofort beim Start und Listenwechsel
- Bereinige Cookie-Icon-Größen für einheitliches Aussehen (34x30 / 30x26 GU)
- Entferne Spruchanzahl in Klammern aus Listenbeschreibungen
- Füge Switch für Cookie-Knacksgeräusch (cookieCrackEnabled) in Einstellungen hinzu
- Optimierte updateCookieImage()-Funktion mit expliziten Aufrufen bei allen Zustandsänderungen

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-06 02:37:27 +02:00

406 lines
16 KiB
QML

import QtQuick 2.7
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtMultimedia 5.0
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import io.thp.pyotherside 1.4
MainView {
id: root
applicationName: "fortunecookie.darklithium"
width: units.gu(45)
height: units.gu(75)
theme.name: "Lomiri.Components.Themes.SuruDark"
// ====================================================================
// PROPERTIES
// ====================================================================
property bool fortuneOpened: false
property string currentFortune: ""
property bool musicPlaying: false
property bool cookieCrackEnabled: true
property bool appInitialized: false
property string currentFortuneListDescription: ""
property string currentFortuneListName: ""
function updateCookieImage() {
var listName = currentFortuneListName || "fortune";
var availableLists = ["farmer wisdom", "UNfortune", "sandman", "famous quotes", "idioms", "vegan recipes", "unicorn"];
if (availableLists.indexOf(listName) !== -1) {
var encodedName = listName.replace(/ /g, "%20");
cookieImage.source = Qt.resolvedUrl("../assets/" + encodedName + (fortuneOpened ? "_open.png" : "_close.png"));
} else {
cookieImage.source = fortuneOpened ? Qt.resolvedUrl("../assets/cookie_open2.png") : Qt.resolvedUrl("../assets/cookie_closed2.png");
}
}
// Entfernt Spruchanzahl in Klammern aus Beschreibung (z.B. "Text (15)" → "Text")
function cleanDescription(text) {
return text.replace(/\s*\(\d+\)$/, "");
}
Python {
id: py
Component.onCompleted: {
addImportPath(Qt.resolvedUrl("../src"));
importModule("fortunecookie", function() {
console.log("Python-Modul fortunecookie geladen");
});
}
}
// Funktionen
function reloadFortune() {
py.call("fortunecookie.get_new_fortune", [], function(result) {
currentFortune = result;
currentFortuneLabel.text = currentFortune;
if (fortuneOpened) {
currentFortuneLabel.visible = true;
}
});
}
MediaPlayer {
id: mediaPlayer
objectName: "mediaPlayer"
source: Qt.resolvedUrl("../assets/chinese_music.mp3")
loops: MediaPlayer.Infinite
volume: 1.0
}
MediaPlayer {
id: crackMediaPlayer
objectName: "crackMediaPlayer"
source: Qt.resolvedUrl("../assets/cookie_crack.mp3")
volume: 1.0
}
// ====================================================================
// STACK LAYOUT FÜR NAVIGATION
// ====================================================================
StackLayout {
id: mainStack
anchors.fill: parent
currentIndex: 0
// ================================================================
// SEITE 0: HAUPTSPIELBILDSCHIRM
// ================================================================
Page {
id: mainPage
objectName: "mainPage"
header: PageHeader {
title: "Fortune Cookie"
trailingActionBar.actions: [
Action {
iconName: "settings"
text: "Einstellungen"
onTriggered: {
mainStack.currentIndex = 1;
}
}
]
}
Component.onCompleted: {
// Verzögerte Initialisierung
Qt.callLater(function() {
try {
// Initialisierung mit async Aufrufen
py.call("fortunecookie.get_initial_fortune", [], function(result) {
currentFortune = result;
currentFortuneLabel.text = currentFortune;
});
// Musik-Status laden
py.call("fortunecookie.get_music_enabled", [], function(result) {
musicPlaying = result;
if (musicPlaying) {
mediaPlayer.play();
}
});
// Cookie-Crack-Sound-Status laden (lokal gespeichert)
py.call("fortunecookie.get_cookie_crack_enabled", [], function(result) {
root.cookieCrackEnabled = (result !== false && result !== undefined); // Default: true
});
// Aktuelle Liste laden und Beschreibung setzen
py.call("fortunecookie.get_current_fortune_list", [], function(listName) {
root.currentFortuneListName = listName;
Qt.callLater(function() { updateCookieImage(); });
var descriptions = {
"fortune": "klassische Glückskeks-Sprüche",
"farmer wisdom": "Bauernweisheiten",
"UNfortune": "Wednesday-Style",
"sandman": "Sandmännchen",
"famous quotes": "Berühmte Zitate",
"idioms": "Redensarten aus aller Welt",
"vegan recipes": "Vegane Rezeptideen",
"unicorn": "Einhorn Glückssprüche (die fast schon wehtun)"
};
root.currentFortuneListDescription = cleanDescription(descriptions[listName] || listName);
});
appInitialized = true;
} catch (e) {
console.log("ERROR QML: Initialisierung fehlgeschlagen: " + e);
}
});
}
Image {
id: cookieImage
anchors.centerIn: parent
width: fortuneOpened ? units.gu(34) : units.gu(30)
height: fortuneOpened ? units.gu(30) : units.gu(26)
source: ""
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
property real startY: 0
onPressed: startY = mouseY
onReleased: {
if (mouseY < startY - units.gu(2)) {
py.call("fortunecookie.open_fortune", [], function() {
if (cookieCrackEnabled) crackMediaPlayer.play();
fortuneOpened = true;
updateCookieImage();
py.call("fortunecookie.get_current_fortune", [], function(result) {
currentFortune = result;
currentFortuneLabel.text = currentFortune;
currentFortuneLabel.visible = true;
});
});
}
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (!fortuneOpened) {
py.call("fortunecookie.open_fortune", [], function() {
if (cookieCrackEnabled) crackMediaPlayer.play();
fortuneOpened = true;
updateCookieImage();
py.call("fortunecookie.get_current_fortune", [], function(result) {
currentFortune = result;
currentFortuneLabel.text = currentFortune;
currentFortuneLabel.visible = true;
});
});
} else {
fortuneOpened = false;
updateCookieImage();
currentFortuneLabel.text = "";
currentFortuneLabel.visible = false;
}
}
}
}
Label {
id: currentFortuneLabel
anchors {
top: cookieImage.bottom
topMargin: units.gu(2)
left: parent.left
right: parent.right
leftMargin: units.gu(2)
rightMargin: units.gu(2)
}
text: ""
fontSize: "large"
horizontalAlignment: Text.AlignHCenter
visible: false
wrapMode: Text.WordWrap
MouseArea {
anchors.fill: parent
onClicked: {
py.call("fortunecookie.get_new_fortune", [], function() {
fortuneOpened = false;
updateCookieImage();
py.call("fortunecookie.get_current_fortune", [], function(result) {
currentFortune = result;
currentFortuneLabel.text = currentFortune;
});
});
}
}
}
// AKTIVE LISTE ANZEIGE (unten links)
Label {
id: activeListLabel
anchors {
left: parent.left
verticalCenter: musicButton.verticalCenter
leftMargin: units.gu(2)
}
text: currentFortuneListDescription
fontSize: "medium"
color: theme.palette.normalText || "white"
visible: currentFortuneListDescription !== ""
}
// MUSIK-BUTTON
Label {
id: musicButton
anchors {
right: parent.right
bottom: parent.bottom
margins: units.gu(2)
}
width: units.gu(8)
height: units.gu(8)
text: musicPlaying ? "\uD83D\uDD0A" : "\uD83D\uDD07"
fontSize: "xx-large"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: theme.palette.normalText || "white"
visible: true
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
console.log("DEBUG QML: Music button clicked, current musicPlaying: " + musicPlaying);
if (musicPlaying) {
mediaPlayer.stop();
} else {
mediaPlayer.play();
}
musicPlaying = !musicPlaying;
console.log("DEBUG QML: Setting music enabled to: " + musicPlaying);
py.call("fortunecookie.set_music_enabled", [musicPlaying]);
}
}
}
}
// ================================================================
// SEITE 1: EINSTELLUNGEN
// ================================================================
Page {
id: settingsPage
objectName: 'settingsPage'
header: PageHeader {
title: "Einstellungen"
}
Component.onCompleted: {
// Verzögerte Initialisierung
Qt.callLater(function() {
try {
// Spruchlisten ComboBox füllen
py.call("fortunecookie.get_current_fortune_list", [], function(currentFortuneList) {
py.call("fortunecookie.get_fortune_lists_descriptions_only", [], function(listObjects) {
fortuneListCombo.model = listObjects;
// Aktuelle Liste auswählen
for (var i = 0; i < listObjects.length; i++) {
if (listObjects[i].list_name === currentFortuneList) {
fortuneListCombo.currentIndex = i;
break;
}
}
});
});
} catch (e) {
console.log("ERROR: Einstellungen nicht geladen: " + e);
}
});
}
ColumnLayout {
anchors.fill: parent
anchors.margins: units.gu(2)
spacing: units.gu(2)
// Spacer für Header
Item {
Layout.fillWidth: true
Layout.preferredHeight: units.gu(2)
}
// SPRUCHLISTEN-AUSWAHL
Label {
text: "Spruchliste:"
Layout.fillWidth: true
fontSize: "large"
}
ComboBox {
id: fortuneListCombo
Layout.fillWidth: true
Layout.preferredHeight: units.gu(8)
textRole: "description"
onActivated: {
var newListObj = fortuneListCombo.model[fortuneListCombo.currentIndex];
var newList = newListObj ? newListObj.list_name : "fortune";
py.call("fortunecookie.set_fortune_list", [newList], function() {
console.log("Spruchliste gewaehlt: " + newList);
root.currentFortuneListName = newList;
updateCookieImage();
reloadFortune();
// Aktualisiere die Anzeige im Hauptbildschirm
root.currentFortuneListDescription = newListObj ? cleanDescription(newListObj.description) : "";
});
}
}
// COOKIE-CRACK-SOUND TOGGLE
Label {
text: "Cookie-Knacksgeräusch:"
Layout.fillWidth: true
fontSize: "large"
}
Switch {
id: crackSoundSwitch
Layout.fillWidth: false
Layout.alignment: Qt.AlignHCenter
checked: cookieCrackEnabled
onCheckedChanged: {
cookieCrackEnabled = checked;
py.call("fortunecookie.set_cookie_crack_enabled", [checked]);
}
}
// ZURÜCK-BUTTON
Item {
Layout.fillWidth: true
Layout.preferredHeight: units.gu(10)
}
Button {
text: "Zurück"
Layout.fillWidth: false
Layout.preferredWidth: units.gu(20)
Layout.preferredHeight: units.gu(8)
Layout.alignment: Qt.AlignHCenter
onClicked: {
mainStack.currentIndex = 0;
}
}
}
}
}
}