AIstudioProxyAPI / gui /theme.py
peijun1's picture
Deploy AI Studio Proxy API to Hugging Face Spaces
a5784e9
Raw
History Blame Contribute Delete
2.85 kB
"""
GUI Launcher Theme Manager
Handles light/dark mode switching with persistence.
"""
from typing import Callable, List, Literal
import customtkinter as ctk
# Type alias for appearance modes
AppearanceMode = Literal["dark", "light", "system"]
# Module-level state
_current_mode: AppearanceMode = "dark"
_on_change_callbacks: List[Callable[[AppearanceMode], None]] = []
def get_appearance_mode() -> AppearanceMode:
"""Get the current appearance mode."""
return _current_mode
def set_appearance_mode(mode: AppearanceMode) -> None:
"""
Set the appearance mode and apply it.
Args:
mode: One of "dark", "light", or "system"
"""
global _current_mode
if mode not in ("dark", "light", "system"):
mode = "dark" # Default fallback
_current_mode = mode
ctk.set_appearance_mode(mode)
# Notify listeners
for callback in _on_change_callbacks:
try:
callback(mode)
except Exception:
pass
def toggle_appearance_mode() -> AppearanceMode:
"""
Toggle between dark and light mode.
Returns:
The new appearance mode after toggle
"""
if _current_mode == "dark":
set_appearance_mode("light")
else:
set_appearance_mode("dark")
return _current_mode
def is_dark_mode() -> bool:
"""Check if currently in dark mode."""
if _current_mode == "system":
# Check actual system setting
return ctk.get_appearance_mode().lower() == "dark"
return _current_mode == "dark"
def on_theme_change(callback: Callable[[AppearanceMode], None]) -> None:
"""
Register a callback to be called when theme changes.
Args:
callback: Function that takes the new mode as argument
"""
if callback not in _on_change_callbacks:
_on_change_callbacks.append(callback)
def remove_theme_callback(callback: Callable[[AppearanceMode], None]) -> None:
"""Remove a previously registered callback."""
if callback in _on_change_callbacks:
_on_change_callbacks.remove(callback)
def get_mode_display_name(mode: AppearanceMode) -> str:
"""
Get a user-friendly display name for the mode.
Args:
mode: The appearance mode
Returns:
Display name with emoji
"""
names = {
"dark": "🌙 Dark",
"light": "☀️ Light",
"system": "💻 System",
}
return names.get(mode, mode)
def get_available_modes() -> List[AppearanceMode]:
"""Get list of available appearance modes."""
return ["dark", "light", "system"]
# Initialize with CustomTkinter's default
def init_theme(mode: AppearanceMode = "dark") -> None:
"""
Initialize the theme system.
Should be called once at application startup.
Args:
mode: Initial appearance mode
"""
set_appearance_mode(mode)