import app.utils.paths as paths import os, json from typing import List, Dict, Any, Optional class Theme: def __init__(self, name: str, colors: Dict[str, str]) -> None: self.name: str = name self.colors: Dict[str, str] = colors def get_color(self, element: str) -> str: return self.colors.get(element, "#FFFFFF") class ThemeManager: def __init__(self) -> None: theme_path: str = os.path.join(paths.get_data_dir(), "themes") self.themes: List[Theme] = [] for theme_file in os.listdir(theme_path): if theme_file.endswith(".json"): with open(os.path.join(theme_path, theme_file), 'r', encoding='utf-8') as f: theme_data: Dict[str, Any] = json.load(f) theme: Theme = Theme(theme_data["theme_name"], theme_data["colors"]) self.themes.append(theme) self.current_theme: Theme = self.themes[0] def set_theme(self, theme: str) -> None: if theme != self.current_theme.name: found_theme: Optional[Theme] = next((t for t in self.themes if t.name == theme), None) if found_theme: self.current_theme = found_theme def get_theme(self) -> Theme: return self.current_theme def get_themes(self) -> List[Theme]: return self.themes def get_sheet(self) -> str: return f""" QWidget {{ background-color: {self.current_theme.get_color("background_secondary_color")}; color: {self.current_theme.get_color("text_color")}; }} QLabel {{ color: {self.current_theme.get_color("text_color")}; font-size: 20px; }} QPushButton {{ background-color: {self.current_theme.get_color("primary_color")}; color: {self.current_theme.get_color("text_color")}; border-radius: 8px; font-size: 16px; padding: 10px 20px; border: none; }} QPushButton:hover {{ background-color: {self.current_theme.get_color("primary_hover_color")}; }} QProgressBar {{ border: 1px solid {self.current_theme.get_color("border_color")}; border-radius: 5px; background-color: {self.current_theme.get_color("background_secondary_color")}; text-align: center; color: {self.current_theme.get_color("text_color")}; }} QProgressBar::chunk {{ background-color: {self.current_theme.get_color("primary_color")}; border-radius: 3px; }} QTextEdit {{ border: 1px solid {self.current_theme.get_color("border_color")}; border-radius: 8px; padding: 10px; font-size: 14px; background-color: {self.current_theme.get_color("background_secondary_color")}; color: {self.current_theme.get_color("text_color")}; }} QComboBox {{ border: 2px solid {self.current_theme.get_color("border_color")}; padding: 5px; border-radius: 8px; font-size: 14px; min-height: 30px; }} QComboBox QAbstractItemView {{ border-radius: 8px; padding: 0px; outline: none; }} QComboBox QAbstractItemView::item {{ padding: 12px 15px; margin: 0px; min-height: 20px; border: 1px solid {self.current_theme.get_color("border_color")}; border-radius: 8px; }} QComboBox QAbstractItemView::item:hover {{ background-color: {self.current_theme.get_color("background_tertiary_color")}; color: {self.current_theme.get_color("text_color")}; }} QComboBox QAbstractItemView::item:selected {{ color: {self.current_theme.get_color("text_color")}; }} QComboBox::drop-down {{ border: none; background: transparent; }} QComboBox::down-arrow {{ image: none; }} QComboBox:hover {{ border-color: {self.current_theme.get_color("primary_hover_color")}; }} QSlider::groove:horizontal {{ border: 1px solid {self.current_theme.get_color("primary_color")}; height: 10px; background: transparent; border-radius: 5px; }} QSlider::sub-page:horizontal {{ background: {self.current_theme.get_color("primary_color")}; border-radius: 5px; }} QSlider::add-page:horizontal {{ background: {self.current_theme.get_color("background_tertiary_color")}; border-radius: 5px; }} QSlider::handle:horizontal {{ background: white; border: 2px solid {self.current_theme.get_color("primary_color")}; width: 14px; margin: -4px 0; border-radius: 7px; }} QScrollBar:vertical {{ border: none; background: {self.current_theme.get_color("background_tertiary_color")}; width: 8px; margin: 0px; }} QScrollBar::handle:vertical {{ background: {self.current_theme.get_color("primary_color")}; border-radius: 4px; min-height: 20px; }} QScrollBar::handle:vertical:hover {{ background: {self.current_theme.get_color("primary_hover_color")}; }} QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{ border: none; background: none; height: 0px; }} QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {{ background: none; }} #tab_bar {{ background-color: {self.current_theme.get_color("background_color")}; }} """