Merged marius_stanciu/flatcam_beta/Beta_8.993 into Beta
This commit is contained in:
commit
1b8ed46f91
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -7,6 +7,16 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
11.05.2020
|
||||
|
||||
- removed the labels in status bar that display X,Y positions and replaced it with a HUD display on canvas (combo key SHIFT+H) will toggle the display of the HUD
|
||||
- made the HUD work in Legacy2D mode
|
||||
- fixed situation when the mouse cursor is outside of the canvas and no therefore returning None values
|
||||
|
||||
10.05.2020
|
||||
|
||||
- fixed the problem with using comma as decimal separator in Grid Snap fields
|
||||
|
||||
9.05.2020
|
||||
|
||||
- modified the GUI for Exclusion areas; now the shapes are displayed in a Table where they can be selected and deleted. Modification applied for Geometry Objects only (for now).
|
||||
|
|
|
@ -285,6 +285,8 @@ class App(QtCore.QObject):
|
|||
:rtype: App
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
App.log.info("FlatCAM Starting...")
|
||||
|
||||
self.main_thread = QtWidgets.QApplication.instance().thread()
|
||||
|
@ -504,8 +506,6 @@ class App(QtCore.QObject):
|
|||
self.FC_light_blue = '#a5a5ffbf'
|
||||
self.FC_dark_blue = '#0000ffbf'
|
||||
|
||||
QtCore.QObject.__init__(self)
|
||||
|
||||
self.ui = FlatCAMGUI(self)
|
||||
|
||||
theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
|
||||
|
@ -5378,14 +5378,20 @@ class App(QtCore.QObject):
|
|||
edge_width=self.defaults["global_cursor_width"],
|
||||
size=self.defaults["global_cursor_size"])
|
||||
|
||||
# Set the position label
|
||||
self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (location[0], location[1]))
|
||||
# Set the relative position label
|
||||
dx = location[0] - float(self.rel_point1[0])
|
||||
dy = location[1] - float(self.rel_point1[1])
|
||||
self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (dx, dy))
|
||||
# self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (location[0], location[1]))
|
||||
# # Set the position label
|
||||
#
|
||||
# self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (dx, dy))
|
||||
|
||||
units = self.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
dx, units, dy, units, location[0], units, location[1], units)
|
||||
|
||||
self.inform.emit('[success] %s' % _("Done."))
|
||||
return location
|
||||
|
@ -5527,14 +5533,19 @@ class App(QtCore.QObject):
|
|||
edge_width=self.defaults["global_cursor_width"],
|
||||
size=self.defaults["global_cursor_size"])
|
||||
|
||||
# Set the position label
|
||||
self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (location[0], location[1]))
|
||||
# Set the relative position label
|
||||
self.dx = location[0] - float(self.rel_point1[0])
|
||||
self.dy = location[1] - float(self.rel_point1[1])
|
||||
self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.dx, self.dy))
|
||||
# Set the position label
|
||||
# self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (location[0], location[1]))
|
||||
# self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.dx, self.dy))
|
||||
|
||||
units = self.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.dx, units, self.dy, units, location[0], units, location[1], units)
|
||||
|
||||
self.inform.emit('[success] %s' % _("Done."))
|
||||
return location
|
||||
|
@ -5843,8 +5854,8 @@ class App(QtCore.QObject):
|
|||
self.ui.plot_tab_area.addTab(self.ui.preferences_tab, _("Preferences"))
|
||||
|
||||
# delete the absolute and relative position and messages in the infobar
|
||||
self.ui.position_label.setText("")
|
||||
self.ui.rel_position_label.setText("")
|
||||
# self.ui.position_label.setText("")
|
||||
# self.ui.rel_position_label.setText("")
|
||||
|
||||
# Switch plot_area to preferences page
|
||||
self.ui.plot_tab_area.setCurrentWidget(self.ui.preferences_tab)
|
||||
|
@ -6738,6 +6749,9 @@ class App(QtCore.QObject):
|
|||
try: # May fail in case mouse not within axes
|
||||
pos_canvas = self.plotcanvas.translate_coords(event_pos)
|
||||
|
||||
if pos_canvas[0] is None or pos_canvas[1] is None:
|
||||
return
|
||||
|
||||
if self.grid_status():
|
||||
pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1])
|
||||
|
||||
|
@ -6749,13 +6763,19 @@ class App(QtCore.QObject):
|
|||
else:
|
||||
pos = (pos_canvas[0], pos_canvas[1])
|
||||
|
||||
self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (pos[0], pos[1]))
|
||||
|
||||
self.dx = pos[0] - float(self.rel_point1[0])
|
||||
self.dy = pos[1] - float(self.rel_point1[1])
|
||||
self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.dx, self.dy))
|
||||
|
||||
# self.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (pos[0], pos[1]))
|
||||
# self.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.dx, self.dy))
|
||||
|
||||
units = self.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.dx, units, self.dy, units, pos[0], units, pos[1], units)
|
||||
|
||||
self.mouse = [pos[0], pos[1]]
|
||||
|
||||
# if the mouse is moved and the LMB is clicked then the action is a selection
|
||||
|
@ -6804,9 +6824,10 @@ class App(QtCore.QObject):
|
|||
# In this case poly_obj creation (see above) will fail
|
||||
pass
|
||||
|
||||
except Exception:
|
||||
self.ui.position_label.setText("")
|
||||
self.ui.rel_position_label.setText("")
|
||||
except Exception as e:
|
||||
log.debug("App.on_mouse_move_over_plot() - rel_point1 is not None -> %s" % str(e))
|
||||
# self.ui.position_label.setText("")
|
||||
# self.ui.rel_position_label.setText("")
|
||||
self.mouse = None
|
||||
|
||||
def on_mouse_click_release_over_plot(self, event):
|
||||
|
|
|
@ -466,15 +466,20 @@ class ExclusionAreas(QtCore.QObject):
|
|||
size=self.app.defaults["global_cursor_size"])
|
||||
|
||||
# update the positions on status bar
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
if self.cursor_pos is None:
|
||||
self.cursor_pos = (0, 0)
|
||||
|
||||
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
|
||||
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.app.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
|
||||
|
||||
if self.obj_type == 'excellon':
|
||||
color = "#FF7400"
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
from PyQt5.QtGui import QPalette
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
import vispy.scene as scene
|
||||
from vispy.scene.visuals import Rectangle, Text
|
||||
from vispy.color import Color
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
class VisPyCanvas(scene.SceneCanvas):
|
||||
|
||||
def __init__(self, config=None):
|
||||
super().__init__(config=config, keys=None)
|
||||
|
||||
self.unfreeze()
|
||||
|
||||
# Colors used by the Scene
|
||||
theme_color = Color('#FFFFFF')
|
||||
tick_color = Color('#000000')
|
||||
back_color = str(QPalette().color(QPalette.Window).name())
|
||||
|
||||
# Central Widget Colors
|
||||
self.central_widget.bgcolor = back_color
|
||||
self.central_widget.border_color = back_color
|
||||
|
||||
self.grid_widget = self.central_widget.add_grid(margin=10)
|
||||
self.grid_widget.spacing = 0
|
||||
|
||||
# TOP Padding
|
||||
top_padding = self.grid_widget.add_widget(row=0, col=0, col_span=2)
|
||||
top_padding.height_max = 0
|
||||
|
||||
# RIGHT Padding
|
||||
right_padding = self.grid_widget.add_widget(row=0, col=2, row_span=2)
|
||||
right_padding.width_max = 0
|
||||
|
||||
# X Axis
|
||||
self.xaxis = scene.AxisWidget(
|
||||
orientation='bottom', axis_color=tick_color, text_color=tick_color,
|
||||
font_size=8, axis_width=1,
|
||||
anchors=['center', 'bottom']
|
||||
)
|
||||
self.xaxis.height_max = 30
|
||||
self.grid_widget.add_widget(self.xaxis, row=2, col=1)
|
||||
|
||||
# Y Axis
|
||||
self.yaxis = scene.AxisWidget(
|
||||
orientation='left', axis_color=tick_color, text_color=tick_color,
|
||||
font_size=8, axis_width=1
|
||||
)
|
||||
self.yaxis.width_max = 55
|
||||
self.grid_widget.add_widget(self.yaxis, row=1, col=0)
|
||||
|
||||
# View & Camera
|
||||
self.view = self.grid_widget.add_view(row=1, col=1, border_color=tick_color,
|
||||
bgcolor=theme_color)
|
||||
self.view.camera = scene.PanZoomCamera(aspect=1, rect=(-25, -25, 150, 150))
|
||||
|
||||
self.xaxis.link_view(self.view)
|
||||
self.yaxis.link_view(self.view)
|
||||
|
||||
self.grid = scene.GridLines(parent=self.view.scene, color='dimgray')
|
||||
self.grid.set_gl_state(depth_test=False)
|
||||
|
||||
self.rect = Rectangle(center=(65,30), color=Color('#0000FF10'), border_color=Color('#0000FF10'),
|
||||
width=120, height=50, radius=[5, 5, 5, 5], parent=self.view)
|
||||
self.rect.set_gl_state(depth_test=False)
|
||||
|
||||
self.text = Text('', parent=self.view, color='black', pos=(5, 30), method='gpu', anchor_x='left')
|
||||
self.text.font_size = 8
|
||||
self.text.text = 'Coordinates:\nX: %s\nY: %s' % ('0.0000', '0.0000')
|
||||
|
||||
self.freeze()
|
||||
|
||||
# self.measure_fps()
|
||||
|
||||
|
||||
class PlotCanvas(QtCore.QObject):
|
||||
|
||||
def __init__(self, container, my_app):
|
||||
"""
|
||||
The constructor configures the VisPy figure that
|
||||
will contain all plots, creates the base axes and connects
|
||||
events to the plotting area.
|
||||
|
||||
:param container: The parent container in which to draw plots.
|
||||
:rtype: PlotCanvas
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
# VisPyCanvas instance
|
||||
self.vispy_canvas = VisPyCanvas()
|
||||
|
||||
self.vispy_canvas.unfreeze()
|
||||
|
||||
self.my_app = my_app
|
||||
|
||||
# Parent container
|
||||
self.container = container
|
||||
|
||||
# <VisPyCanvas>
|
||||
self.vispy_canvas.create_native()
|
||||
self.vispy_canvas.native.setParent(self.my_app.ui)
|
||||
|
||||
# <QtCore.QObject>
|
||||
self.container.addWidget(self.vispy_canvas.native)
|
||||
|
||||
# add two Infinite Lines to act as markers for the X,Y axis
|
||||
self.v_line = scene.visuals.InfiniteLine(
|
||||
pos=0, color=(0.0, 0.0, 1.0, 0.3), vertical=True,
|
||||
parent=self.vispy_canvas.view.scene)
|
||||
|
||||
self.h_line = scene.visuals.InfiniteLine(
|
||||
pos=0, color=(0.00, 0.0, 1.0, 0.3), vertical=False,
|
||||
parent=self.vispy_canvas.view.scene)
|
||||
|
||||
self.vispy_canvas.freeze()
|
||||
|
||||
def event_connect(self, event, callback):
|
||||
getattr(self.vispy_canvas.events, event).connect(callback)
|
||||
|
||||
def event_disconnect(self, event, callback):
|
||||
getattr(self.vispy_canvas.events, event).disconnect(callback)
|
||||
|
||||
def translate_coords(self, pos):
|
||||
"""
|
||||
Translate pixels to canvas units.
|
||||
"""
|
||||
tr = self.vispy_canvas.grid.get_transform('canvas', 'visual')
|
||||
return tr.map(pos)
|
||||
|
||||
|
||||
class MyGui(QtWidgets.QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowTitle("VisPy Test")
|
||||
|
||||
# add Menubar
|
||||
self.menu = self.menuBar()
|
||||
self.menufile = self.menu.addMenu("File")
|
||||
self.menuedit = self.menu.addMenu("Edit")
|
||||
self.menufhelp = self.menu.addMenu("Help")
|
||||
|
||||
# add a Toolbar
|
||||
self.file_toolbar = QtWidgets.QToolBar("File Toolbar")
|
||||
self.addToolBar(self.file_toolbar)
|
||||
self.button = self.file_toolbar.addAction("Open")
|
||||
|
||||
# add Central Widget
|
||||
self.c_widget = QtWidgets.QWidget()
|
||||
self.central_layout = QtWidgets.QVBoxLayout()
|
||||
self.c_widget.setLayout(self.central_layout)
|
||||
self.setCentralWidget(self.c_widget)
|
||||
|
||||
# add InfoBar
|
||||
# self.infobar = self.statusBar()
|
||||
# self.position_label = QtWidgets.QLabel("Position: X: 0.0000\tY: 0.0000")
|
||||
# self.infobar.addWidget(self.position_label)
|
||||
|
||||
|
||||
class MyApp(QtCore.QObject):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.ui = MyGui()
|
||||
self.plot = PlotCanvas(container=self.ui.central_layout, my_app=self)
|
||||
|
||||
self.ui.show()
|
||||
|
||||
self.plot.event_connect(event="mouse_move", callback=self.on_mouse_move)
|
||||
|
||||
def on_mouse_move(self, event):
|
||||
cursor_pos = event.pos
|
||||
|
||||
pos_canvas = self.plot.translate_coords(cursor_pos)
|
||||
|
||||
# we don't need all the info in the tuple returned by the translate_coords()
|
||||
# only first 2 elements
|
||||
pos_canvas = [pos_canvas[0], pos_canvas[1]]
|
||||
# self.ui.position_label.setText("Position: X: %.4f\tY: %.4f" % (pos_canvas[0], pos_canvas[1]))
|
||||
# pos_text = 'Coordinates: \nX: {:<7.4f}\nY: {:<7.4f}'.format(pos_canvas[0], pos_canvas[1])
|
||||
pos_text = 'Coordinates: \nX: {:<.4f}\nY: {:<.4f}'.format(pos_canvas[0], pos_canvas[1])
|
||||
self.plot.vispy_canvas.text.text = pos_text
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
|
||||
m_app = MyApp()
|
||||
sys.exit(app.exec_())
|
|
@ -43,6 +43,7 @@ class FlatCAMDefaults:
|
|||
|
||||
# General
|
||||
"global_graphic_engine": '3D',
|
||||
"global_hud": True,
|
||||
"global_app_level": 'b',
|
||||
"global_portable": False,
|
||||
"global_language": 'English',
|
||||
|
|
|
@ -3801,18 +3801,22 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.snap_x = x
|
||||
self.snap_y = y
|
||||
|
||||
# update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (x, y))
|
||||
|
||||
if self.pos is None:
|
||||
self.pos = (0, 0)
|
||||
self.app.dx = x - self.pos[0]
|
||||
self.app.dy = y - self.pos[1]
|
||||
|
||||
# update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
# # update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (x, y))
|
||||
# # update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, x, units, y, units)
|
||||
|
||||
# ## Utility geometry (animated)
|
||||
self.update_utility_geometry(data=(x, y))
|
||||
|
|
|
@ -3467,22 +3467,32 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
:return:
|
||||
"""
|
||||
try:
|
||||
self.options[opt] = float(entry.text())
|
||||
text_value = entry.text()
|
||||
if ',' in text_value:
|
||||
text_value = text_value.replace(',', '.')
|
||||
self.options[opt] = float(text_value)
|
||||
except Exception as e:
|
||||
entry.set_value(self.app.defaults[opt])
|
||||
log.debug("FlatCAMGeoEditor.__init__().entry2option() --> %s" % str(e))
|
||||
return
|
||||
|
||||
def gridx_changed(goption, gentry):
|
||||
def grid_changed(goption, gentry):
|
||||
"""
|
||||
|
||||
:param goption: String. Can be either 'global_gridx' or 'global_gridy'
|
||||
:param gentry: A GUI element which text value is read and used
|
||||
:param goption: String. Can be either 'global_gridx' or 'global_gridy'
|
||||
:param gentry: A GUI element which text value is read and used
|
||||
:return:
|
||||
"""
|
||||
if goption not in ['global_gridx', 'global_gridy']:
|
||||
return
|
||||
|
||||
entry2option(opt=goption, entry=gentry)
|
||||
# if the grid link is checked copy the value in the GridX field to GridY
|
||||
try:
|
||||
val = float(gentry.get_value())
|
||||
text_value = gentry.text()
|
||||
if ',' in text_value:
|
||||
text_value = text_value.replace(',', '.')
|
||||
val = float(text_value)
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
|
@ -3491,7 +3501,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
|
||||
self.app.ui.grid_gap_x_entry.setValidator(QtGui.QDoubleValidator())
|
||||
self.app.ui.grid_gap_x_entry.textChanged.connect(
|
||||
lambda: gridx_changed("global_gridx", self.app.ui.grid_gap_x_entry))
|
||||
lambda: grid_changed("global_gridx", self.app.ui.grid_gap_x_entry))
|
||||
|
||||
self.app.ui.grid_gap_y_entry.setValidator(QtGui.QDoubleValidator())
|
||||
self.app.ui.grid_gap_y_entry.textChanged.connect(
|
||||
|
@ -4261,18 +4271,23 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
self.snap_y = y
|
||||
self.app.mouse = [x, y]
|
||||
|
||||
# update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (x, y))
|
||||
|
||||
if self.pos is None:
|
||||
self.pos = (0, 0)
|
||||
self.app.dx = x - self.pos[0]
|
||||
self.app.dy = y - self.pos[1]
|
||||
|
||||
# update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
# # update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (x, y))
|
||||
#
|
||||
# # update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, x, units, y, units)
|
||||
|
||||
if event.button == 1 and event_is_dragging and isinstance(self.active_tool, FCEraser):
|
||||
pass
|
||||
|
|
|
@ -4774,18 +4774,23 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
|
||||
self.app.mouse = [x, y]
|
||||
|
||||
# update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (x, y))
|
||||
|
||||
if self.pos is None:
|
||||
self.pos = (0, 0)
|
||||
self.app.dx = x - self.pos[0]
|
||||
self.app.dy = y - self.pos[1]
|
||||
|
||||
# update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
# # update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (x, y))
|
||||
#
|
||||
# # update the reference position label in the infobar since the APP mouse event handlers are disconnected
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, x, units, y, units)
|
||||
|
||||
self.update_utility_geometry(data=(x, y))
|
||||
|
||||
|
|
|
@ -2306,17 +2306,17 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
self.snap_infobar_label.setPixmap(QtGui.QPixmap(self.app.resource_location + '/snap_16.png'))
|
||||
self.infobar.addWidget(self.snap_infobar_label)
|
||||
|
||||
self.rel_position_label = QtWidgets.QLabel(
|
||||
"<b>Dx</b>: 0.0000 <b>Dy</b>: 0.0000 ")
|
||||
self.rel_position_label.setMinimumWidth(110)
|
||||
self.rel_position_label.setToolTip(_("Relative measurement.\nReference is last click position"))
|
||||
self.infobar.addWidget(self.rel_position_label)
|
||||
|
||||
self.position_label = QtWidgets.QLabel(
|
||||
" <b>X</b>: 0.0000 <b>Y</b>: 0.0000")
|
||||
self.position_label.setMinimumWidth(110)
|
||||
self.position_label.setToolTip(_("Absolute measurement.\nReference is (X=0, Y= 0) position"))
|
||||
self.infobar.addWidget(self.position_label)
|
||||
# self.rel_position_label = QtWidgets.QLabel(
|
||||
# "<b>Dx</b>: 0.0000 <b>Dy</b>: 0.0000 ")
|
||||
# self.rel_position_label.setMinimumWidth(110)
|
||||
# self.rel_position_label.setToolTip(_("Relative measurement.\nReference is last click position"))
|
||||
# self.infobar.addWidget(self.rel_position_label)
|
||||
#
|
||||
# self.position_label = QtWidgets.QLabel(
|
||||
# " <b>X</b>: 0.0000 <b>Y</b>: 0.0000")
|
||||
# self.position_label.setMinimumWidth(110)
|
||||
# self.position_label.setToolTip(_("Absolute measurement.\nReference is (X=0, Y= 0) position"))
|
||||
# self.infobar.addWidget(self.position_label)
|
||||
|
||||
self.units_label = QtWidgets.QLabel("[in]")
|
||||
self.units_label.setMargin(2)
|
||||
|
@ -2993,6 +2993,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
if key == QtCore.Qt.Key_G:
|
||||
self.app.on_toggle_axis()
|
||||
|
||||
# Toggle HUD (Heads-Up Display)
|
||||
if key == QtCore.Qt.Key_H:
|
||||
state = False if self.app.plotcanvas.hud_enabled else True
|
||||
self.app.plotcanvas.on_toggle_hud(state=state)
|
||||
|
||||
# Locate in Object
|
||||
if key == QtCore.Qt.Key_J:
|
||||
self.app.on_locate(obj=self.app.collection.get_active())
|
||||
|
|
|
@ -10,7 +10,7 @@ from PyQt5 import QtCore
|
|||
import logging
|
||||
from flatcamGUI.VisPyCanvas import VisPyCanvas, Color
|
||||
from flatcamGUI.VisPyVisuals import ShapeGroup, ShapeCollection, TextCollection, TextGroup, Cursor
|
||||
from vispy.scene.visuals import InfiniteLine, Line
|
||||
from vispy.scene.visuals import InfiniteLine, Line, Rectangle, Text
|
||||
|
||||
import numpy as np
|
||||
from vispy.geometry import Rect
|
||||
|
@ -54,8 +54,12 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
|||
|
||||
if theme == 'white':
|
||||
self.line_color = (0.3, 0.0, 0.0, 1.0)
|
||||
self.rect_hud_color = Color('#0000FF10')
|
||||
self.text_hud_color = 'black'
|
||||
else:
|
||||
self.line_color = (0.4, 0.4, 0.4, 1.0)
|
||||
self.rect_hud_color = Color('#0000FF10')
|
||||
self.text_hud_color = 'white'
|
||||
|
||||
# workspace lines; I didn't use the rectangle because I didn't want to add another VisPy Node,
|
||||
# which might decrease performance
|
||||
|
@ -146,13 +150,28 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
|||
self.cursor_h_line = InfiniteLine(pos=None, color=c_color, vertical=False,
|
||||
parent=self.line_parent)
|
||||
|
||||
self.rect_hud = Rectangle(center=(90,45), color=self.rect_hud_color, border_color=self.rect_hud_color,
|
||||
width=170, height=80, radius=[5, 5, 5, 5], parent=None)
|
||||
self.rect_hud.set_gl_state(depth_test=False)
|
||||
|
||||
# HUD Display
|
||||
self.hud_enabled = False
|
||||
|
||||
self.text_hud = Text('', color=self.text_hud_color, pos=(8, 45), method='gpu', anchor_x='left', parent=None)
|
||||
self.text_hud.font_size = 8
|
||||
units = self.fcapp.defaults["units"].lower()
|
||||
self.text_hud.text = 'Dx:\t%s [%s]\nDy:\t%s [%s]\nX: \t%s [%s]\nY: \t%s [%s]' % \
|
||||
('0.0000', units, '0.0000', units, '0.0000', units, '0.0000', units)
|
||||
|
||||
if self.fcapp.defaults['global_hud'] is True:
|
||||
self.on_toggle_hud(state=True)
|
||||
|
||||
self.shape_collections = []
|
||||
|
||||
self.shape_collection = self.new_shape_collection()
|
||||
self.fcapp.pool_recreated.connect(self.on_pool_recreated)
|
||||
self.text_collection = self.new_text_collection()
|
||||
|
||||
# TODO: Should be setting to show/hide CNC job annotations (global or per object)
|
||||
self.text_collection.enabled = True
|
||||
|
||||
self.c = None
|
||||
|
@ -163,6 +182,16 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
|||
|
||||
self.graph_event_connect('mouse_wheel', self.on_mouse_scroll)
|
||||
|
||||
def on_toggle_hud(self, state):
|
||||
if state:
|
||||
self.hud_enabled = True
|
||||
self.rect_hud.parent = self.view
|
||||
self.text_hud.parent = self.view
|
||||
else:
|
||||
self.hud_enabled = False
|
||||
self.rect_hud.parent = None
|
||||
self.text_hud.parent = None
|
||||
|
||||
def draw_workspace(self, workspace_size):
|
||||
"""
|
||||
Draw a rectangular shape on canvas to specify our valid workspace.
|
||||
|
|
|
@ -29,6 +29,7 @@ mpl_use("Qt5Agg")
|
|||
from matplotlib.figure import Figure
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.lines import Line2D
|
||||
from matplotlib.offsetbox import AnchoredText
|
||||
# from matplotlib.widgets import Cursor
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
|
@ -147,9 +148,13 @@ class PlotCanvasLegacy(QtCore.QObject):
|
|||
if self.app.defaults['global_theme'] == 'white':
|
||||
theme_color = '#FFFFFF'
|
||||
tick_color = '#000000'
|
||||
self.rect_hud_color = '#0000FF10'
|
||||
self.text_hud_color = '#000000'
|
||||
else:
|
||||
theme_color = '#000000'
|
||||
tick_color = '#FFFFFF'
|
||||
self.rect_hud_color = '#0000FF10'
|
||||
self.text_hud_color = '#000000'
|
||||
|
||||
# workspace lines; I didn't use the rectangle because I didn't want to add another VisPy Node,
|
||||
# which might decrease performance
|
||||
|
@ -298,11 +303,79 @@ class PlotCanvasLegacy(QtCore.QObject):
|
|||
# signal if there is a doubleclick
|
||||
self.is_dblclk = False
|
||||
|
||||
self.hud_enabled = False
|
||||
self.text_hud = self.Thud(plotcanvas=self)
|
||||
|
||||
# bbox_props = dict(boxstyle="round,pad=0.3", fc="blue", ec="b", lw=0)
|
||||
# self.text_hud = self.figure.text(0, 0, "Direction", ha="left", va="center", rotation=0,
|
||||
# size=15,
|
||||
# bbox=bbox_props)
|
||||
|
||||
# draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area
|
||||
# all CNC have a limited workspace
|
||||
if self.app.defaults['global_workspace'] is True:
|
||||
self.draw_workspace(workspace_size=self.app.defaults["global_workspaceT"])
|
||||
|
||||
if self.app.defaults['global_hud'] is True:
|
||||
self.on_toggle_hud(state=True)
|
||||
|
||||
def on_toggle_hud(self, state):
|
||||
if state:
|
||||
self.hud_enabled = True
|
||||
self.text_hud.add_artist()
|
||||
else:
|
||||
self.hud_enabled = False
|
||||
self.text_hud.remove_artist()
|
||||
self.canvas.draw()
|
||||
|
||||
class Thud(QtCore.QObject):
|
||||
text_changed = QtCore.pyqtSignal(str)
|
||||
|
||||
def __init__(self, plotcanvas):
|
||||
super().__init__()
|
||||
|
||||
self.p = plotcanvas
|
||||
units = self.p.app.defaults['units']
|
||||
self._text = 'Dx: %s [%s]\nDy: %s [%s]\nX: %s [%s]\nY: %s [%s]' % \
|
||||
('0.0000', units, '0.0000', units, '0.0000', units, '0.0000', units)
|
||||
|
||||
self.hud_holder = AnchoredText(self._text,
|
||||
prop=dict(size=20), frameon=True,
|
||||
loc='upper left',
|
||||
)
|
||||
self.hud_holder.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
|
||||
|
||||
self.hud_holder.patch.set_facecolor('blue')
|
||||
self.hud_holder.patch.set_alpha(0.3)
|
||||
self.hud_holder.patch.set_edgecolor((0, 0, 0, 0))
|
||||
|
||||
self.text_changed.connect(self.on_text_changed)
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self._text
|
||||
|
||||
@text.setter
|
||||
def text(self, val):
|
||||
self.text_changed.emit(val)
|
||||
self._text = val
|
||||
|
||||
def on_text_changed(self, txt):
|
||||
try:
|
||||
txt = txt.replace('\t', ' ')
|
||||
self.hud_holder.txt.set_text(txt)
|
||||
self.p.canvas.draw()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def add_artist(self):
|
||||
if self.hud_holder not in self.p.axes.artists:
|
||||
self.p.axes.add_artist(self.hud_holder)
|
||||
|
||||
def remove_artist(self):
|
||||
if self.hud_holder in self.p.axes.artists:
|
||||
self.p.axes.artists.remove(self.hud_holder)
|
||||
|
||||
def draw_workspace(self, workspace_size):
|
||||
"""
|
||||
Draw a rectangular shape on canvas to specify our valid workspace.
|
||||
|
|
|
@ -13,6 +13,7 @@ import numpy as np
|
|||
|
||||
import vispy.scene as scene
|
||||
from vispy.scene.cameras.base_camera import BaseCamera
|
||||
# from vispy.scene.widgets import Widget as VisPyWidget
|
||||
from vispy.color import Color
|
||||
|
||||
import time
|
||||
|
|
|
@ -910,16 +910,22 @@ class ToolCopperThieving(FlatCAMTool):
|
|||
edge_width=self.app.defaults["global_cursor_width"],
|
||||
size=self.app.defaults["global_cursor_size"])
|
||||
|
||||
# update the positions on status bar
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
if self.cursor_pos is None:
|
||||
self.cursor_pos = (0, 0)
|
||||
|
||||
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
|
||||
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
# # update the positions on status bar
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
|
||||
|
||||
# draw the utility geometry
|
||||
if self.first_click:
|
||||
|
|
|
@ -544,11 +544,16 @@ class Distance(FlatCAMTool):
|
|||
else:
|
||||
pos = (pos_canvas[0], pos_canvas[1])
|
||||
|
||||
self.app.ui.position_label.setText(
|
||||
" <b>X</b>: {} <b>Y</b>: {}".format(
|
||||
'%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
|
||||
)
|
||||
)
|
||||
# self.app.ui.position_label.setText(
|
||||
# " <b>X</b>: {} <b>Y</b>: {}".format(
|
||||
# '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
|
||||
# )
|
||||
# )
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
0.0000, units, 0.0000, units, pos[0], units, pos[1], units)
|
||||
|
||||
if self.rel_point1 is not None:
|
||||
dx = pos[0] - float(self.rel_point1[0])
|
||||
|
|
|
@ -1825,16 +1825,22 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
edge_width=self.app.defaults["global_cursor_width"],
|
||||
size=self.app.defaults["global_cursor_size"])
|
||||
|
||||
# update the positions on status bar
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
if self.cursor_pos is None:
|
||||
self.cursor_pos = (0, 0)
|
||||
|
||||
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
|
||||
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
# # update the positions on status bar
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
|
||||
|
||||
# draw the utility geometry
|
||||
if shape_type == "square":
|
||||
|
|
|
@ -1724,16 +1724,22 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
edge_width=self.app.defaults["global_cursor_width"],
|
||||
size=self.app.defaults["global_cursor_size"])
|
||||
|
||||
# update the positions on status bar
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
"<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
if self.cursor_pos is None:
|
||||
self.cursor_pos = (0, 0)
|
||||
|
||||
self.app.dx = curr_pos[0] - float(self.cursor_pos[0])
|
||||
self.app.dy = curr_pos[1] - float(self.cursor_pos[1])
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
# # update the positions on status bar
|
||||
# self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
# "<b>Y</b>: %.4f" % (curr_pos[0], curr_pos[1]))
|
||||
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
# "%.4f " % (self.app.dx, self.app.dy))
|
||||
|
||||
units = self.app.defaults["units"].lower()
|
||||
self.plotcanvas.text_hud.text = \
|
||||
'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
|
||||
self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
|
||||
|
||||
# draw the utility geometry
|
||||
if shape_type == "square":
|
||||
|
|
Loading…
Reference in New Issue