Files
anonymisation/gui_v6/theme.py
Domi31tls 60fb41c2e7 fix(gui): clarifier aide et disponibilite moteurs
Passe theme clair, libelles utilisateur, aides conteneurs, recherche de mise a jour et indication honnete des moteurs optionnels non embarques. Tests GUI unitaires: 126 passed.
2026-06-17 18:01:25 +02:00

141 lines
3.9 KiB
Python

"""Thèmes et palette de la GUI V6 (G4 — alignement maquette).
Reprend les 4 thèmes et les tokens couleur exacts de ``docs/ui_mockup_v6.html``.
customtkinter n'a pas de variables CSS : on colore chaque widget via la palette
résolue ici. Les tokens semi-transparents de la maquette (rgba) sont rendus en
hex approchés sur le fond du thème.
Import de ce module : aucun widget créé (compatible ``--self-test``).
"""
from __future__ import annotations
from typing import Dict, List
# Palette complète par thème (tokens alignés sur la maquette HTML).
PALETTES: Dict[str, dict] = {
# Défaut maquette — sombre indigo / accent rose.
"sombre": {
"appearance": "dark",
"bg": "#1a1a2e",
"card": "#16213e",
"card_border": "#0f3460",
"primary": "#e94560",
"primary_dim": "#c73652",
"accent": "#f5a623",
"text": "#e0e0e0",
"text_dim": "#9ca3af",
"text_muted": "#6b7280",
"success": "#10b981",
"warning": "#f59e0b",
"danger": "#ef4444",
"blue": "#3b82f6",
"divider": "#23233a",
"btn_sec_bg": "#222a40",
"btn_sec_border": "#333a4d",
},
# Clair — fond gris moyen, cartes blanches.
"clair": {
"appearance": "light",
"bg": "#cdd2da",
"card": "#ffffff",
"card_border": "#9aa3b0",
"primary": "#c93050",
"primary_dim": "#a82545",
"accent": "#b45309",
"text": "#0d1117",
"text_dim": "#1f2937",
"text_muted": "#374151",
"success": "#047857",
"warning": "#b45309",
"danger": "#b91c1c",
"blue": "#1d4ed8",
"divider": "#e6e9ee",
"btn_sec_bg": "#eef0f3",
"btn_sec_border": "#9aa3b0",
},
# Médical — fond bleu structuré.
"medical": {
"appearance": "light",
"bg": "#b8ceea",
"card": "#eef5ff",
"card_border": "#6897ca",
"primary": "#1a56db",
"primary_dim": "#1340b0",
"accent": "#0369a1",
"text": "#071427",
"text_dim": "#0f2a4a",
"text_muted": "#1e3a5f",
"success": "#166534",
"warning": "#92400e",
"danger": "#991b1b",
"blue": "#1e40af",
"divider": "#dbe8fb",
"btn_sec_bg": "#e2edfc",
"btn_sec_border": "#6897ca",
},
# Neutre — gris sombre.
"neutre": {
"appearance": "dark",
"bg": "#1f2937",
"card": "#374151",
"card_border": "#6b7280",
"primary": "#818cf8",
"primary_dim": "#6366f1",
"accent": "#fbbf24",
"text": "#f9fafb",
"text_dim": "#e5e7eb",
"text_muted": "#d1d5db",
"success": "#34d399",
"warning": "#fbbf24",
"danger": "#f87171",
"blue": "#60a5fa",
"divider": "#2f3a49",
"btn_sec_bg": "#3d4a5c",
"btn_sec_border": "#6b7280",
},
}
DEFAULT_THEME = "clair"
THEME_LABELS = {
"sombre": "🌙 Sombre",
"clair": "☀️ Clair",
"medical": "🏥 Médical",
"neutre": "🌿 Neutre",
}
# Token de palette utilisé pour colorer un statut licence.
_STATUS_TOKEN = {
"active": "success",
"grace": "warning",
"expired": "danger",
"revoked": "danger",
"invalid": "danger",
"unavailable": "warning",
"none": "text_muted",
}
def theme_names() -> List[str]:
return list(PALETTES.keys())
def get_palette(name: str) -> dict:
return PALETTES.get(name, PALETTES[DEFAULT_THEME])
def status_color(theme_name: str, status: str) -> str:
"""Couleur hex pour un statut licence, dans le thème donné."""
palette = get_palette(theme_name)
return palette[_STATUS_TOKEN.get(status, "text_muted")]
def apply_theme(name: str = DEFAULT_THEME) -> dict:
"""Applique le mode d'apparence customtkinter et retourne la palette."""
palette = get_palette(name)
import customtkinter as ctk
ctk.set_appearance_mode(palette["appearance"])
return palette