feat(gui): add GUI V6 G1 foundation (license client/store, shell, About tab)
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>
This commit is contained in:
83
gui_v6/theme.py
Normal file
83
gui_v6/theme.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user