core/theme.py est le moteur esthétique de GrimOS. Il contient la base de données des "styles visuels" et la logique nécessaire pour injecter ces styles dans l'ensemble des composants Tkinter, permettant à GrimOS de changer radicalement d'apparence en temps réel.
THEMES : C'est le cœur du fichier. Il liste des profils comme "Win 98", "MacOS Classic", ou "Ubuntu". Chaque profil est un dictionnaire de variables (couleurs hexadécimales, noms de polices, styles de bordures).option_add) : La fonction apply_theme(root, theme_name) utilise le mécanisme natif (mais peu connu) de Tkinter : la base de données d'options X11. En utilisant root.option_add("*background", couleur), elle force tous les widgets qui seront instanciés par la suite à hériter de cette couleur, sans qu'il soit nécessaire de modifier le code des applications.Entry ou Text) doivent souvent rester blanches avec du texte noir pour être lisibles, à moins que le système ne soit réglé sur un thème sombre pur (comme le thème "Ubuntu").THEMES avec ses propres couleurs, pour créer un environnement "Hacker", "Rose Poudré", ou un mode "Lecture de Nuit" (couleurs chaudes ambrées).import tkinter as tk
THEMES = {
"GrimOS": {
"bg": "lightgray",
"fg": "black",
"font": ("Arial", 10),
"btn_bg": "#e0e0e0",
"relief": "flat",
"desktop_bg": "gray",
"desktop_fg": "white",
"accent": "blue",
"title_bg": "darkblue",
"title_fg": "white",
"taskbar_bg": "#333333",
"taskbar_fg": "white",
"start_btn_bg": "blue",
"start_btn_fg": "white",
"panel_btn_bg": "#555555",
"window_border": "black",
"icon_theme": "grimos"
},
"Win 3.1": {
"bg": "white",
"fg": "black",
"font": ("System", 10, "bold"),
"btn_bg": "white",
"relief": "solid",
"desktop_bg": "#008080",
"desktop_fg": "black",
"accent": "black",
"title_bg": "white",
"title_fg": "black",
"taskbar_bg": "white",
"taskbar_fg": "black",
"start_btn_bg": "white",
"start_btn_fg": "black",
"panel_btn_bg": "white",
"window_border": "black",
"icon_theme": "win31"
},
"Win 98": {
"bg": "#C0C0C0",
"fg": "black",
"font": ("MS Sans Serif", 9),
"btn_bg": "#C0C0C0",
"relief": "raised",
"desktop_bg": "#008080",
"desktop_fg": "white",
"accent": "#000080",
"title_bg": "#000080",
"title_fg": "white",
"taskbar_bg": "#C0C0C0",
"taskbar_fg": "black",
"start_btn_bg": "#C0C0C0",
"start_btn_fg": "black",
"panel_btn_bg": "#C0C0C0",
"window_border": "#C0C0C0",
"icon_theme": "win98"
},
"Win XP": {
"bg": "#ECE9D8",
"fg": "black",
"font": ("Tahoma", 8),
"btn_bg": "#ECE9D8",
"relief": "raised",
"desktop_bg": "#004E98",
"desktop_fg": "white",
"accent": "#003399",
"title_bg": "#003399",
"title_fg": "white",
"taskbar_bg": "#245EDC",
"taskbar_fg": "white",
"start_btn_bg": "#3C8120",
"start_btn_fg": "white",
"panel_btn_bg": "#245EDC",
"window_border": "#003399",
"icon_theme": "winxp"
},
"MacOS Classic": {
"bg": "#E8E8E8",
"fg": "black",
"font": ("Geneva", 9),
"btn_bg": "#E8E8E8",
"relief": "raised",
"desktop_bg": "#4A7698",
"desktop_fg": "black",
"accent": "#4A7698",
"title_bg": "white",
"title_fg": "black",
"taskbar_bg": "white",
"taskbar_fg": "black",
"start_btn_bg": "white",
"start_btn_fg": "black",
"panel_btn_bg": "white",
"window_border": "black",
"icon_theme": "mac"
},
"Ubuntu": {
"bg": "#3c3b37",
"fg": "#dfdcd8",
"font": ("Ubuntu", 10),
"btn_bg": "#4e4d49",
"relief": "flat",
"desktop_bg": "#2c001e",
"desktop_fg": "white",
"accent": "#f07746",
"title_bg": "#333333",
"title_fg": "#dfdcd8",
"taskbar_bg": "#111111",
"taskbar_fg": "white",
"start_btn_bg": "#f07746",
"start_btn_fg": "white",
"panel_btn_bg": "#333333",
"window_border": "#333333",
"icon_theme": "ubuntu"
},
"Lubuntu": {
"bg": "#f0f0f0",
"fg": "#333333",
"font": ("Ubuntu", 10),
"btn_bg": "#00557f",
"relief": "flat",
"desktop_bg": "#1c3144",
"desktop_fg": "white",
"accent": "#00557f",
"title_bg": "#1c3144",
"title_fg": "white",
"taskbar_bg": "#1c3144",
"taskbar_fg": "white",
"start_btn_bg": "#00557f",
"start_btn_fg": "white",
"panel_btn_bg": "#00557f",
"window_border": "#1c3144",
"icon_theme": "lubuntu"
}
}
def apply_theme(root, theme_name):
theme = THEMES.get(theme_name, THEMES["GrimOS"])
# Configuration globale pour tous les futurs widgets
root.option_add("*background", theme["bg"])
root.option_add("*foreground", theme["fg"])
root.option_add("*font", theme["font"])
# Styles spécifiques
root.option_add("*Button.background", theme["btn_bg"])
root.option_add("*Button.relief", theme["relief"])
root.option_add("*Button.borderwidth", 2 if theme["relief"] == "raised" else 1)
# Pour les entrées de texte, on veut souvent du blanc sauf si c'est très sombre
if theme_name in ["Ubuntu"]:
root.option_add("*Entry.background", "#2b2a27")
root.option_add("*Entry.foreground", "white")
root.option_add("*Text.background", "#2b2a27")
root.option_add("*Text.foreground", "white")
else:
root.option_add("*Entry.background", "white")
root.option_add("*Entry.foreground", "black")
root.option_add("*Text.background", "white")
root.option_add("*Text.foreground", "black")
return theme