HoDA_Radio/app/core/theme_manager.py
2025-09-21 20:13:54 +02:00

158 lines
6.3 KiB
Python

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")};
}}
"""