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; } } } } } }