From fc1dfb855035328f46982736adf505513609b681 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 14 Apr 2019 16:59:20 +0300 Subject: [PATCH] - cleaned up Measuring Tool --- FlatCAMApp.py | 6 +- README.md | 1 + flatcamGUI/FlatCAMGUI.py | 1 - flatcamTools/ToolMeasurement.py | 168 ++++++++++++++++---------------- 4 files changed, 85 insertions(+), 91 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 2787a485..0a4bdf55 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4472,7 +4472,6 @@ class App(QtCore.QObject): self.report_usage("on_set_origin()") self.inform.emit(_('Click to set the origin ...')) - self.plotcanvas.vis_connect('mouse_press', self.on_set_zero_click) def on_jump_to(self, custom_location=None, fit_center=True): @@ -5117,9 +5116,7 @@ class App(QtCore.QObject): def on_mouse_move_over_plot(self, event, origin_click=None): """ - Callback for the mouse motion event over the plot. This event is generated - by the Matplotlib backend and has been registered in ``self.__init__()``. - For details, see: http://matplotlib.org/users/event_handling.html + Callback for the mouse motion event over the plot. :param event: Contains information about the event. :param origin_click @@ -5314,7 +5311,6 @@ class App(QtCore.QObject): def select_objects(self, key=None): # list where we store the overlapped objects under our mouse left click position objects_under_the_click_list = [] - # Populate the list with the overlapped objects on the click position curr_x, curr_y = self.pos for obj in self.all_objects_list: diff --git a/README.md b/README.md index e70c1538..adf9c96a 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ CAD program, and create G-Code for Isolation routing. - In Geometry Editor I fixed bug in Arc modes. Arc mode shortcut key is now key 'M' and arc direction change shortcut key is 'D' - moved the key handler out of the Measurement tool to flatcamGUI.FlatCAMGui.keyPressEvent() - Gerber Editor: started to add new function of poligonize which should make a filled polygon out of a shape +- cleaned up Measuring Tool 13.04.2019 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 583aa31a..37914892 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -2923,7 +2923,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): elif modifiers == QtCore.Qt.NoModifier: if key == QtCore.Qt.Key_Escape or key == 'Escape': # abort the measurement action - self.app.measurement_tool.on_measure(activate=False) self.app.measurement_tool.deactivate_measure_tool() self.app.inform.emit(_("Measurement Tool exit...")) return diff --git a/flatcamTools/ToolMeasurement.py b/flatcamTools/ToolMeasurement.py index 12f68bdd..e8a4f96f 100644 --- a/flatcamTools/ToolMeasurement.py +++ b/flatcamTools/ToolMeasurement.py @@ -103,25 +103,23 @@ class Measurement(FlatCAMTool): self.layout.addStretch() - self.clicked_meas = 0 + # store here the first click and second click of the measurement process + self.points = [] - self.point1 = None - self.point2 = None - - # the default state is disabled for the Move command - # self.setVisible(False) - self.active = 0 + self.active = False self.original_call_source = 'app' # VisPy visuals self.sel_shapes = ShapeCollection(parent=self.app.plotcanvas.vispy_canvas.view.scene, layers=1) - self.measure_btn.clicked.connect(lambda: self.on_measure(activate=True)) + self.measure_btn.clicked.connect(self.activate_measure_tool) def run(self, toggle=False): self.app.report_usage("ToolMeasurement()") + self.points[:] = [] + if self.app.tool_tab_locked is True: return @@ -130,8 +128,13 @@ class Measurement(FlatCAMTool): # if the splitter is hidden, display it if self.app.ui.splitter.sizes()[0] == 0: self.app.ui.splitter.setSizes([1, 1]) + if toggle: + pass - self.on_measure(activate=True) + if self.active is False: + self.activate_measure_tool() + else: + self.deactivate_measure_tool() def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='CTRL+M', **kwargs) @@ -156,101 +159,104 @@ class Measurement(FlatCAMTool): self.distance_x_entry.set_value('0') self.distance_y_entry.set_value('0') self.total_distance_entry.set_value('0') + log.debug("Measurement Tool --> tool initialized") def activate_measure_tool(self): - # we disconnect the mouse/key handlers from wherever the measurement tool was called - self.canvas.vis_disconnect('mouse_move') - self.canvas.vis_disconnect('mouse_press') - self.canvas.vis_disconnect('mouse_release') + # ENABLE the Measuring TOOL + self.active = True - # we can safely connect the app mouse events to the measurement tool + self.clicked_meas = 0 + self.original_call_source = copy(self.app.call_source) + + self.app.inform.emit(_("MEASURING: Click on the Start point ...")) + self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + + # we can connect the app mouse events to the measurement tool + # NEVER DISCONNECT THOSE before connecting some other handlers; it breaks something in VisPy self.canvas.vis_connect('mouse_move', self.on_mouse_move_meas) self.canvas.vis_connect('mouse_release', self.on_mouse_click_release) + # we disconnect the mouse/key handlers from wherever the measurement tool was called + if self.app.call_source == 'app': + self.canvas.vis_disconnect('mouse_move', self.app.on_mouse_move_over_plot) + self.canvas.vis_disconnect('mouse_press', self.app.on_mouse_click_over_plot) + self.canvas.vis_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot) + elif self.app.call_source == 'geo_editor': + self.canvas.vis_disconnect('mouse_move', self.app.geo_editor.on_canvas_move) + self.canvas.vis_disconnect('mouse_press', self.app.geo_editor.on_canvas_click) + self.canvas.vis_disconnect('mouse_release', self.app.geo_editor.on_geo_click_release) + elif self.app.call_source == 'exc_editor': + self.canvas.vis_disconnect('mouse_move', self.app.exc_editor.on_canvas_move) + self.canvas.vis_disconnect('mouse_press', self.app.exc_editor.on_canvas_click) + self.canvas.vis_disconnect('mouse_release', self.app.exc_editor.on_exc_click_release) + elif self.app.call_source == 'grb_editor': + self.canvas.vis_disconnect('mouse_move', self.app.grb_editor.on_canvas_move) + self.canvas.vis_disconnect('mouse_press', self.app.grb_editor.on_canvas_click) + self.canvas.vis_disconnect('mouse_release', self.app.grb_editor.on_grb_click_release) + + self.app.call_source = 'measurement' + self.set_tool_ui() def deactivate_measure_tool(self): - # disconnect the mouse/key events from functions of measurement tool - self.canvas.vis_disconnect('mouse_move', self.on_mouse_move_meas) - self.canvas.vis_disconnect('mouse_release', self.on_mouse_click_release) + # DISABLE the Measuring TOOL + self.active = False + self.points = [] - if self.app.call_source == 'app': + self.app.call_source = copy(self.original_call_source) + if self.original_call_source == 'app': self.canvas.vis_connect('mouse_move', self.app.on_mouse_move_over_plot) self.canvas.vis_connect('mouse_press', self.app.on_mouse_click_over_plot) self.canvas.vis_connect('mouse_release', self.app.on_mouse_click_release_over_plot) - elif self.app.call_source == 'geo_editor': + elif self.original_call_source == 'geo_editor': self.canvas.vis_connect('mouse_move', self.app.geo_editor.on_canvas_move) self.canvas.vis_connect('mouse_press', self.app.geo_editor.on_canvas_click) self.canvas.vis_connect('mouse_release', self.app.geo_editor.on_geo_click_release) - elif self.app.call_source == 'exc_editor': + elif self.original_call_source == 'exc_editor': self.canvas.vis_connect('mouse_move', self.app.exc_editor.on_canvas_move) self.canvas.vis_connect('mouse_press', self.app.exc_editor.on_canvas_click) self.canvas.vis_connect('mouse_release', self.app.exc_editor.on_exc_click_release) - elif self.app.call_source == 'grb_editor': + elif self.original_call_source == 'grb_editor': self.canvas.vis_connect('mouse_move', self.app.grb_editor.on_canvas_move) self.canvas.vis_connect('mouse_press', self.app.grb_editor.on_canvas_click) self.canvas.vis_connect('mouse_release', self.app.grb_editor.on_grb_click_release) - self.app.ui.notebook.setTabText(2, _("Tools")) - self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) + # disconnect the mouse/key events from functions of measurement tool + self.canvas.vis_disconnect('mouse_move', self.on_mouse_move_meas) + self.canvas.vis_disconnect('mouse_release', self.on_mouse_click_release) - def on_measure(self, signal=None, activate=None): - log.debug("Measurement.on_measure()") - if activate is True: - # ENABLE the Measuring TOOL - self.clicked_meas = 0 - self.original_call_source = copy(self.app.call_source) - self.app.call_source = 'measurement' + # self.app.ui.notebook.setTabText(2, _("Tools")) + # self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) - self.app.inform.emit(_("MEASURING: Click on the Start point ...")) - self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + self.app.command_active = None - self.activate_measure_tool() - log.debug("Measurement Tool --> tool initialized") - else: - # DISABLE the Measuring TOOL - self.deactivate_measure_tool() - self.app.call_source = copy(self.original_call_source) - self.app.command_active = None + # delete the measuring line + self.delete_shape() - # delete the measuring line - self.delete_shape() - - log.debug("Measurement Tool --> exit tool") + log.debug("Measurement Tool --> exit tool") def on_mouse_click_release(self, event): # mouse click releases will be accepted only if the left button is clicked # this is necessary because right mouse click or middle mouse click # are used for panning on the canvas + log.debug("Measuring Tool --> mouse click release") if event.button == 1: pos_canvas = self.canvas.vispy_canvas.translate_coords(event.pos) + # if GRID is active we need to get the snapped positions + if self.app.grid_status() == True: + pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) + else: + pos = pos_canvas[0], pos_canvas[1] + self.points.append(pos) - if self.clicked_meas == 0: - self.clicked_meas = 1 - - # if GRID is active we need to get the snapped positions - if self.app.grid_status() == True: - pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) - else: - pos = pos_canvas[0], pos_canvas[1] - - self.point1 = pos + if len(self.points) == 1: self.start_entry.set_value("(%.4f, %.4f)" % pos) self.app.inform.emit(_("MEASURING: Click on the Destination point ...")) - else: - # delete the selection bounding box - self.delete_shape() - - # if GRID is active we need to get the snapped positions - if self.app.grid_status() is True: - pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) - else: - pos = pos_canvas[0], pos_canvas[1] - - dx = pos[0] - self.point1[0] - dy = pos[1] - self.point1[1] + if len(self.points) == 2: + dx = self.points[1][0] - self.points[0][0] + dy = self.points[1][1] - self.points[0][1] d = sqrt(dx ** 2 + dy ** 2) self.stop_entry.set_value("(%.4f, %.4f)" % pos) @@ -262,33 +268,25 @@ class Measurement(FlatCAMTool): self.distance_y_entry.set_value('%.4f' % abs(dy)) self.total_distance_entry.set_value('%.4f' % abs(d)) - # TODO: I don't understand why I have to do it twice ... but without it the mouse handlers are - # TODO: are left disconnected ... - self.on_measure(activate=False) - self.deactivate() + self.deactivate_measure_tool() def on_mouse_move_meas(self, event): pos_canvas = self.canvas.vispy_canvas.translate_coords(event.pos) - - # if GRID is active we need to get the snapped positions + # Update cursor + pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) if self.app.grid_status() == True: - pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) - self.app.app_cursor.enabled = True - # Update cursor self.app.app_cursor.set_data(np.asarray([(pos[0], pos[1])]), symbol='++', edge_color='black', size=20) - else: - pos = pos_canvas - self.app.app_enabled = False - - self.point2 = (pos[0], pos[1]) # update utility geometry - if self.clicked_meas == 1: - # first delete old shape - self.delete_shape() - # second draw the new shape of the utility geometry - self.meas_line = LineString([self.point2, self.point1]) - self.sel_shapes.add(self.meas_line, color='black', update=True, layer=0, tolerance=None) + if len(self.points) == 1: + self.utility_geometry(pos=pos) + + def utility_geometry(self, pos): + # first delete old shape + self.delete_shape() + # second draw the new shape of the utility geometry + self.meas_line = LineString([pos, self.points[0]]) + self.sel_shapes.add(self.meas_line, color='black', update=True, layer=0, tolerance=None) def delete_shape(self): self.sel_shapes.clear()