Interface_IA/app/core/theme_manager.py
2026-06-06 10:21:48 +02:00

332 lines
13 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 {{
background-color: transparent;
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: 2px solid {self.current_theme.get_color("border_color")};
border-radius: 8px;
padding: 5px;
font-size: 14px;
background-color: {self.current_theme.get_color("background_tertiary_color")};
color: {self.current_theme.get_color("text_color")};
}}
QLineEdit {{
border: 2px solid {self.current_theme.get_color("border_color")};
border-radius: 8px;
padding: 5px;
font-size: 14px;
background-color: {self.current_theme.get_color("background_tertiary_color")};
color: {self.current_theme.get_color("text_color")};
}}
QDateEdit {{
border: 2px solid {self.current_theme.get_color("border_color")};
padding: 5px;
border-radius: 8px;
font-size: 14px;
min-height: 30px;
}}
QDateEdit::drop-down {{
border: none;
background: transparent;
}}
QDateEdit:hover {{
border-color: {self.current_theme.get_color("primary_hover_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")};
}}
#table_combobox {{
border: 1px solid {self.current_theme.get_color("border_color")};
padding: 2px 5px;
border-radius: 4px;
font-size: 12px;
min-height: 20px;
max-height: 28px;
}}
#table_combobox::drop-down {{
border: none;
background: transparent;
}}
#table_combobox::down-arrow {{
image: none;
}}
#table_combobox QAbstractItemView {{
border-radius: 4px;
padding: 0px;
outline: none;
}}
#table_combobox QAbstractItemView::item {{
padding: 8px 10px;
margin: 0px;
min-height: 16px;
border: 1px solid {self.current_theme.get_color("border_color")};
border-radius: 4px;
}}
#table_combobox QAbstractItemView::item:hover {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
color: {self.current_theme.get_color("text_color")};
}}
#table_combobox QAbstractItemView::item:selected {{
color: {self.current_theme.get_color("text_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")};
}}
QSplitter::handle {{
background-color: {self.current_theme.get_color("border_color")};
}}
QScrollArea#chat_scroll {{
background-color: {self.current_theme.get_color("background_secondary_color")};
border: none;
}}
#messages_container {{
background-color: transparent;
}}
#button_container {{
background-color: {self.current_theme.get_color("background_color")};
border-right: 1px solid {self.current_theme.get_color("border_color")};
}}
QListWidget#chat_list {{
background-color: transparent;
border: none;
outline: none;
font-size: 13px;
color: {self.current_theme.get_color("text_color")};
}}
QListWidget#chat_list::item {{
padding: 10px 12px;
border-radius: 10px;
background-color: transparent;
margin: 1px 0;
}}
QListWidget#chat_list::item:selected {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
color: {self.current_theme.get_color("text_color")};
}}
QListWidget#chat_list::item:hover {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
}}
QListWidget#chat_list QLineEdit {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
color: {self.current_theme.get_color("text_color")};
border: none;
border-radius: 0;
padding: 0;
font-size: 13px;
selection-background-color: {self.current_theme.get_color("primary_color")};
}}
QPushButton#sidebar_new_btn {{
background-color: transparent;
color: {self.current_theme.get_color("text_color")};
border: 1px solid {self.current_theme.get_color("border_color")};
border-radius: 10px;
font-size: 13px;
padding: 10px;
}}
QPushButton#sidebar_new_btn:hover {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
}}
#greeting_label {{
font-size: 24px;
color: {self.current_theme.get_color("text_color")};
background-color: transparent;
padding: 20px;
}}
#chat_input_container {{
background-color: transparent;
}}
#chat_input_wrapper {{
background-color: {self.current_theme.get_color("background_tertiary_color")};
border: 2px solid {self.current_theme.get_color("border_color")};
border-radius: 24px;
}}
QTextEdit#chat_input_field {{
border: none;
background: transparent;
font-size: 14px;
color: {self.current_theme.get_color("text_color")};
selection-background-color: {self.current_theme.get_color("primary_color")};
}}
QPushButton#chat_send_btn {{
background-color: {self.current_theme.get_color("primary_color")};
color: #FFFFFF;
border: none;
border-radius: 19px;
font-size: 20px;
padding: 0;
}}
QPushButton#chat_send_btn:hover {{
background-color: {self.current_theme.get_color("primary_hover_color")};
}}
QPushButton#chat_send_btn:disabled {{
background-color: {self.current_theme.get_color("background_secondary_color")};
color: {self.current_theme.get_color("text_color")};
}}
QPushButton#chat_stop_btn {{
background-color: #FF453A;
color: #FFFFFF;
border: none;
border-radius: 19px;
font-size: 18px;
padding: 0;
}}
QPushButton#chat_stop_btn:hover {{
background-color: #FF6961;
}}
QFrame#chat_bubble {{
border-radius: 14px;
}}
#status_label {{
color: {self.current_theme.get_color("text_color")};
font-size: 12px;
background-color: transparent;
padding: 4px;
}}
#chat_stack {{
background-color: {self.current_theme.get_color("background_secondary_color")};
}}
"""