Преглед изворни кода

- fixed setup_ubuntu.sh to include the matplotlib package required by the Legacy (2D) graphic engine
- in legacy graphic engine, fixed issue where immediately after changing the mouse cursor snapping the mouse cursor shape was not updated
- in legacy graphic engine, fixed issue where while zooming the mouse cursor shape was not updated
- in legacy graphic engine, fixed issue where immediately after panning finished the mouse cursor shape was not updated

Marius Stanciu пре 6 година
родитељ
комит
1ee7f9bf1e
3 измењених фајлова са 90 додато и 13 уклоњено
  1. 4 0
      README.md
  2. 84 12
      flatcamGUI/PlotCanvasLegacy.py
  3. 2 1
      setup_ubuntu.sh

+ 4 - 0
README.md

@@ -12,6 +12,10 @@ CAD program, and create G-Code for Isolation routing.
 24.09.2019
 
 - fixed the fullscreen method to show the application window in fullscreen wherever the mouse pointer it is therefore on the screen we are working on; before it was showing always on the primary screen
+- fixed setup_ubuntu.sh to include the matplotlib package required by the Legacy (2D) graphic engine
+- in legacy graphic engine, fixed issue where immediately after changing the mouse cursor snapping the mouse cursor shape was not updated
+- in legacy graphic engine, fixed issue where while zooming the mouse cursor shape was not updated
+- in legacy graphic engine, fixed issue where immediately after panning finished the mouse cursor shape was not updated
 
 23.09.2019
 

+ 84 - 12
flatcamGUI/PlotCanvasLegacy.py

@@ -8,12 +8,13 @@
 ############################################################
 
 from PyQt5 import QtGui, QtCore, QtWidgets
+from PyQt5.QtCore import pyqtSignal
 
 # Prevent conflict with Qt5 and above.
 from matplotlib import use as mpl_use
 mpl_use("Qt5Agg")
 from matplotlib.figure import Figure
-from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
 from matplotlib.backends.backend_agg import FigureCanvasAgg
 from matplotlib.widgets import Cursor
 
@@ -26,6 +27,7 @@ from shapely.geometry import Polygon, LineString, LinearRing, Point, MultiPolygo
 import FlatCAMApp
 from copy import deepcopy
 import logging
+import traceback
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -113,6 +115,33 @@ class CanvasCache(QtCore.QObject):
     #     log.debug("A new object is available. Should plot it!")
 
 
+class FigureCanvas(FigureCanvasQTAgg):
+    """
+    Reimplemented this so I can emit a signal when the idle drawing is finished and display the mouse shape
+    """
+
+    idle_drawing_finished = pyqtSignal()
+
+    def __init__(self, figure):
+        super().__init__(figure=figure)
+
+    def _draw_idle(self):
+        if self.height() < 0 or self.width() < 0:
+            self._draw_pending = False
+        if not self._draw_pending:
+            return
+        try:
+            self.draw()
+        except Exception:
+            # Uncaught exceptions are fatal for PyQt5, so catch them instead.
+            traceback.print_exc()
+        finally:
+            self._draw_pending = False
+
+            # I reimplemented this class only to launch this signal
+            self.idle_drawing_finished.emit()
+
+
 class PlotCanvasLegacy(QtCore.QObject):
     """
     Class handling the plotting area in the application.
@@ -209,6 +238,9 @@ class PlotCanvasLegacy(QtCore.QObject):
         # signal if there is a doubleclick
         self.is_dblclk = False
 
+        # pay attention, this signal should be connected only after the self.canvas and self.mouse is declared
+        self.canvas.idle_drawing_finished.connect(lambda: self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1]))
+
     def graph_event_connect(self, event_name, callback):
         """
         Attach an event handler to the canvas through the Matplotlib interface.
@@ -256,9 +288,20 @@ class PlotCanvasLegacy(QtCore.QObject):
         #     c = MplCursor(axes=axes, color='black', linewidth=1)
 
         c = FakeCursor()
-
+        try:
+            c.mouse_state_updated.connect(self.clear_cursor)
+        except Exception as e:
+            print(str(e))
         return c
 
