From 1eea99fde23a8f1d953b777e11c7775aacbf59f6 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 1 Jun 2025 19:09:36 +0200 Subject: [PATCH] Mejorado de la ventana de Plot --- hybrid_calc_settings.json | 2 +- interactive_results.py | 113 ++++++++++++++++++++++++++++++++------ main_launcher.py | 93 +------------------------------ 3 files changed, 98 insertions(+), 110 deletions(-) diff --git a/hybrid_calc_settings.json b/hybrid_calc_settings.json index 774a72f..6876a94 100644 --- a/hybrid_calc_settings.json +++ b/hybrid_calc_settings.json @@ -1,4 +1,4 @@ { - "window_geometry": "1000x700+175+111", + "window_geometry": "1000x700+127+123", "sash_pos_x": 339 } \ No newline at end of file diff --git a/interactive_results.py b/interactive_results.py index 745cb15..b1b9c57 100644 --- a/interactive_results.py +++ b/interactive_results.py @@ -136,11 +136,35 @@ class InteractiveResultManager: def _show_plot_window(self, plot_result: PlotResult, window_key: str): """Muestra ventana con plot matplotlib""" - window = self._create_base_window(f"Plot - {plot_result.plot_type}", "800x600") + # Asegurar que las dimensiones de la ventana principal estén actualizadas + self.parent.update_idletasks() + parent_x = self.parent.winfo_x() + parent_y = self.parent.winfo_y() + parent_width = self.parent.winfo_width() + parent_height = self.parent.winfo_height() + + # Definir dimensiones y posición para la ventana del plot + plot_window_width = 600 # Ancho deseado para la ventana del plot (puedes ajustarlo) + plot_window_height = parent_height # Misma altura que la ventana principal + + # Posicionar la ventana del plot a la derecha de la ventana principal + plot_window_x = parent_x + parent_width + plot_window_y = parent_y # Misma posición Y que la ventana principal + + window_title = f"Plot - {plot_result.plot_type}" + + # Crear la ventana base especificando la posición + window = self._create_base_window( + window_title, + width=plot_window_width, + height=plot_window_height, + pos_x=plot_window_x, + pos_y=plot_window_y + ) self.open_windows[window_key] = window try: - fig, ax = plt.subplots(figsize=(8, 6)) + fig, ax = plt.subplots(figsize=(8, 6)) # Tamaño de la figura interna del plot if plot_result.plot_type == "plot": self._create_2d_plot(fig, ax, plot_result.args, plot_result.kwargs) @@ -171,7 +195,7 @@ class InteractiveResultManager: error_label.pack(pady=20) print(f"❌ Error en plot: {e}") - + def _create_2d_plot(self, fig, ax, args, kwargs): """Crea plot 2D usando SymPy""" if len(args) >= 1: @@ -247,7 +271,23 @@ class InteractiveResultManager: def _show_matrix_window(self, matrix: sympy.Matrix, window_key: str): """Muestra ventana con matriz formateada""" rows, cols = matrix.shape - window = self._create_base_window(f"Matriz {rows}×{cols}", "600x400") + window_title = f"Matriz {rows}×{cols}" + + # Asegurar que las dimensiones de la ventana principal estén actualizadas + self.parent.update_idletasks() + parent_x = self.parent.winfo_x() + parent_y = self.parent.winfo_y() + parent_width = self.parent.winfo_width() + parent_height = self.parent.winfo_height() + + # Definir dimensiones y posición para la ventana de la matriz + matrix_window_width = 600 # Ancho deseado + matrix_window_height = parent_height # Misma altura que la ventana principal + matrix_window_x = parent_x + parent_width # A la derecha + matrix_window_y = parent_y # Misma posición Y + + window = self._create_base_window(window_title, width=matrix_window_width, height=matrix_window_height, + pos_x=matrix_window_x, pos_y=matrix_window_y) self.open_windows[window_key] = window # Crear frame con scroll @@ -332,7 +372,7 @@ class InteractiveResultManager: def _show_matrix_property(self, matrix: sympy.Matrix, prop_name: str, prop_value: Any): """Muestra propiedad de matriz en ventana separada""" - prop_window = self._create_base_window(f"Matriz - {prop_name.title()}", "400x300") + prop_window = self._create_base_window(f"Matriz - {prop_name.title()}", width=400, height=300) text_widget = scrolledtext.ScrolledText( prop_window, @@ -353,7 +393,23 @@ class InteractiveResultManager: def _show_list_window(self, lst: list, window_key: str): """Muestra ventana con lista expandida""" - window = self._create_base_window(f"Lista ({len(lst)} elementos)", "500x400") + window_title = f"Lista ({len(lst)} elementos)" + + # Asegurar que las dimensiones de la ventana principal estén actualizadas + self.parent.update_idletasks() + parent_x = self.parent.winfo_x() + parent_y = self.parent.winfo_y() + parent_width = self.parent.winfo_width() + parent_height = self.parent.winfo_height() + + # Definir dimensiones y posición para la ventana de la lista + list_window_width = 500 # Ancho deseado + list_window_height = parent_height # Misma altura que la ventana principal + list_window_x = parent_x + parent_width # A la derecha + list_window_y = parent_y # Misma posición Y + + window = self._create_base_window(window_title, width=list_window_width, height=list_window_height, + pos_x=list_window_x, pos_y=list_window_y) self.open_windows[window_key] = window text_widget = scrolledtext.ScrolledText( @@ -374,7 +430,7 @@ class InteractiveResultManager: def _show_dict_window(self, dct: dict, window_key: str): """Muestra ventana con diccionario expandido""" - window = self._create_base_window(f"Diccionario ({len(dct)} entradas)", "500x400") + window = self._create_base_window(f"Diccionario ({len(dct)} entradas)", width=500, height=400) self.open_windows[window_key] = window text_widget = scrolledtext.ScrolledText( @@ -395,7 +451,7 @@ class InteractiveResultManager: def _show_object_window(self, obj: Any, window_key: str): """Muestra ventana con detalles de objeto""" - window = self._create_base_window(f"Objeto - {type(obj).__name__}", "600x500") + window = self._create_base_window(f"Objeto - {type(obj).__name__}", width=600, height=500) self.open_windows[window_key] = window text_widget = scrolledtext.ScrolledText( @@ -424,22 +480,43 @@ class InteractiveResultManager: text_widget.insert("1.0", content) text_widget.config(state="disabled") - def _create_base_window(self, title: str, geometry: str = "500x400") -> Toplevel: - """Crea ventana base con estilo consistente""" + def _create_base_window(self, + title: str, + width: int = 500, + height: int = 400, + pos_x: Optional[int] = None, + pos_y: Optional[int] = None) -> Toplevel: + """Crea ventana base con estilo consistente y posición opcional""" window = Toplevel(self.parent) window.title(title) - window.geometry(geometry) window.configure(bg="#2b2b2b") - window.transient(self.parent) + window.transient(self.parent) # Hace que la ventana aparezca encima del padre - # Centrar ventana - window.update_idletasks() - x = (window.winfo_screenwidth() // 2) - (window.winfo_width() // 2) - y = (window.winfo_screenheight() // 2) - (window.winfo_height() // 2) - window.geometry(f"+{x}+{y}") + # Construir la cadena de geometría completa WxH+X+Y + geometry_str = f"{width}x{height}" + + if pos_x is not None and pos_y is not None: + # Usar posición provista, asegurándose de que no sea negativa + final_x = max(0, pos_x) + final_y = max(0, pos_y) + geometry_str += f"+{final_x}+{final_y}" + else: + # Centrar ventana si no se especifica posición + # Para centrar, necesitamos las dimensiones de la pantalla + # y las dimensiones de la ventana (width, height ya las tenemos) + screen_width = window.winfo_screenwidth() + screen_height = window.winfo_screenheight() + + center_x = (screen_width // 2) - (width // 2) + center_y = (screen_height // 2) - (height // 2) + final_x = max(0, center_x) + final_y = max(0, center_y) + geometry_str += f"+{final_x}+{final_y}" + + window.geometry(geometry_str) # Aplicar tamaño y posición de una sola vez return window - + def close_all_windows(self): """Cierra todas las ventanas interactivas""" for window in list(self.open_windows.values()): diff --git a/main_launcher.py b/main_launcher.py index 5da6b05..da7c843 100644 --- a/main_launcher.py +++ b/main_launcher.py @@ -411,91 +411,6 @@ def launch_application(): show_error_with_log_info(e, log_file, "Error durante la ejecución de la aplicación") -def show_startup_splash(): - """Muestra splash screen durante la carga""" - if not logger: - return # Skip splash si no hay logger - - try: - logger.info("Mostrando splash screen...") - - splash = tk.Tk() - splash.title("Calculadora MAV") - splash.geometry("400x200") - splash.configure(bg="#2b2b2b") - splash.resizable(False, False) - - # Centrar ventana - splash.update_idletasks() - x = (splash.winfo_screenwidth() // 2) - (splash.winfo_width() // 2) - y = (splash.winfo_screenheight() // 2) - (splash.winfo_height() // 2) - splash.geometry(f"+{x}+{y}") - - # Contenido del splash - title_label = tk.Label( - splash, - text="Calculadora MAV", - font=("Arial", 20, "bold"), - fg="#ffffff", - bg="#2b2b2b" - ) - title_label.pack(pady=20) - - subtitle_label = tk.Label( - splash, - text="CAS Híbrido", - font=("Arial", 14), - fg="#82aaff", - bg="#2b2b2b" - ) - subtitle_label.pack() - - status_label = tk.Label( - splash, - text="Cargando componentes...", - font=("Arial", 10), - fg="#c8c8c8", - bg="#2b2b2b" - ) - status_label.pack(pady=20) - - # Barra de progreso simple - progress_frame = tk.Frame(splash, bg="#2b2b2b") - progress_frame.pack(pady=10) - - progress_bar = tk.Canvas( - progress_frame, - width=300, - height=10, - bg="#1e1e1e", - highlightthickness=0 - ) - progress_bar.pack() - - # Animar barra de progreso - def animate_progress(): - for i in range(0, 301, 10): - progress_bar.delete("all") - progress_bar.create_rectangle( - 0, 0, i, 10, - fill="#4fc3f7", - outline="" - ) - splash.update() - splash.after(50) - - splash.after(100, animate_progress) - splash.after(2000, splash.destroy) - - logger.info("Splash screen mostrado correctamente") - splash.mainloop() - - except Exception as e: - # Si hay error con splash, continuar sin él - logger.warning(f"Error mostrando splash screen: {e}") - pass - - def main(): """Función principal del launcher""" global logger, log_file @@ -560,12 +475,8 @@ def main(): logger.info("✅ Todas las dependencias disponibles") - # Mostrar splash screen - if "--no-splash" not in sys.argv: - logger.info("Mostrando splash screen...") - show_startup_splash() - else: - logger.info("Splash screen omitido por argumento --no-splash") + # Splash screen eliminado + logger.info("Splash screen ha sido eliminado.") # Lanzar aplicación logger.info("Lanzando aplicación principal...")