- 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
This commit is contained in:
Marius Stanciu 2019-09-24 15:47:33 +03:00
parent e042f6beed
commit 1ee7f9bf1e
3 changed files with 90 additions and 13 deletions

View File

@ -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

View File

@ -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."""

View File

@ -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