diff --git a/LEKTIONEN_2026-06-06.md b/LEKTIONEN_2026-06-06.md new file mode 100644 index 0000000..163c758 --- /dev/null +++ b/LEKTIONEN_2026-06-06.md @@ -0,0 +1,98 @@ +# Lektionen gelehrt am 06.06.2026 + +## 🎯 Dynamische Cookie-Bilder Implementierung + +### Problem +Cookie-Bilder sollten sich je nach ausgewählter Spruchliste ändern (z.B. `famous quotes_open.png` für berühmte Zitate). + +### Lösung +1. **Funktion `updateCookieImage()`** erstellt, die den Bildpfad basierend auf `currentFortuneListName` und `fortuneOpened` bestimmt +2. **Explizite Aufrufe** an allen Stellen, wo sich der Zustand ändert: + - Initialisierung (mit `Qt.callLater` für UI-Bereitschaft) + - Beim Listenwechsel in den Einstellungen + - Beim Öffnen/Schließen des Cookies (MouseArea Handler) + - Beim Neuladen des Fortunes + +### Wichtige Erkenntnis +**Qt.binding() funktioniert NICHT zuverlässig** für automatische Updates, wenn sich Properties in JavaScript-Funktionen ändern. +→ **Immer explizite Aufrufe** von Update-Funktionen verwenden, statt auf automatische Bindings zu vertrauen. + +### Code-Beispiel +```qml +function updateCookieImage() { + var listName = currentFortuneListName || "fortune"; + var availableLists = ["farmer wisdom", "UNfortune", ...]; + 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"); + } +} +``` + +--- + +## 📝 Listenbeschreibungen + +### Problem +Spruchanzahl wurde in Klammern angezeigt (z.B. "Redensarten aus aller Welt (15)"). + +### Lösung +`cleanDescription()`-Funktion entfernt alle Klammern mit Zahlen am Ende: +```qml +function cleanDescription(text) { + return text.replace(/\s*\(\d+\)$/, ""); +} +``` + +--- + +## 🔊 Cookie-Knacksgeräusch Toggle + +### Implementierung +- Property `cookieCrackEnabled` (default: true) +- Switch in Einstellungen mit Binding an die Property +- Sound wird nur abgespielt, wenn `cookieCrackEnabled === true` + +### Code +```qml +Switch { + checked: cookieCrackEnabled + onCheckedChanged: { + cookieCrackEnabled = checked; + py.call("fortunecookie.set_cookie_crack_enabled", [checked]); + } +} + +// In Event-Handlern: +if (cookieCrackEnabled) crackMediaPlayer.play(); +``` + +--- + +## 📏 Cookie-Icon-Größen + +### Anpassung +- Geschlossen: 30x26 GU +- Geöffnet: 34x30 GU + +Alle Cookie-Bilder haben jetzt ähnliche Dimensionen für ein einheitliches Aussehen. + +--- + +## 🔧 Debugging-Tipps + +1. **console.log() ist essenziell** - Ohne Debug-Ausgaben ist es schwer, den Code-Fluss zu verfolgen +2. **Clean Build** - `clickable clean` vor `clickable build` durchführen, wenn Änderungen nicht sichtbar sind +3. **Git Status prüfen** - `git status` zeigt, welche Dateien geändert sind +4. **Build-Directory prüfen** - Manchmal wird die alte Main.qml verwendet, weil der Build nicht neu gestartet wurde + +--- + +## 📌 Best Practices + +1. **Explizit > Implizit** - Bei QML besser explizite Funktionsaufrufe als automatische Bindings verwenden +2. **Fehlerbehandlung** - try-catch in komplexen Funktionen hilft bei der Fehlersuche +3. **Konsistente Größen** - UI-Elemente sollten ähnliche Dimensionen haben für ein professionelles Aussehen +4. **Benutzerfreundlichkeit** - Toggle-Switches für Sound sind intuitiver als Checkboxen diff --git a/assets/UNfortune_close.png b/assets/UNfortune_close.png new file mode 100644 index 0000000..12806a5 Binary files /dev/null and b/assets/UNfortune_close.png differ diff --git a/assets/UNfortune_open.png b/assets/UNfortune_open.png new file mode 100644 index 0000000..c585541 Binary files /dev/null and b/assets/UNfortune_open.png differ diff --git a/assets/famous quotes_close.png b/assets/famous quotes_close.png new file mode 100644 index 0000000..c7271d2 Binary files /dev/null and b/assets/famous quotes_close.png differ diff --git a/assets/famous quotes_open.png b/assets/famous quotes_open.png new file mode 100644 index 0000000..ebf7317 Binary files /dev/null and b/assets/famous quotes_open.png differ diff --git a/assets/farmer wisdom_close.png b/assets/farmer wisdom_close.png new file mode 100644 index 0000000..22ebc00 Binary files /dev/null and b/assets/farmer wisdom_close.png differ diff --git a/assets/farmer wisdom_open.png b/assets/farmer wisdom_open.png new file mode 100644 index 0000000..9d95f62 Binary files /dev/null and b/assets/farmer wisdom_open.png differ diff --git a/assets/idioms_close.png b/assets/idioms_close.png new file mode 100644 index 0000000..b7ba356 Binary files /dev/null and b/assets/idioms_close.png differ diff --git a/assets/idioms_open.png b/assets/idioms_open.png new file mode 100644 index 0000000..16a55e1 Binary files /dev/null and b/assets/idioms_open.png differ diff --git a/assets/sandman_close.png b/assets/sandman_close.png new file mode 100644 index 0000000..b4cc460 Binary files /dev/null and b/assets/sandman_close.png differ diff --git a/assets/sandman_open.png b/assets/sandman_open.png new file mode 100644 index 0000000..ac66c7c Binary files /dev/null and b/assets/sandman_open.png differ diff --git a/assets/unicorn_close.png b/assets/unicorn_close.png new file mode 100644 index 0000000..cd8eeb0 Binary files /dev/null and b/assets/unicorn_close.png differ diff --git a/assets/unicorn_open.png b/assets/unicorn_open.png new file mode 100644 index 0000000..4480349 Binary files /dev/null and b/assets/unicorn_open.png differ diff --git a/assets/vegan recipes_close.png b/assets/vegan recipes_close.png new file mode 100644 index 0000000..af2dd01 Binary files /dev/null and b/assets/vegan recipes_close.png differ diff --git a/assets/vegan recipes_open.png b/assets/vegan recipes_open.png new file mode 100644 index 0000000..dfaa9cb Binary files /dev/null and b/assets/vegan recipes_open.png differ diff --git a/qml/Main.qml b/qml/Main.qml index 0da02fd..003174a 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -19,8 +19,26 @@ MainView { 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 @@ -94,20 +112,25 @@ MainView { py.call("fortunecookie.get_initial_fortune", [], function(result) { currentFortune = result; currentFortuneLabel.text = currentFortune; - cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png"); }); // Musik-Status laden py.call("fortunecookie.get_music_enabled", [], function(result) { musicPlaying = result; - console.log("DEBUG QML: musicPlaying geladen: " + musicPlaying); 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", @@ -118,7 +141,7 @@ MainView { "vegan recipes": "Vegane Rezeptideen", "unicorn": "Einhorn Glückssprüche (die fast schon wehtun)" }; - root.currentFortuneListDescription = descriptions[listName] || listName; + root.currentFortuneListDescription = cleanDescription(descriptions[listName] || listName); }); appInitialized = true; @@ -132,9 +155,9 @@ MainView { Image { id: cookieImage anchors.centerIn: parent - width: fortuneOpened ? units.gu(36) : units.gu(32) - height: fortuneOpened ? units.gu(28) : units.gu(24) - source: fortuneOpened ? Qt.resolvedUrl("../assets/cookie_open2.png") : Qt.resolvedUrl("../assets/cookie_closed2.png") + width: fortuneOpened ? units.gu(34) : units.gu(30) + height: fortuneOpened ? units.gu(30) : units.gu(26) + source: "" fillMode: Image.PreserveAspectFit MouseArea { @@ -146,13 +169,13 @@ MainView { onReleased: { if (mouseY < startY - units.gu(2)) { py.call("fortunecookie.open_fortune", [], function() { - crackMediaPlayer.play(); + if (cookieCrackEnabled) crackMediaPlayer.play(); fortuneOpened = true; + updateCookieImage(); py.call("fortunecookie.get_current_fortune", [], function(result) { currentFortune = result; currentFortuneLabel.text = currentFortune; currentFortuneLabel.visible = true; - cookieImage.source = Qt.resolvedUrl("../assets/cookie_open2.png"); }); }); } @@ -166,20 +189,20 @@ MainView { onClicked: { if (!fortuneOpened) { py.call("fortunecookie.open_fortune", [], function() { - crackMediaPlayer.play(); + if (cookieCrackEnabled) crackMediaPlayer.play(); fortuneOpened = true; + updateCookieImage(); py.call("fortunecookie.get_current_fortune", [], function(result) { currentFortune = result; currentFortuneLabel.text = currentFortune; currentFortuneLabel.visible = true; - cookieImage.source = Qt.resolvedUrl("../assets/cookie_open2.png"); }); }); } else { fortuneOpened = false; + updateCookieImage(); currentFortuneLabel.text = ""; currentFortuneLabel.visible = false; - cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png"); } } } @@ -207,10 +230,10 @@ MainView { onClicked: { py.call("fortunecookie.get_new_fortune", [], function() { fortuneOpened = false; + updateCookieImage(); py.call("fortunecookie.get_current_fortune", [], function(result) { currentFortune = result; currentFortuneLabel.text = currentFortune; - cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png"); }); }); } @@ -332,13 +355,33 @@ MainView { 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 ? newListObj.description : ""; + 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