202 lines
8.6 KiB
Python
202 lines
8.6 KiB
Python
# Módulo: vista/panel_lateral.py
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
from tkinter import messagebox
|
|
|
|
# --- Módulos de Lógica Existente ---
|
|
# Asumiendo que estos módulos existen en la estructura lógica del proyecto
|
|
from logica.controlador import accion_placeholder
|
|
from logica.T1.backup import accion_backup_t1
|
|
from logica.T1.runVScode import abrir_vscode
|
|
from logica.T1.openBrowser import navegar_a_url
|
|
from logica.T2.scraping import hacer_scraping
|
|
|
|
# --- Módulos de Vistas ---
|
|
# Importamos la clase RadioPanel, que contiene los controles de música (Play/Pause y Volumen).
|
|
from vista.central_panel.view_radio import RadioPanel
|
|
from vista.config import *
|
|
|
|
|
|
class PanelLateral(ttk.Frame):
|
|
"""
|
|
Panel lateral izquierdo de la aplicación.
|
|
Contiene la barra de entrada, botones de lógica (Extracción, Navegación, Backup)
|
|
y los controles de música esenciales.
|
|
"""
|
|
|
|
# Usamos la constante definida en vista/config.py
|
|
ANCHO_CARACTERES_FIJO = ANCHO_CARACTERES_PANEL_LATERAL
|
|
|
|
def __init__(self, parent, root, panel_central, *args, **kwargs):
|
|
super().__init__(parent, *args, **kwargs)
|
|
self.root = root
|
|
self.panel_central = panel_central
|
|
self.controles_musica = None
|
|
|
|
self.entrada_superior = None
|
|
|
|
self.configurar_estilos_locales(root)
|
|
|
|
# Configuración de Layout Principal
|
|
self.grid_rowconfigure(99, weight=1) # Permite que la Fila 99 se expanda
|
|
self.grid_columnconfigure(0, weight=1)
|
|
|
|
# Creación de Secciones
|
|
self.crear_barra_de_entrada() # Fila 0
|
|
self.crear_seccion_acciones() # Fila 1
|
|
self.crear_seccion_aplicaciones() # Fila 2
|
|
self.crear_seccion_batch() # Fila 3
|
|
|
|
# Separador y Espacio Expandible
|
|
ttk.Separator(self, orient='horizontal').grid(row=4, column=0, sticky="ew", pady=(10, 0))
|
|
tk.Frame(self, height=1).grid(row=99, column=0, sticky="nsew")
|
|
|
|
self.crear_controles_musica() # Fila 100
|
|
|
|
# -------------------------------------------------------------
|
|
# 🖼️ ESTRUCTURA Y WIDGETS
|
|
# -------------------------------------------------------------
|
|
|
|
def crear_barra_de_entrada(self):
|
|
"""Crea la entrada superior para URL/Scraping."""
|
|
frame_entrada = ttk.Frame(self, style='TFrame', padding="10 5 10 0")
|
|
frame_entrada.grid(row=0, column=0, sticky="ew")
|
|
|
|
self.entrada_superior = ttk.Entry(frame_entrada, width=self.ANCHO_CARACTERES_FIJO, style='Yellow.TEntry')
|
|
self.entrada_superior.pack(fill="x", ipady=3)
|
|
self.entrada_superior.bind('<Return>', self.manejar_navegacion)
|
|
|
|
def crear_seccion_acciones(self):
|
|
"""Crea los botones de Extracción/Navegación."""
|
|
acciones_extraccion = [
|
|
("Extraer Datos (Wikipedia)", self.manejar_extraccion_datos),
|
|
("Ir a la URL usando el navegador", self.manejar_navegacion),
|
|
("Buscar API Google", lambda: accion_placeholder("Buscar API Google"))
|
|
]
|
|
self._crear_bloque_botones(self, titulo="Extracción/Navegación", acciones=acciones_extraccion, grid_row=1)
|
|
|
|
def crear_seccion_aplicaciones(self):
|
|
"""Crea los botones de apertura de aplicaciones."""
|
|
app2_comando = self.manejar_inicio_carrera_t2
|
|
|
|
acciones_aplicaciones = [
|
|
("Visual Code", abrir_vscode),
|
|
("App2 (Carrera 🏁)", app2_comando),
|
|
("App3", lambda: accion_placeholder("App3"))
|
|
]
|
|
self._crear_bloque_botones(self, titulo="Aplicaciones", acciones=acciones_aplicaciones, grid_row=2)
|
|
|
|
def crear_seccion_batch(self):
|
|
"""Crea el botón de Copias de seguridad."""
|
|
acciones_batch = [
|
|
("Copias de seguridad", self.manejar_backup)
|
|
]
|
|
self._crear_bloque_botones(self, titulo="Procesos batch", acciones=acciones_batch, grid_row=3)
|
|
|
|
def crear_controles_musica(self):
|
|
"""Crea el área para alojar los controles de música/radio."""
|
|
frame_musica = ttk.Frame(self, style='TFrame', padding="15 10")
|
|
frame_musica.grid(row=100, column=0, sticky="ew")
|
|
frame_musica.grid_columnconfigure(0, weight=1)
|
|
|
|
# Instancia la clase RadioPanel, que ahora contiene solo Play/Pause y Volumen
|
|
self.controles_musica = RadioPanel(frame_musica, self.root)
|
|
self.controles_musica.grid(row=0, column=0, sticky="nsew")
|
|
|
|
frame_musica.grid_rowconfigure(0, weight=1)
|
|
|
|
# -------------------------------------------------------------
|
|
# ⏯️ MÉTODOS DE LÓGICA / CONTROL
|
|
# -------------------------------------------------------------
|
|
|
|
def manejar_extraccion_datos(self):
|
|
"""
|
|
Obtiene el término de búsqueda, realiza el scraping, y carga el resultado
|
|
en el módulo Navegador del Panel Central.
|
|
"""
|
|
termino_busqueda = self.entrada_superior.get().strip()
|
|
|
|
if not termino_busqueda:
|
|
messagebox.showwarning("⚠️ Entrada Vacía",
|
|
"Por favor, introduce un término de búsqueda para extraer datos.")
|
|
return
|
|
|
|
success, message, contenido = hacer_scraping(termino_busqueda)
|
|
|
|
if success:
|
|
messagebox.showinfo("✅ Extracción Exitosa", message)
|
|
|
|
if self.panel_central:
|
|
self.panel_central.cargar_contenido_web(f"Scraping: {termino_busqueda}", contenido)
|
|
else:
|
|
messagebox.showerror("Error", "No se puede visualizar el resultado: Panel Central no disponible.")
|
|
|
|
else:
|
|
messagebox.showerror("❌ Error de Extracción", message)
|
|
|
|
def manejar_inicio_carrera_t2(self):
|
|
"""
|
|
Llama al método 'manejar_inicio_carrera' del Panel Central.
|
|
"""
|
|
if self.panel_central:
|
|
print("Botón App2 presionado. Iniciando Carrera de Camellos en Panel Central...")
|
|
self.panel_central.manejar_inicio_carrera()
|
|
else:
|
|
messagebox.showerror("Error", "El Panel Central no está inicializado.")
|
|
|
|
def manejar_navegacion(self, event=None):
|
|
"""
|
|
Obtiene el texto de la entrada superior y llama a la función de navegación (abrir navegador externo).
|
|
"""
|
|
url = self.entrada_superior.get()
|
|
if navegar_a_url(url):
|
|
self.entrada_superior.delete(0, tk.END)
|
|
|
|
def manejar_backup(self):
|
|
"""Llama a la lógica de backup de T1 e informa al usuario del resultado."""
|
|
print("Iniciando proceso de Copia de Seguridad...")
|
|
success, message = accion_backup_t1()
|
|
|
|
if success:
|
|
messagebox.showinfo("✅ Backup Completado", message)
|
|
else:
|
|
messagebox.showerror("❌ Error en el Backup", message)
|
|
|
|
# -------------------------------------------------------------
|
|
# ⚙️ MÉTODOS HELPER
|
|
# -------------------------------------------------------------
|
|
|
|
def configurar_estilos_locales(self, parent):
|
|
"""Configura estilos para los widgets del panel lateral, usando constantes importadas."""
|
|
style = ttk.Style(parent)
|
|
|
|
style.configure('Yellow.TEntry', fieldbackground='#fff8e1', foreground=COLOR_TEXTO, padding=[5, 5],
|
|
relief='solid', borderwidth=1)
|
|
|
|
style.configure('Green.TButton', background=COLOR_EXITO, foreground=COLOR_BLANCO, font=FUENTE_NEGOCIOS,
|
|
relief='flat', padding=[10, 5])
|
|
style.map('Green.TButton', background=[('active', '#388E3C'), ('pressed', '#1B5E20')])
|
|
|
|
style.configure('Action.TButton', background=COLOR_ACCION, foreground=COLOR_BLANCO, font=FUENTE_NEGOCIOS,
|
|
relief='flat', padding=[10, 5])
|
|
style.map('Action.TButton', background=[('active', COLOR_ACCION_HOVER), ('pressed', COLOR_ACCION_PRESSED)])
|
|
|
|
style.configure('SmallAction.TButton', background=COLOR_ACCION, foreground=COLOR_BLANCO,
|
|
font=(FUENTE_FAMILIA, 9, 'bold'),
|
|
relief='flat', padding=[5, 3])
|
|
style.map('SmallAction.TButton', background=[('active', COLOR_ACCION_HOVER), ('pressed', COLOR_ACCION_PRESSED)])
|
|
|
|
def _crear_bloque_botones(self, parent_frame, titulo, acciones, grid_row):
|
|
"""Función helper para crear secciones de etiquetas y botones usando GRID."""
|
|
|
|
frame_seccion = ttk.Frame(parent_frame, style='TFrame', padding="10 0 10 5")
|
|
frame_seccion.grid(row=grid_row, column=0, sticky="ew")
|
|
|
|
if titulo:
|
|
frame_titulo = ttk.Frame(frame_seccion, style='TFrame')
|
|
frame_titulo.pack(fill="x", pady=(10, 0))
|
|
ttk.Label(frame_titulo, text=titulo, font=FUENTE_NEGOCIOS).pack(anchor="w", padx=5)
|
|
|
|
for texto_boton, comando in acciones:
|
|
ttk.Button(frame_seccion, text=texto_boton, command=comando, style='Green.TButton').pack(fill="x", pady=5) |