diff --git a/.data/history.txt b/.data/history.txt index dc6dece..0938bf3 100644 --- a/.data/history.txt +++ b/.data/history.txt @@ -1,19 +1 @@ - -salario=horas*tarifa -#salario=8000 -#tarifa=36 - -horas=? - - -plot(sin(x),(x,0,1)) - - - - - - - - - - +plot(sin(x), (x, 0, 1)) \ No newline at end of file diff --git a/app/gui_evaluation.py b/app/gui_evaluation.py index a4af69b..31d796b 100644 --- a/app/gui_evaluation.py +++ b/app/gui_evaluation.py @@ -40,7 +40,7 @@ class EvaluationManager: 'custom_type': self._create_format("#4ec9b0"), 'plot': self._create_format("#569cd6", underline=True), 'type_indicator': self._create_format("#808080"), - 'clickable': self._create_format("#4fc3f7", underline=True), + 'clickable': self._create_format("#4fc3f7", underline=True, bold=True), 'helper': self._create_format("#ffd700", italic=True) } @@ -254,6 +254,7 @@ class EvaluationManager: cursor.insertText(display_text, self.output_formats.get('clickable')) end_pos = cursor.position() self.main_window.output_text.clickable_links[(start_pos, end_pos)] = (link_id, result_object) + self.logger.debug(f"🔗 Link creado: {display_text} en posición {start_pos}-{end_pos}, ID: {link_id}") elif len(part_data) >= 2: tag, content = part_data[0], part_data[1] diff --git a/app/gui_main.py b/app/gui_main.py index e868336..c025385 100644 --- a/app/gui_main.py +++ b/app/gui_main.py @@ -293,6 +293,7 @@ class HybridCalculatorPySide6(QMainWindow): def _handle_output_link_click(self, link_id: str, result_object): """Maneja clicks en links del output""" + self.logger.debug(f"🖱️ Click en link recibido: {link_id}, objeto: {type(result_object).__name__}") # Delegar al evaluation manager self.evaluation_manager.handle_output_link_click(link_id, result_object) diff --git a/app/gui_popup.py b/app/gui_popup.py index 174305e..bc46d36 100644 --- a/app/gui_popup.py +++ b/app/gui_popup.py @@ -8,8 +8,13 @@ from PySide6.QtGui import QFont, QTextCursor, QTextCharFormat, QColor from PySide6.QtWebEngineWidgets import QWebEngineView import sympy from typing import Any, Optional, Dict, List, Tuple -import matplotlib.pyplot as plt -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg +try: + import matplotlib.pyplot as plt + from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg + MATPLOTLIB_AVAILABLE = True +except ImportError: + print("⚠️ Matplotlib no disponible - plots no funcionarán") + MATPLOTLIB_AVAILABLE = False import numpy as np @@ -127,12 +132,9 @@ class InteractiveResultManager(QWidget): def handle_interactive_click(self, result: Any, is_mathjax_click: bool = False): """Maneja clicks en elementos interactivos""" if isinstance(result, PlotResult): - if not is_mathjax_click: - # Primera vez: mostrar en MathJax - self.plot_requested.emit(result) - else: - # Click en MathJax: abrir ventana emergente - self._show_plot_window(result) + # Abrir ventana de plot directamente + print(f"🖱️ Abriendo ventana de plot para: {result.plot_type}") + self._show_plot_window(result) else: # Otros tipos siempre abren ventana self._handle_other_interactive_click(result) @@ -303,7 +305,18 @@ class InteractiveResultManager(QWidget): if not parent_frame.layout(): parent_frame.setLayout(QVBoxLayout()) + if not MATPLOTLIB_AVAILABLE: + error_label = QLabel("Matplotlib no está disponible.\nInstala con: pip install matplotlib") + error_label.setStyleSheet("color: #f44747; font-size: 12px;") + error_label.setWordWrap(True) + parent_frame.layout().addWidget(error_label) + return + + print(f"📊 Creando plot {plot_result.plot_type} con args: {plot_result.args}") + fig, ax = plt.subplots(figsize=(8, 6)) + fig.patch.set_facecolor('#1a1a1a') # Fondo oscuro + ax.set_facecolor('#1a1a1a') if plot_result.plot_type == "plot": self._create_2d_plot(fig, ax, plot_result.args, plot_result.kwargs) @@ -314,7 +327,13 @@ class InteractiveResultManager(QWidget): canvas = FigureCanvasQTAgg(fig) parent_frame.layout().addWidget(canvas) + print("✅ Plot creado exitosamente") + except Exception as e: + print(f"❌ Error creando plot: {e}") + import traceback + traceback.print_exc() + if not parent_frame.layout(): parent_frame.setLayout(QVBoxLayout()) diff --git a/app/gui_widgets.py b/app/gui_widgets.py index c36eea8..d03243e 100644 --- a/app/gui_widgets.py +++ b/app/gui_widgets.py @@ -41,6 +41,7 @@ class OutputTextEdit(QTextEdit): self.setReadOnly(True) self.setFont(QFont("Consolas", 11)) self.clickable_links = {} # {(start, end): (link_id, object)} + self.setMouseTracking(True) # Habilitar tracking del mouse def mousePressEvent(self, event): """Detecta clicks en links""" @@ -59,6 +60,26 @@ class OutputTextEdit(QTextEdit): return super().mousePressEvent(event) + + def mouseMoveEvent(self, event): + """Cambia el cursor cuando está sobre un link""" + cursor = self.cursorForPosition(event.pos()) + pos = cursor.position() + + # Verificar si el mouse está sobre un link + over_link = False + for (start, end), (link_id, obj) in self.clickable_links.items(): + if start <= pos <= end: + over_link = True + break + + # Cambiar cursor + if over_link: + self.setCursor(Qt.PointingHandCursor) + else: + self.setCursor(Qt.ArrowCursor) + + super().mouseMoveEvent(event) class ExpandableLatexButton(QPushButton):