Socle de la refonte GUI V6 (couche présentation uniquement, aucune logique de détection) : - license_store: stockage licence hors dépôt (%LOCALAPPDATA%/Aivanov | XDG), read/write atomique/delete, ne journalise aucun token - license_client: LicenseStatus + activate/check/local_status, session HTTP injectable, serveur indisponible géré sans crash, aucune clé privée - theme: 4 thèmes + couleurs de statut licence - app + tab_about: shell customtkinter minimal (header, bandeau licence, 3 onglets), onglet À propos étoffé - Pseudonymisation_Gui_V6.py: point d'entrée + --self-test (exit 0 sans fenêtre) - requirements.txt: customtkinter==5.2.2 Tests: 20 nouveaux (store sur vrais fichiers, client sur session injectée). Suite tests/unit: 167 passed, 0 régression. V5/moteur/managers/specs intacts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84 lines
2.1 KiB
Python
84 lines
2.1 KiB
Python
"""Thèmes et palette de la GUI V6.
|
|
|
|
Mappe les tokens de couleur de la maquette ``docs/ui_mockup_v6.html`` vers
|
|
customtkinter. Lot G1 : 4 thèmes de base + helper d'application. L'import de ce
|
|
module ne crée aucun widget (compatible ``--self-test`` sans display).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Dict
|
|
|
|
# Tokens couleur par thème (bandeau statut licence, accents, surfaces).
|
|
THEMES: Dict[str, dict] = {
|
|
"clair": {
|
|
"appearance": "light",
|
|
"color_theme": "blue",
|
|
"accent": "#2563eb",
|
|
"ok": "#16a34a",
|
|
"warn": "#d97706",
|
|
"error": "#dc2626",
|
|
},
|
|
"sombre": {
|
|
"appearance": "dark",
|
|
"color_theme": "blue",
|
|
"accent": "#3b82f6",
|
|
"ok": "#22c55e",
|
|
"warn": "#f59e0b",
|
|
"error": "#ef4444",
|
|
},
|
|
"médical": {
|
|
"appearance": "light",
|
|
"color_theme": "green",
|
|
"accent": "#0d9488",
|
|
"ok": "#15803d",
|
|
"warn": "#ca8a04",
|
|
"error": "#b91c1c",
|
|
},
|
|
"contraste": {
|
|
"appearance": "dark",
|
|
"color_theme": "dark-blue",
|
|
"accent": "#60a5fa",
|
|
"ok": "#4ade80",
|
|
"warn": "#fbbf24",
|
|
"error": "#f87171",
|
|
},
|
|
}
|
|
|
|
DEFAULT_THEME = "clair"
|
|
|
|
# Couleurs du bandeau de statut licence selon l'état métier.
|
|
STATUS_COLORS = {
|
|
"active": "ok",
|
|
"grace": "warn",
|
|
"expired": "error",
|
|
"revoked": "error",
|
|
"invalid": "error",
|
|
"unavailable": "warn",
|
|
"none": "warn",
|
|
}
|
|
|
|
|
|
def theme_names() -> list[str]:
|
|
return list(THEMES.keys())
|
|
|
|
|
|
def get_theme(name: str) -> dict:
|
|
return THEMES.get(name, THEMES[DEFAULT_THEME])
|
|
|
|
|
|
def status_color(theme_name: str, status: str) -> str:
|
|
"""Couleur hex pour un statut licence, dans le thème donné."""
|
|
theme = get_theme(theme_name)
|
|
return theme[STATUS_COLORS.get(status, "warn")]
|
|
|
|
|
|
def apply_theme(name: str = DEFAULT_THEME) -> dict:
|
|
"""Applique le thème à customtkinter. Import paresseux de ctk."""
|
|
theme = get_theme(name)
|
|
import customtkinter as ctk
|
|
|
|
ctk.set_appearance_mode(theme["appearance"])
|
|
ctk.set_default_color_theme(theme["color_theme"])
|
|
return theme
|