+    def clear_cursor(self, state):
+
+        if state is True:
+            self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
+        else:
+            self.canvas.restore_region(self.background)
+            self.canvas.blit(self.axes.bbox)
+
     def on_key_down(self, event):
         """
 
@@ -571,9 +614,12 @@ class PlotCanvasLegacy(QtCore.QObject):
             # Clear pan flag
             self.panning = False
 
+            # And update the cursor
+            self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
+
     def on_mouse_move(self, event):
         """
-        Mouse movement event hadler. Stores the coordinates. Updates view on pan.
+        Mouse movement event handler. Stores the coordinates. Updates view on pan.
 
         :param event: Contains information about the event.
         :return: None
@@ -591,23 +637,44 @@ class PlotCanvasLegacy(QtCore.QObject):
 
         # Update pan view on mouse move
         if self.panning is True:
-            # x_pan, y_pan = self.app.geo_editor.snap(event.xdata, event.ydata)
-            # self.app.app_cursor.set_data(event, (x_pan, y_pan))
             for a in self.pan_axes:
                 a.drag_pan(1, event.key, event.x, event.y)
 
+            # x_pan, y_pan = self.app.geo_editor.snap(event.xdata, event.ydata)
+            # self.draw_cursor(x_pos=x_pan, y_pos=y_pan)
+
             # Async re-draw (redraws only on thread idle state, uses timer on backend)
             self.canvas.draw_idle()
 
             # #### Temporary place-holder for cached update #####
             self.update_screen_request.emit([0, 0, 0, 0, 0])
 
-        x, y = self.app.geo_editor.snap(x, y)
-        if self.app.app_cursor.enabled is True:
-            # Pointer (snapped)
-            elements = self.axes.plot(x, y, 'k+', ms=40, mew=2, animated=True)
-            for el in elements:
-                self.axes.draw_artist(el)
+        self.draw_cursor(x_pos=x, y_pos=y)
+
+        # self.canvas.blit(self.axes.bbox)
+
+    def draw_cursor(self, x_pos, y_pos):
+        """
+        Draw a cursor at the mouse grid snapped position
+
+        :param x_pos: mouse x position
+        :param y_pos: mouse y position
+        :return:
+        """
+        # there is no point in drawing mouse cursor when panning as it jumps in a confusing way
+        if self.app.app_cursor.enabled is True and self.panning is False:
+            try:
+                x, y = self.app.geo_editor.snap(x_pos, y_pos)
+
+                # Pointer (snapped)
+                elements = self.axes.plot(x, y, 'k+', ms=40, mew=2, animated=True)
+                for el in elements:
+                    self.axes.draw_artist(el)
+            except Exception as e:
+                # this happen at app initialization since self.app.geo_editor does not exist yet
+                # I could reshuffle the object instantiating order but what's the point? I could crash something else
+                # and that's pythonic, too
+                pass
 
         self.canvas.blit(self.axes.bbox)
 
@@ -656,13 +723,17 @@ class PlotCanvasLegacy(QtCore.QObject):
         return width / xpx, height / ypx
 
 
-class FakeCursor:
+class FakeCursor(QtCore.QObject):
     """
     This is a fake cursor to ensure compatibility with the OpenGL engine (VisPy).
     This way I don't have to chane (disable) things related to the cursor all over when
     using the low performance Matplotlib 2D graphic engine.
     """
+
+    mouse_state_updated = pyqtSignal(bool)
+
     def __init__(self):
+        super().__init__()
         self._enabled = True
 
     @property
@@ -672,6 +743,7 @@ class FakeCursor:
     @enabled.setter
     def enabled(self, value):
         self._enabled = value
+        self.mouse_state_updated.emit(value)
 
     def set_data(self, pos, **kwargs):
         """Internal event handler to draw the cursor when the mouse moves."""

+ 2 - 1
setup_ubuntu.sh

@@ -29,4 +29,5 @@ pip3 install --upgrade freetype-py
 pip3 install --upgrade fontTools
 pip3 install --upgrade rasterio
 pip3 install --upgrade lxml
-pip3 install --upgrade ezdxf
+pip3 install --upgrade ezdxf
+pip3 install --upgrade matplotlib