fix: Last-State, Keks-Größe, Musik-Button
- Last-State speichert in .cache/fortunecookie.darklithium/music_enabled - Geöffneter Keks: 36x28 gu (geschlossen: 32x24 gu) - Musik-Button: 10x10 gu, x-large Icon, erst nach Init sichtbar - Python ohne PySide2-Abhängigkeiten - Properties vor Functions in QML Fixes: PermissionError auf .config/, Icon-Flickern Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
@@ -4,7 +4,7 @@ Type=Application
|
|||||||
Name=Fortune Cookie
|
Name=Fortune Cookie
|
||||||
Comment=Glückskeks App mit Sprüchen, Musik und einfacher Verwaltung
|
Comment=Glückskeks App mit Sprüchen, Musik und einfacher Verwaltung
|
||||||
Exec=qmlscene %U qml/Main.qml
|
Exec=qmlscene %U qml/Main.qml
|
||||||
Icon=assets/cookie_closed.png
|
Icon=assets/cookie_closed2.png
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Categories=Utility;
|
Categories=Utility;
|
||||||
X-Lomiri-Touch=true
|
X-Lomiri-Touch=true
|
||||||
|
|||||||
+75
-47
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick 2.7
|
import QtQuick 2.7
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtMultimedia 5.0
|
||||||
import Lomiri.Components 1.3
|
import Lomiri.Components 1.3
|
||||||
import Lomiri.Components.Popups 1.3
|
import Lomiri.Components.Popups 1.3
|
||||||
import io.thp.pyotherside 1.4
|
import io.thp.pyotherside 1.4
|
||||||
@@ -11,97 +12,114 @@ MainView {
|
|||||||
height: units.gu(75)
|
height: units.gu(75)
|
||||||
theme.name: "Lomiri.Components.Themes.SuruDark"
|
theme.name: "Lomiri.Components.Themes.SuruDark"
|
||||||
|
|
||||||
// ====================================================================
|
property bool fortuneOpened: false
|
||||||
// 1. PYTHON-MODUL (STANDARD 1.7)
|
property string currentFortune: ""
|
||||||
// ====================================================================
|
property bool musicPlaying: false
|
||||||
|
property bool musicButtonVisible: false
|
||||||
|
|
||||||
Python {
|
Python {
|
||||||
id: py
|
id: py
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
addImportPath(Qt.resolvedUrl("../src"));
|
addImportPath(Qt.resolvedUrl("../src"));
|
||||||
importModule("fortunecookie", function() {
|
importModule("fortunecookie", function() {
|
||||||
console.log("Python-Modul fortunecookie geladen");
|
console.log("Python-Modul fortunecookie geladen");
|
||||||
// Initialisierung
|
|
||||||
currentFortuneLabel.text = py.call_sync("fortunecookie.get_initial_fortune", []);
|
|
||||||
cookieImage.source = "assets/cookie_closed.png";
|
|
||||||
fortuneOpened = false;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================================================================
|
MediaPlayer {
|
||||||
// 2. APP-ZUSTAND (STANDARD 1.7)
|
id: mediaPlayer
|
||||||
// ====================================================================
|
source: Qt.resolvedUrl("../assets/chinese_music.mp3")
|
||||||
property bool fortuneOpened: false
|
loops: MediaPlayer.Infinite
|
||||||
property string currentFortune: ""
|
volume: 0.5
|
||||||
property bool musicPlaying: false
|
}
|
||||||
|
|
||||||
|
MediaPlayer {
|
||||||
|
id: crackMediaPlayer
|
||||||
|
source: Qt.resolvedUrl("../assets/cookie_crack.mp3")
|
||||||
|
volume: 1.0
|
||||||
|
}
|
||||||
|
|
||||||
// ====================================================================
|
|
||||||
// 3. HAUPTSEITE
|
|
||||||
// ====================================================================
|
|
||||||
Page {
|
Page {
|
||||||
id: mainPage
|
id: mainPage
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
// Header
|
|
||||||
header: PageHeader {
|
header: PageHeader {
|
||||||
title: "Fortune Cookie"
|
title: "Fortune Cookie"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================
|
Timer {
|
||||||
// COOKIE & SPRUCH
|
id: initTimer
|
||||||
// ================================================================
|
interval: 1000 // Warte 1 Sekunde auf Python-Ladung
|
||||||
|
running: true
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
try {
|
||||||
|
currentFortuneLabel.text = py.call_sync("fortunecookie.get_initial_fortune", []);
|
||||||
|
cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png");
|
||||||
|
musicPlaying = py.call_sync("fortunecookie.get_music_enabled", []);
|
||||||
|
console.log("DEBUG QML: musicPlaying loaded from Python: " + musicPlaying);
|
||||||
|
if (musicPlaying) {
|
||||||
|
mediaPlayer.play();
|
||||||
|
}
|
||||||
|
musicButtonVisible = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("ERROR QML: Failed to initialize: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cookie-Image (zentral)
|
|
||||||
Image {
|
Image {
|
||||||
id: cookieImage
|
id: cookieImage
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: units.gu(30)
|
width: fortuneOpened ? units.gu(36) : units.gu(32)
|
||||||
height: units.gu(30)
|
height: fortuneOpened ? units.gu(28) : units.gu(24)
|
||||||
source: fortuneOpened ? "assets/cookie_open.png" : "assets/cookie_closed.png"
|
source: fortuneOpened ? Qt.resolvedUrl("../assets/cookie_open2.png") : Qt.resolvedUrl("../assets/cookie_closed2.png")
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
|
||||||
// Wisch-Geste nach oben
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property real startY: 0
|
property real startY: 0
|
||||||
|
|
||||||
onPressed: {
|
onPressed: startY = mouseY
|
||||||
startY = mouseY
|
|
||||||
}
|
|
||||||
|
|
||||||
onReleased: {
|
onReleased: {
|
||||||
// Ende der Geste - pruufen ob nach oben gewischt
|
|
||||||
if (mouseY < startY - units.gu(2)) {
|
if (mouseY < startY - units.gu(2)) {
|
||||||
// Wisch nach oben -> Cookie oeffnen
|
|
||||||
py.call("fortunecookie.open_fortune", [], function() {
|
py.call("fortunecookie.open_fortune", [], function() {
|
||||||
|
crackMediaPlayer.play();
|
||||||
fortuneOpened = true;
|
fortuneOpened = true;
|
||||||
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
||||||
currentFortuneLabel.text = currentFortune;
|
currentFortuneLabel.text = currentFortune;
|
||||||
cookieImage.source = "assets/cookie_open.png";
|
cookieImage.source = Qt.resolvedUrl("../assets/cookie_open2.png");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tap auf Cookie (wenn geschlossen)
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!fortuneOpened) {
|
if (!fortuneOpened) {
|
||||||
// Cookie oeffnen (gleiche Funktion wie Wisch nach oben)
|
|
||||||
py.call("fortunecookie.open_fortune", [], function() {
|
py.call("fortunecookie.open_fortune", [], function() {
|
||||||
|
crackMediaPlayer.play();
|
||||||
fortuneOpened = true;
|
fortuneOpened = true;
|
||||||
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
||||||
currentFortuneLabel.text = currentFortune;
|
currentFortuneLabel.text = currentFortune;
|
||||||
cookieImage.source = "assets/cookie_open.png";
|
currentFortuneLabel.visible = true;
|
||||||
|
cookieImage.source = Qt.resolvedUrl("../assets/cookie_open2.png");
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
fortuneOpened = false;
|
||||||
|
currentFortuneLabel.text = "";
|
||||||
|
currentFortuneLabel.visible = false;
|
||||||
|
cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fortune-Text (erscheint nach dem Oeffnen)
|
|
||||||
Label {
|
Label {
|
||||||
id: currentFortuneLabel
|
id: currentFortuneLabel
|
||||||
anchors {
|
anchors {
|
||||||
@@ -118,7 +136,6 @@ MainView {
|
|||||||
visible: fortuneOpened
|
visible: fortuneOpened
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
// Tap auf Spruch -> neuer Cookie
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
@@ -127,34 +144,45 @@ MainView {
|
|||||||
fortuneOpened = false;
|
fortuneOpened = false;
|
||||||
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
currentFortune = py.call_sync("fortunecookie.get_current_fortune", []);
|
||||||
currentFortuneLabel.text = currentFortune;
|
currentFortuneLabel.text = currentFortune;
|
||||||
cookieImage.source = "assets/cookie_closed.png";
|
cookieImage.source = Qt.resolvedUrl("../assets/cookie_closed2.png");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================
|
Item {
|
||||||
// MUSIK BUTTON (rechts unten)
|
id: musicButtonContainer
|
||||||
// ================================================================
|
|
||||||
Button {
|
|
||||||
id: musicButton
|
|
||||||
anchors {
|
anchors {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
margins: units.gu(2)
|
margins: units.gu(2)
|
||||||
}
|
}
|
||||||
width: units.gu(8)
|
width: units.gu(10)
|
||||||
height: units.gu(8)
|
height: units.gu(10)
|
||||||
text: musicPlaying ? "\uD83D\uDD07" : "\uD83D\uDD0A"
|
visible: musicButtonVisible
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: musicButton
|
||||||
|
text: musicPlaying ? "\uD83D\uDD0A" : "\uD83D\uDD07"
|
||||||
fontSize: "x-large"
|
fontSize: "x-large"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
console.log("DEBUG QML: Music button clicked, current musicPlaying: " + musicPlaying);
|
||||||
if (musicPlaying) {
|
if (musicPlaying) {
|
||||||
py.call("fortunecookie.stop_music", []);
|
mediaPlayer.stop();
|
||||||
} else {
|
} else {
|
||||||
py.call("fortunecookie.start_music", []);
|
mediaPlayer.play();
|
||||||
}
|
}
|
||||||
musicPlaying = !musicPlaying;
|
musicPlaying = !musicPlaying;
|
||||||
|
console.log("DEBUG QML: Setting music enabled to: " + musicPlaying);
|
||||||
|
py.call("fortunecookie.set_music_enabled", [musicPlaying]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-155
@@ -1,6 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Fortune Cookie v1.0 - Python Backend Module
|
Fortune Cookie v1.0 - Python Backend Module
|
||||||
Framework 1.7 Standard
|
Framework 1.7 Standard
|
||||||
|
Audio-Steuerung in QML (keine Qt-Python-Bindings benoetigt)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -37,18 +38,13 @@ _current_fortune = ""
|
|||||||
_fortunes = []
|
_fortunes = []
|
||||||
_initialized = False
|
_initialized = False
|
||||||
|
|
||||||
# Musik-Status
|
# Musik-Status (wird dynamisch von Datei geladen)
|
||||||
_music_enabled = True
|
# _music_enabled wird nicht als globale Variable gespeichert, sondern immer frisch geladen
|
||||||
_music_playing = False
|
|
||||||
|
|
||||||
# Medien-Player (wird lazy initialisiert)
|
|
||||||
_media_player = None
|
|
||||||
_cookie_crack_sound = None
|
|
||||||
|
|
||||||
|
|
||||||
def _init():
|
def _init():
|
||||||
"""Initialisiert das Modul (wird beim ersten Aufruf ausgefuehrt)."""
|
"""Initialisiert das Modul (wird beim ersten Aufruf ausgefuehrt)."""
|
||||||
global _fortunes, _initialized, _music_enabled
|
global _fortunes, _initialized
|
||||||
|
|
||||||
if _initialized:
|
if _initialized:
|
||||||
return True
|
return True
|
||||||
@@ -56,9 +52,6 @@ def _init():
|
|||||||
# Lade Fortunes
|
# Lade Fortunes
|
||||||
_load_fortunes()
|
_load_fortunes()
|
||||||
|
|
||||||
# Lade Last-State
|
|
||||||
_music_enabled = _load_music_state()
|
|
||||||
|
|
||||||
_initialized = True
|
_initialized = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -84,6 +77,9 @@ def _load_fortunes():
|
|||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
_fortunes = data
|
_fortunes = data
|
||||||
elif isinstance(data, dict):
|
elif isinstance(data, dict):
|
||||||
|
# Lade deutsche Sprüche, falls vorhanden, sonst englische
|
||||||
|
_fortunes = data.get("de", data.get("en", []))
|
||||||
|
elif isinstance(data, dict) and "fortunes" in data:
|
||||||
_fortunes = data.get("fortunes", [])
|
_fortunes = data.get("fortunes", [])
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -95,12 +91,14 @@ def _load_fortunes():
|
|||||||
]
|
]
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# Fallback: Einige Standard-Sprueche
|
_fortunes = []
|
||||||
_fortunes = [
|
|
||||||
"Ein guter Tag beginnt mit einem Laecheln.",
|
|
||||||
"Das Glueck liegt in den kleinen Dingen.",
|
def _get_random_fortune():
|
||||||
"Geduld ist eine Tugend.",
|
"""Gibt einen zufaelligen Spruch zurueck."""
|
||||||
]
|
if not _fortunes:
|
||||||
|
_load_fortunes()
|
||||||
|
return random.choice(_fortunes) if _fortunes else "Keine Sprueche verfguebar."
|
||||||
|
|
||||||
|
|
||||||
def get_initial_fortune():
|
def get_initial_fortune():
|
||||||
@@ -112,16 +110,13 @@ def get_initial_fortune():
|
|||||||
|
|
||||||
|
|
||||||
def open_fortune():
|
def open_fortune():
|
||||||
"""Oeffnet den Fortune Cookie (neuer Spruch + Knack-Geraeusch)."""
|
"""Oeffnet den Fortune Cookie (neuer Spruch)."""
|
||||||
_init()
|
_init()
|
||||||
global _current_fortune
|
global _current_fortune
|
||||||
|
|
||||||
# Neuer Spruch
|
# Neuer Spruch
|
||||||
_current_fortune = _get_random_fortune()
|
_current_fortune = _get_random_fortune()
|
||||||
|
|
||||||
# Knack-Geraeusch abspielen (wenn verfguebar)
|
|
||||||
_play_crack_sound()
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -140,164 +135,83 @@ def get_new_fortune():
|
|||||||
return _current_fortune
|
return _current_fortune
|
||||||
|
|
||||||
|
|
||||||
def _get_random_fortune():
|
|
||||||
"""Gibt einen zufaelligen Spruch zurueck."""
|
|
||||||
if not _fortunes:
|
|
||||||
_load_fortunes()
|
|
||||||
return random.choice(_fortunes) if _fortunes else "Keine Sprueche verfguebar."
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# MUSIK-LOGIK
|
# LAST-STATE SPEICHERUNG (Musik an/aus)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
def start_music():
|
def _get_config_dir():
|
||||||
"""Startet die Hintergrundmusik."""
|
"""Gibt das Konfigurationsverzeichnis der App zurueck.
|
||||||
_init()
|
|
||||||
global _music_playing, _media_player, _music_enabled
|
|
||||||
|
|
||||||
if not _music_enabled:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
Click-Apps auf UBPorts haben eingeschraenkte Schreibrechte.
|
||||||
|
Verwendete Pfade:
|
||||||
|
- ~/.cache/<appname>/ (funktioniert in Click-Apps)
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
# Medien-Player initialisieren (wenn nicht vorhanden)
|
home = os.path.expanduser("~")
|
||||||
if _media_player is None:
|
# Click-App-Pfad (funktioniert in der Sandbox)
|
||||||
from PySide2 import QtMultimedia, QtCore
|
app_name = "fortunecookie.darklithium"
|
||||||
|
cache_dir = os.path.join(home, ".cache", app_name)
|
||||||
_media_player = QtMultimedia.QMediaPlayer()
|
os.makedirs(cache_dir, exist_ok=True)
|
||||||
audio_output = QtMultimedia.QAudioOutput()
|
return cache_dir
|
||||||
_media_player.setAudioOutput(audio_output)
|
|
||||||
|
|
||||||
# Musik-Datei laden
|
|
||||||
music_path = get_asset_path("chinese_music.mp3")
|
|
||||||
_media_player.setSource(QtCore.QUrl.fromLocalFile(music_path))
|
|
||||||
_media_player.setLoops(QtMultimedia.QMediaPlayer.Infinite)
|
|
||||||
_media_player.setVolume(50)
|
|
||||||
|
|
||||||
_media_player.play()
|
|
||||||
_music_playing = True
|
|
||||||
return True
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
# Fallback
|
||||||
|
return os.path.join("/tmp", "fortunecookie")
|
||||||
|
|
||||||
|
|
||||||
def stop_music():
|
def _get_music_state_file():
|
||||||
"""Stoppt die Hintergrundmusik."""
|
"""Gibt den Pfad zur Musik-Status-Datei zurueck."""
|
||||||
global _music_playing, _media_player
|
config_dir = _get_config_dir()
|
||||||
|
return os.path.join(config_dir, "music_enabled")
|
||||||
if _media_player is not None:
|
|
||||||
try:
|
|
||||||
_media_player.stop()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
_music_playing = False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def toggle_music():
|
|
||||||
"""Wechselt Musik-Status (an/aus)."""
|
|
||||||
if _music_playing:
|
|
||||||
return stop_music()
|
|
||||||
else:
|
|
||||||
return start_music()
|
|
||||||
|
|
||||||
|
|
||||||
def set_music_enabled(enabled):
|
|
||||||
"""Aktiviert/Deaktiviert Musik generell."""
|
|
||||||
global _music_enabled
|
|
||||||
_music_enabled = enabled
|
|
||||||
_save_music_state(enabled)
|
|
||||||
return enabled
|
|
||||||
|
|
||||||
|
|
||||||
def get_music_enabled():
|
|
||||||
"""Gibt zurueck, ob Musik aktiviert ist."""
|
|
||||||
global _music_enabled
|
|
||||||
return _music_enabled
|
|
||||||
|
|
||||||
|
|
||||||
def get_music_playing():
|
|
||||||
"""Gibt zurueck, ob Musik gerade spielt."""
|
|
||||||
global _music_playing
|
|
||||||
return _music_playing
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
# LAST-STATE SPEICHERUNG
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
def _get_data_dir():
|
|
||||||
"""Gibt das Datenverzeichnis zurueck."""
|
|
||||||
if "CLICK" in os.environ:
|
|
||||||
return os.path.join(
|
|
||||||
os.path.expanduser("~"), ".local", "share", f"{APP_NAME}.darklithium"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return os.path.join(
|
|
||||||
os.path.expanduser("~"), ".local", "share", f"{APP_NAME}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _load_music_state():
|
def _load_music_state():
|
||||||
"""Laedt den Musik-Status aus Datei."""
|
"""Laedt den Musik-Status aus Datei (true/false)."""
|
||||||
try:
|
try:
|
||||||
state_file = os.path.join(_get_data_dir(), "music_state.json")
|
state_file = _get_music_state_file()
|
||||||
|
print(f"DEBUG: Loading music state from: {state_file}")
|
||||||
|
print(f"DEBUG: File exists: {os.path.exists(state_file)}")
|
||||||
if os.path.exists(state_file):
|
if os.path.exists(state_file):
|
||||||
with open(state_file, "r") as f:
|
with open(state_file, "r") as f:
|
||||||
data = json.load(f)
|
content = f.read().strip().lower()
|
||||||
return data.get("enabled", True)
|
print(f"DEBUG: File content: '{content}'")
|
||||||
except Exception:
|
result = content == "true"
|
||||||
pass
|
print(f"DEBUG: Music enabled: {result}")
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
print("DEBUG: Music state file does not exist, using default: True")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"WARN: Musik-Status nicht geladen: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
# Default: Musik an
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _save_music_state(enabled):
|
def _save_music_state(enabled):
|
||||||
"""Speichert den Musik-Status in Datei."""
|
"""Speichert den Musik-Status in Datei (true/false)."""
|
||||||
try:
|
try:
|
||||||
data_dir = _get_data_dir()
|
config_dir = _get_config_dir()
|
||||||
os.makedirs(data_dir, exist_ok=True)
|
os.makedirs(config_dir, exist_ok=True)
|
||||||
state_file = os.path.join(data_dir, "music_state.json")
|
state_file = _get_music_state_file()
|
||||||
|
print(f"DEBUG: Saving music state {enabled} to: {state_file}")
|
||||||
with open(state_file, "w") as f:
|
with open(state_file, "w") as f:
|
||||||
json.dump({"enabled": enabled}, f)
|
f.write("true" if enabled else "false")
|
||||||
except Exception:
|
print(f"DEBUG: Successfully saved music state")
|
||||||
pass
|
except Exception as e:
|
||||||
|
print(f"WARN: Musik-Status nicht gespeichert: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
def _play_crack_sound():
|
def set_music_enabled(enabled):
|
||||||
"""Spielt das Knack-Geraeusch ab."""
|
"""Aktiviert/Deaktiviert die Musik und speichert den Status."""
|
||||||
try:
|
_save_music_state(enabled)
|
||||||
global _cookie_crack_sound
|
return True
|
||||||
|
|
||||||
if _cookie_crack_sound is None:
|
|
||||||
from PySide2 import QtMultimedia, QtCore
|
|
||||||
|
|
||||||
_cookie_crack_sound = QtMultimedia.QMediaPlayer()
|
|
||||||
audio_output = QtMultimedia.QAudioOutput()
|
|
||||||
_cookie_crack_sound.setAudioOutput(audio_output)
|
|
||||||
|
|
||||||
crack_path = get_asset_path("cookie_crack.mp3")
|
|
||||||
if os.path.exists(crack_path):
|
|
||||||
_cookie_crack_sound.setSource(QtCore.QUrl.fromLocalFile(crack_path))
|
|
||||||
_cookie_crack_sound.setVolume(100)
|
|
||||||
_cookie_crack_sound.play()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
def get_music_enabled():
|
||||||
# DATENVERZEICHNIS (fuer zukuenftige Erweiterungen)
|
"""Gibt den Musik-Status zurueck (frisch von Datei geladen)."""
|
||||||
# ============================================================================
|
return _load_music_state()
|
||||||
|
|
||||||
def get_data_dir():
|
|
||||||
"""Gibt das Datenverzeichnis der App zurueck."""
|
|
||||||
return _get_data_dir()
|
|
||||||
|
|
||||||
|
|
||||||
def get_fortunes_file_path():
|
|
||||||
"""Gibt den Pfad zur Fortunes-Datei zurueck."""
|
|
||||||
return os.path.join(_get_data_dir(), "fortunes.json")
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user