import tkinter as tk from tkinter import simpledialog, messagebox from typing import Callable, List from ui import styles class ProfileBar(tk.Frame): """Barra superior con dropdown de perfiles y botones New/Rename/Delete.""" def __init__(self, parent, on_change: Callable[[str], None], **kwargs): super().__init__(parent, **kwargs) self._on_change = on_change tk.Label(self, text="Perfil:", font=styles.FONT_LABEL).pack(side="left", padx=(0, 4)) self._var = tk.StringVar() self._dropdown = tk.OptionMenu(self, self._var, "") self._dropdown.config(font=styles.FONT_LABEL, width=20) self._dropdown.pack(side="left", padx=4) tk.Button(self, text="New", font=styles.FONT_SMALL, command=self._new_profile).pack(side="left", padx=2) tk.Button(self, text="Rename", font=styles.FONT_SMALL, command=self._rename_profile).pack(side="left", padx=2) tk.Button(self, text="Delete", font=styles.FONT_SMALL, command=self._delete_profile).pack(side="left", padx=2) # Callbacks inyectados desde app.py self._cb_new: Callable[[str], bool] = lambda name: False self._cb_rename: Callable[[str, str], bool] = lambda old, new: False self._cb_delete: Callable[[str], bool] = lambda name: False # ------------------------------------------------------------------ # API pública # ------------------------------------------------------------------ def set_callbacks( self, on_new: Callable[[str], bool], on_rename: Callable[[str, str], bool], on_delete: Callable[[str], bool], ) -> None: self._cb_new = on_new self._cb_rename = on_rename self._cb_delete = on_delete def refresh(self, names: List[str], active: str) -> None: """Actualiza el dropdown con la lista de nombres de perfil.""" menu = self._dropdown["menu"] menu.delete(0, "end") for name in names: menu.add_command(label=name, command=lambda n=name: self._select(n)) self._var.set(active) def current(self) -> str: return self._var.get() # ------------------------------------------------------------------ # Acciones internas # ------------------------------------------------------------------ def _select(self, name: str) -> None: self._var.set(name) self._on_change(name) def _new_profile(self) -> None: name = simpledialog.askstring("Nuevo perfil", "Nombre del perfil:", parent=self) if not name: return name = name.strip() if not name: return if self._cb_new(name): self._on_change(name) else: messagebox.showerror("Error", f"Ya existe un perfil con el nombre '{name}'.") def _rename_profile(self) -> None: old = self._var.get() new = simpledialog.askstring("Renombrar perfil", f"Nuevo nombre para '{old}':", parent=self) if not new: return new = new.strip() if not new: return if not self._cb_rename(old, new): messagebox.showerror("Error", f"No se pudo renombrar el perfil.") def _delete_profile(self) -> None: name = self._var.get() if not messagebox.askyesno("Eliminar perfil", f"¿Eliminar el perfil '{name}'?"): return if not self._cb_delete(name): messagebox.showerror("Error", "No se puede eliminar el único perfil existente.")