Estil targeta tipus web a les files + tema seleccionable (system/clar/fosc)
UI: - Files amb estil de targeta: icona arrodonida, títol gran, subtítol atenuat i 'pills' amb estat, versió, data de llançament, jugadors, autor i topics. Els pills envolten amb un FlowLayout nou quan no caben. - Submenú Opcions > Tema amb Sistema/Clar/Fosc; persisteix a settings.json (theme) i s'aplica a l'instant. El watcher del SO només actua en mode Sistema. Dades: - GameMeta guarda topics i created_at, llegits de la resposta de Gitea que ja demanàvem (gratis, auto-sincronitzats). - games.toml: camps opcionals players i author per joc (la resta surt de Gitea). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+28
-6
@@ -8,11 +8,18 @@ propios (consola de log, fondos) siguen automáticamente esta paleta.
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from collections.abc import Callable
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QColor, QPalette
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
# Modos de tema seleccionables por el usuario.
|
||||
THEME_SYSTEM = "system"
|
||||
THEME_LIGHT = "light"
|
||||
THEME_DARK = "dark"
|
||||
THEME_MODES = (THEME_SYSTEM, THEME_LIGHT, THEME_DARK)
|
||||
|
||||
|
||||
def _portal_is_dark() -> bool | None:
|
||||
"""Consulta el portal XDG (org.freedesktop.appearance color-scheme).
|
||||
@@ -104,17 +111,32 @@ def _dark_palette() -> QPalette:
|
||||
return p
|
||||
|
||||
|
||||
def apply_theme(app: QApplication) -> None:
|
||||
"""Aplica estilo Fusion + paleta acorde al esquema del sistema."""
|
||||
def resolve_is_dark(app: QApplication, mode: str) -> bool:
|
||||
"""Decide si pintar oscuro según el modo elegido (system/light/dark)."""
|
||||
if mode == THEME_DARK:
|
||||
return True
|
||||
if mode == THEME_LIGHT:
|
||||
return False
|
||||
return system_is_dark(app) # THEME_SYSTEM (o valor desconocido)
|
||||
|
||||
|
||||
def apply_theme(app: QApplication, mode: str = THEME_SYSTEM) -> None:
|
||||
"""Aplica estilo Fusion + paleta clara/oscura según el modo elegido."""
|
||||
app.setStyle("Fusion")
|
||||
if system_is_dark(app):
|
||||
if resolve_is_dark(app, mode):
|
||||
app.setPalette(_dark_palette())
|
||||
else:
|
||||
app.setPalette(app.style().standardPalette())
|
||||
|
||||
|
||||
def watch_system_theme(app: QApplication) -> None:
|
||||
"""Re-aplica el tema cuando el sistema cambia entre claro/oscuro en caliente."""
|
||||
def watch_system_theme(app: QApplication, should_follow: Callable[[], bool]) -> None:
|
||||
"""Re-aplica el tema al cambiar el esquema del sistema, solo si seguimos al sistema.
|
||||
|
||||
``should_follow`` se consulta en cada cambio: devuelve True cuando el modo activo
|
||||
es 'system' (si el usuario ha forzado claro/oscuro, ignoramos el cambio del SO).
|
||||
"""
|
||||
hints = app.styleHints()
|
||||
if hasattr(hints, "colorSchemeChanged"):
|
||||
hints.colorSchemeChanged.connect(lambda _scheme: apply_theme(app))
|
||||
hints.colorSchemeChanged.connect(
|
||||
lambda _scheme: apply_theme(app, THEME_SYSTEM) if should_follow() else None
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user