"""Pestaña de Configuración de la aplicación GUI.""" import customtkinter as ctk from gui.styles import AppStyles class SettingsTab: """Encapsula la UI de la pestaña Configuración.""" def __init__(self, parent_tab): """Inicializa la pestaña de Configuración. Args: parent_tab: El CTkFrame que representa la pestaña. """ self.tab = parent_tab self.fonts = AppStyles.get_fonts() self.colors = AppStyles.get_colors() self.spacing = AppStyles.get_spacing() self._setup_layout() self._create_api_section() self._create_processing_section() self._create_save_button() def _setup_layout(self): """Configura el layout base de la pestaña.""" self.tab.grid_columnconfigure(0, weight=1) self.tab.grid_rowconfigure(0, weight=1) self.settings_container = ctk.CTkFrame(self.tab, fg_color="transparent") self.settings_container.grid(row=0, column=0, sticky="nsew", padx=20, pady=20) self.settings_container.grid_columnconfigure(0, weight=1) def _create_api_section(self): """Crea la sección de configuración del modelo LLM.""" self.frame_api = ctk.CTkFrame(self.settings_container) self.frame_api.grid(row=0, column=0, sticky="ew", padx=5, pady=5) self.frame_api.grid_columnconfigure(1, weight=1) # Título lbl_api_title = ctk.CTkLabel( self.frame_api, text="Configuración del Modelo LLM", font=self.fonts["section"] ) lbl_api_title.grid(row=0, column=0, columnspan=2, sticky="w", padx=15, pady=10) # Selector de modelo lbl_model = ctk.CTkLabel( self.frame_api, text="Modelo (Ollama):", font=self.fonts["ui"] ) lbl_model.grid(row=1, column=0, padx=15, pady=10, sticky="w") self.combo_model = ctk.CTkComboBox( self.frame_api, values=["5.1", "4.1", "4.1 mini", "4.1 nano"], width=250, font=self.fonts["ui"] ) self.combo_model.grid(row=1, column=1, padx=15, pady=10, sticky="w") self.combo_model.set("4.1") # Texto de ayuda help_text = ( "ℹ 4.1 mini: Muy rápido (recomendado)\n" "ℹ 4.1: Estándar (balanceado)\n" "ℹ 5.1: Lento pero mayor razonamiento" ) lbl_help = ctk.CTkLabel( self.frame_api, text=help_text, font=self.fonts["italic_small"], text_color=self.colors["gray_light"], justify="left" ) lbl_help.grid(row=2, column=1, padx=15, pady=(0, 10), sticky="w") def _create_processing_section(self): """Crea la sección de procesamiento y rendimiento.""" self.frame_proc = ctk.CTkFrame(self.settings_container) self.frame_proc.grid(row=1, column=0, sticky="ew", padx=5, pady=5) self.frame_proc.grid_columnconfigure(1, weight=1) # Título lbl_proc_title = ctk.CTkLabel( self.frame_proc, text="Procesamiento y Rendimiento", font=self.fonts["section"] ) lbl_proc_title.grid(row=0, column=0, columnspan=2, sticky="w", padx=15, pady=10) # Límite de concurrencia lbl_conc = ctk.CTkLabel( self.frame_proc, text="Límite de Concurrencia:", font=self.fonts["ui"] ) lbl_conc.grid(row=1, column=0, padx=15, pady=10, sticky="w") self.concurrency_var = ctk.StringVar(value="100") self.concurrency_entry = ctk.CTkEntry( self.frame_proc, textvariable=self.concurrency_var, width=100, font=self.fonts["ui"] ) self.concurrency_entry.grid(row=1, column=1, padx=15, pady=10, sticky="w") # Advertencia warning_text = ( "⚠️ Advertencia: Entre mayor el número, mayor la probabilidad de Rate Limits (429)." ) lbl_conc_warn = ctk.CTkLabel( self.frame_proc, text=warning_text, font=self.fonts["italic_small"], text_color="orange" ) lbl_conc_warn.grid(row=2, column=0, columnspan=2, padx=15, pady=(0, 10), sticky="w") def _create_save_button(self): """Crea el botón de guardar configuración.""" self.btn_save_settings = ctk.CTkButton( self.settings_container, text="Aplicar Configuración", font=self.fonts["ui"], height=35 ) self.btn_save_settings.grid(row=2, column=0, padx=15, pady=15, sticky="ew") # --- API Pública --- def set_on_save(self, callback): """Vincula el callback al botón de guardar.""" self.btn_save_settings.configure(command=callback) def get_selected_model(self) -> str: """Devuelve el modelo seleccionado.""" return self.combo_model.get() def set_selected_model(self, model: str) -> None: """Establece el modelo seleccionado.""" self.combo_model.set(model) def get_concurrency_limit(self) -> int: """Devuelve el límite de concurrencia.""" try: return int(self.concurrency_var.get()) except Exception: return 20 def set_concurrency_limit(self, limit: int) -> None: """Establece el límite de concurrencia.""" self.concurrency_var.set(str(limit)) def enable_controls(self, enabled: bool): """Habilita o deshabilita los controles.""" state = "normal" if enabled else "disabled" self.combo_model.configure(state=state) self.concurrency_entry.configure(state=state) self.btn_save_settings.configure(state=state)