Spaces:
Sleeping
Sleeping
| """Gerenciador de temas para a interface do usuário.""" | |
| from typing import Dict, Any | |
| from enum import Enum | |
| class ThemeType(Enum): | |
| """Tipos de tema disponíveis.""" | |
| LIGHT = "light" | |
| DARK = "dark" | |
| class ThemeManager: | |
| """Gerenciador de temas da aplicação.""" | |
| def __init__(self, default_theme: ThemeType = ThemeType.DARK): | |
| """Inicializa o gerenciador de temas. | |
| Args: | |
| default_theme: Tema padrão a ser usado | |
| """ | |
| self.current_theme = default_theme | |
| self._themes = { | |
| ThemeType.LIGHT: self._get_light_theme(), | |
| ThemeType.DARK: self._get_dark_theme() | |
| } | |
| def get_current_theme(self) -> Dict[str, Any]: | |
| """Retorna o tema atual. | |
| Returns: | |
| Dicionário com as configurações do tema atual | |
| """ | |
| return self._themes[self.current_theme] | |
| def set_theme(self, theme: ThemeType) -> None: | |
| """Define o tema atual. | |
| Args: | |
| theme: Tipo de tema a ser definido | |
| """ | |
| self.current_theme = theme | |
| def toggle_theme(self) -> ThemeType: | |
| """Alterna entre os temas disponíveis. | |
| Returns: | |
| O novo tema ativo | |
| """ | |
| if self.current_theme == ThemeType.LIGHT: | |
| self.current_theme = ThemeType.DARK | |
| else: | |
| self.current_theme = ThemeType.LIGHT | |
| return self.current_theme | |
| def _get_light_theme(self) -> Dict[str, Any]: | |
| """Configurações do tema claro. | |
| Returns: | |
| Dicionário com as configurações do tema claro | |
| """ | |
| return { | |
| 'name': 'light', | |
| 'colors': { | |
| 'primary': '#667eea', | |
| 'secondary': '#764ba2', | |
| 'background': '#ffffff', | |
| 'surface': '#f8f9fa', | |
| 'card_background': '#ffffff', | |
| 'text_primary': '#495057', | |
| 'text_secondary': '#6c757d', | |
| 'text_muted': '#adb5bd', | |
| 'border': '#dee2e6', | |
| 'success': '#28a745', | |
| 'success_background': '#d4edda', | |
| 'success_border': '#c3e6cb', | |
| 'success_text': '#155724', | |
| 'warning': '#ffc107', | |
| 'warning_background': '#fff3cd', | |
| 'warning_border': '#ffeaa7', | |
| 'warning_text': '#856404', | |
| 'error': '#dc3545', | |
| 'info': '#007bff', | |
| 'gradient_start': '#667eea', | |
| 'gradient_end': '#764ba2', | |
| 'shadow': 'rgba(0,0,0,0.1)', | |
| 'shadow_hover': 'rgba(0,0,0,0.2)' | |
| }, | |
| 'css_variables': { | |
| '--bg-primary': '#ffffff', | |
| '--bg-secondary': '#f8f9fa', | |
| '--bg': '#ffffff', | |
| '--surface': '#f8f9fa', | |
| '--text-primary': '#495057', | |
| '--text-secondary': '#6c757d', | |
| '--border-color': '#dee2e6', | |
| '--shadow': '0 2px 4px rgba(0,0,0,0.1)', | |
| '--gradient': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' | |
| } | |
| } | |
| def _get_dark_theme(self) -> Dict[str, Any]: | |
| """Configurações do tema escuro. | |
| Returns: | |
| Dicionário com as configurações do tema escuro | |
| """ | |
| return { | |
| 'name': 'dark', | |
| 'colors': { | |
| 'primary': '#4f46e5', | |
| 'secondary': '#7c3aed', | |
| 'background': '#0f172a', | |
| 'surface': '#1e293b', | |
| 'card_background': '#334155', | |
| 'text_primary': '#f1f5f9', | |
| 'text_secondary': '#cbd5e1', | |
| 'text_muted': '#94a3b8', | |
| 'border': '#475569', | |
| 'success': '#10b981', | |
| 'success_background': '#064e3b', | |
| 'success_border': '#065f46', | |
| 'success_text': '#34d399', | |
| 'warning': '#f59e0b', | |
| 'warning_background': '#451a03', | |
| 'warning_border': '#92400e', | |
| 'warning_text': '#fbbf24', | |
| 'error': '#ef4444', | |
| 'info': '#3b82f6', | |
| 'gradient_start': '#4f46e5', | |
| 'gradient_end': '#7c3aed', | |
| 'shadow': 'rgba(0,0,0,0.3)', | |
| 'shadow_hover': 'rgba(0,0,0,0.5)' | |
| }, | |
| 'css_variables': { | |
| '--bg-primary': '#0f172a', | |
| '--bg-secondary': '#1e293b', | |
| '--bg': '#0f172a', | |
| '--surface': '#1e293b', | |
| '--text-primary': '#f1f5f9', | |
| '--text-secondary': '#cbd5e1', | |
| '--border-color': '#475569', | |
| '--shadow': '0 4px 8px rgba(0,0,0,0.3)', | |
| '--gradient': 'linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%)' | |
| } | |
| } | |
| def get_css_variables(self) -> str: | |
| """Retorna as variáveis CSS do tema atual. | |
| Returns: | |
| String com as variáveis CSS formatadas | |
| """ | |
| theme = self.get_current_theme() | |
| variables = [] | |
| for var_name, var_value in theme['css_variables'].items(): | |
| variables.append(f" {var_name}: {var_value};") | |
| return ":root {\n" + "\n".join(variables) + "\n}" | |
| def get_custom_css(self) -> str: | |
| """Retorna o CSS customizado para o tema atual. | |
| Returns: | |
| String com o CSS customizado completo | |
| """ | |
| theme = self.get_current_theme() | |
| colors = theme['colors'] | |
| return f""" | |
| {self.get_css_variables()} | |
| /* Tema {theme['name'].title()} */ | |
| body {{ | |
| background-color: {colors['background']} !important; | |
| color: {colors['text_primary']} !important; | |
| }} | |
| body[data-theme="{theme['name']}"] {{ | |
| background-color: {colors['background']} !important; | |
| color: {colors['text_primary']} !important; | |
| }} | |
| .gradio-container {{ | |
| max-width: 1200px !important; | |
| margin: auto !important; | |
| background-color: {colors['background']} !important; | |
| color: {colors['text_primary']} !important; | |
| }} | |
| /* Botões */ | |
| .gr-button {{ | |
| transition: all 0.3s ease !important; | |
| background: {colors['gradient_start']} !important; | |
| border: none !important; | |
| color: white !important; | |
| border-radius: 8px !important; | |
| font-weight: 600 !important; | |
| }} | |
| .gr-button:hover {{ | |
| transform: translateY(-2px) !important; | |
| box-shadow: 0 8px 16px {colors['shadow_hover']} !important; | |
| background: {colors['gradient_end']} !important; | |
| }} | |
| /* Inputs e TextAreas */ | |
| .gr-textbox, .gr-number, .gr-dropdown {{ | |
| background-color: {colors['surface']} !important; | |
| border: 1px solid {colors['border']} !important; | |
| color: {colors['text_primary']} !important; | |
| border-radius: 8px !important; | |
| }} | |
| .gr-textbox textarea, .gr-textbox input {{ | |
| font-family: 'Courier New', monospace !important; | |
| background-color: {colors['surface']} !important; | |
| color: {colors['text_primary']} !important; | |
| border: none !important; | |
| }} | |
| /* Tabs */ | |
| .gr-tab-nav {{ | |
| background: {colors['surface']} !important; | |
| border-bottom: 1px solid {colors['border']} !important; | |
| }} | |
| .gr-tab-nav button {{ | |
| border-radius: 8px 8px 0 0 !important; | |
| background: {colors['card_background']} !important; | |
| color: {colors['text_primary']} !important; | |
| border: 1px solid {colors['border']} !important; | |
| border-bottom: none !important; | |
| }} | |
| .gr-tab-nav button.selected {{ | |
| background: {colors['primary']} !important; | |
| color: white !important; | |
| }} | |
| /* Cards e Containers */ | |
| .gr-panel, .gr-box {{ | |
| background-color: {colors['card_background']} !important; | |
| border: 1px solid {colors['border']} !important; | |
| border-radius: 12px !important; | |
| box-shadow: {colors['shadow']} !important; | |
| }} | |
| /* HTML Components */ | |
| .gr-html {{ | |
| background-color: transparent !important; | |
| }} | |
| /* JSON Viewer */ | |
| .gr-json {{ | |
| background-color: {colors['surface']} !important; | |
| border: 1px solid {colors['border']} !important; | |
| border-radius: 8px !important; | |
| color: {colors['text_primary']} !important; | |
| }} | |
| /* Scrollbars */ | |
| ::-webkit-scrollbar {{ | |
| width: 8px; | |
| height: 8px; | |
| }} | |
| ::-webkit-scrollbar-track {{ | |
| background: {colors['surface']}; | |
| border-radius: 4px; | |
| }} | |
| ::-webkit-scrollbar-thumb {{ | |
| background: {colors['border']}; | |
| border-radius: 4px; | |
| }} | |
| ::-webkit-scrollbar-thumb:hover {{ | |
| background: {colors['text_muted']}; | |
| }} | |
| /* Animações */ | |
| * {{ | |
| transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease !important; | |
| }} | |
| /* Loading Spinner */ | |
| .loading {{ | |
| border: 3px solid {colors['border']}; | |
| border-top: 3px solid {colors['primary']}; | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| }} | |
| @keyframes spin {{ | |
| 0% {{ transform: rotate(0deg); }} | |
| 100% {{ transform: rotate(360deg); }} | |
| }} | |
| """ | |
| # Instância global do gerenciador de temas | |
| theme_manager = ThemeManager(ThemeType.DARK) |