From 4b52196310f0de7a66d8cfb808221b6fc82caceb Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 9 Sep 2021 23:09:09 +0300 Subject: [PATCH] - in Fiducials Plugin added the support for ESCAPE key from manual mode and also exit by right clicking - in Fiducials Plugin addressed the situation when no object is selected but there are available - in Fiducials Plugin when adding manual fiducials now panning is allowed without cancelling the process of adding - in Corners Plugin implemented the manual adding of markers - in Corners Plugin added the support for ESCAPE key from manual mode and also exit by right clicking --- CHANGELOG.md | 6 +- appGUI/MainGUI.py | 25 +++++++ appPlugins/ToolCorners.py | 140 ++++++++++++++++++++++++++++++++++-- appPlugins/ToolFiducials.py | 19 +++-- appPlugins/ToolMilling.py | 19 ++--- 5 files changed, 187 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d808c633..4b0f095d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,11 @@ CHANGELOG for FlatCAM beta - in Copper Thieving Plugin more UI changes - in GUI Elements the FCGridLayout has now a class method that allow adjusting column size in multiple grid layouts to the highest on that column; still work to d oto take care of the situation when widgets are spanning multiple cells - in Fiducials Plugin added the support for ESCAPE key from manual mode and also exit by right clicking - +- in Fiducials Plugin addressed the situation when no object is selected but there are available +- in Fiducials Plugin when adding manual fiducials now panning is allowed without cancelling the process of adding +- in Corners Plugin implemented the manual adding of markers +- in Corners Plugin added the support for ESCAPE key from manual mode and also exit by right clicking +- 8.09.2021 - in Calculator Plugin, in Units Calculator added more units conversions diff --git a/appGUI/MainGUI.py b/appGUI/MainGUI.py index fbbbaa7e..5f1d2094 100644 --- a/appGUI/MainGUI.py +++ b/appGUI/MainGUI.py @@ -4222,6 +4222,31 @@ class MainGUI(QtWidgets.QMainWindow): # Jump to coords if key == QtCore.Qt.Key.Key_J: self.app.on_jump_to() + elif self.app.call_source == 'corners_tool': + # CTRL + ALT + if modifiers == QtCore.Qt.KeyboardModifier.ControlModifier | QtCore.Qt.KeyboardModifier.AltModifier: + if key == QtCore.Qt.Key.Key_X: + self.app.abort_all_tasks() + return + elif modifiers == QtCore.Qt.KeyboardModifier.ControlModifier: + pass + elif modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier: + pass + elif modifiers == QtCore.Qt.KeyboardModifier.AltModifier: + pass + # NO MODIFIER + elif modifiers == QtCore.Qt.KeyboardModifier.NoModifier: + # Escape = Deselect All + if key == QtCore.Qt.Key.Key_Escape or key == 'Escape': + self.app.corners_tool.on_exit(cancelled=True) + + # Grid toggle + if key == QtCore.Qt.Key.Key_G: + self.app.ui.grid_snap_btn.trigger() + + # Jump to coords + if key == QtCore.Qt.Key.Key_J: + self.app.on_jump_to() def eventFilter(self, obj, event): """ diff --git a/appPlugins/ToolCorners.py b/appPlugins/ToolCorners.py index 2102d1f3..c5542c4e 100644 --- a/appPlugins/ToolCorners.py +++ b/appPlugins/ToolCorners.py @@ -55,11 +55,15 @@ class ToolCorners(AppTool): # store the flattened geometry here: self.flat_geometry = [] + self.mr = None + # Tool properties self.fid_dia = None self.grb_steps_per_circle = self.app.defaults["gerber_circle_steps"] + self.handlers_connected = False + def run(self, toggle=True): self.app.defaults.report_usage("ToolCorners()") @@ -153,6 +157,9 @@ class ToolCorners(AppTool): obj_name = obj.options['name'] self.ui.object_combo.set_value(obj_name) + if obj is None: + self.ui.object_combo.setCurrentIndex(0) + # Show/Hide Advanced Options app_mode = self.app.defaults["global_app_level"] self.change_level(app_mode) @@ -211,19 +218,34 @@ class ToolCorners(AppTool): if val == 'a': self.ui.locs_label.setDisabled(False) self.ui.loc_frame.setDisabled(False) + + self.ui.type_label.setDisabled(False) + self.ui.type_radio.setDisabled(False) + self.ui.margin_label.setDisabled(False) + self.ui.margin_entry.setDisabled(False) else: self.ui.locs_label.setDisabled(True) self.ui.loc_frame.setDisabled(True) + self.ui.type_label.setDisabled(True) + self.ui.type_radio.setDisabled(True) + self.ui.margin_label.setDisabled(True) + self.ui.margin_entry.setDisabled(True) + self.ui.type_radio.set_value('c') + def add_markers(self): + self.app.call_source = "corners_tool" select_type = self.ui.sel_radio.get_value() if select_type == 'a': self.handle_automatic_placement() else: - self.handle_manual_placement() + self.app.inform.emit('%s' % _("Click to add next marker or right click to finish.")) + # it works only with cross markers + self.ui.type_radio.set_value('c') + self.app.ui.notebook.setDisabled(True) + self.connect_event_handlers() def handle_automatic_placement(self): - self.app.call_source = "corners_tool" tl_state = self.ui.tl_cb.get_value() tr_state = self.ui.tr_cb.get_value() bl_state = self.ui.bl_cb.get_value() @@ -261,6 +283,28 @@ class ToolCorners(AppTool): self.on_exit(ret_val) + def handle_manual_placement(self): + # self.app.inform.emit('[ERROR_NOTCL] %s' % "Not implemented yet.") + + # get the Gerber object on which the corner marker will be inserted + selection_index = self.ui.object_combo.currentIndex() + model_index = self.app.collection.index(selection_index, 0, self.ui.object_combo.rootModelIndex()) + + try: + self.grb_object = model_index.internalPointer().obj + except Exception as e: + log.error("ToolCorners.add_markers() --> %s" % str(e)) + self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ...")) + self.on_exit() + return + + ret_val = self.add_corners_geo(self.points, g_obj=self.grb_object) + if ret_val == 'fail': + self.on_exit(ok=False) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed.")) + return + self.on_exit() + def add_corners_geo(self, points_storage, g_obj): """ Add geometry to the solid_geometry of the copper Gerber object @@ -362,6 +406,22 @@ class ToolCorners(AppTool): ]) geo_list.append(line_geo_hor) geo_list.append(line_geo_vert) + if key == 'manual': + if points_storage['manual']: + for man_pt in points_storage['manual']: + x = man_pt[0] - line_thickness / 2.0 + y = man_pt[1] + line_thickness / 2.0 + line_geo_hor = LineString([ + (x - line_length, y), (x + line_length, y) + ]) + line_geo_vert = LineString([ + (x, y + line_length), (x, y - line_length) + ]) + geo_list.append(line_geo_hor) + geo_list.append(line_geo_vert) + else: + self.app.log.warning("Not enough points.") + return "fail" new_apertures = deepcopy(g_obj.tools) @@ -437,9 +497,6 @@ class ToolCorners(AppTool): return ret - def handle_manual_placement(self): - self.app.inform.emit('[ERROR_NOTCL] %s' % "Not implemented yet.") - def on_create_drill_object(self): self.app.call_source = "corners_tool" @@ -649,7 +706,7 @@ class ToolCorners(AppTool): else: worker_task() - def on_exit(self, corner_gerber_obj=None): + def on_exit(self, corner_gerber_obj=None, cancelled=None, ok=True): # plot the object if corner_gerber_obj: try: @@ -671,7 +728,76 @@ class ToolCorners(AppTool): log.error("ToolCorners.on_exit() copper_obj bounds error --> %s" % str(e)) self.app.call_source = "app" - self.app.inform.emit('[success] %s' % _("A Gerber object with corner markers was created.")) + self.app.ui.notebook.setDisabled(False) + self.disconnect_event_handlers() + + if cancelled is True: + self.app.delete_selection_shape() + self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled by user request.")) + return + + if ok: + self.app.inform.emit('[success] %s' % _("A Gerber object with corner markers was created.")) + + def connect_event_handlers(self): + if self.handlers_connected is False: + if self.app.is_legacy is False: + self.app.plotcanvas.graph_event_disconnect('mouse_press', self.app.on_mouse_click_over_plot) + self.app.plotcanvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot) + else: + self.app.plotcanvas.graph_event_disconnect(self.app.mp) + self.app.plotcanvas.graph_event_disconnect(self.app.mr) + + self.mr = self.app.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_release) + + self.handlers_connected = True + + def disconnect_event_handlers(self): + if self.handlers_connected is True: + if self.app.is_legacy is False: + self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release) + else: + self.app.plotcanvas.graph_event_disconnect(self.mr) + + self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press', + self.app.on_mouse_click_over_plot) + + self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release', + self.app.on_mouse_click_release_over_plot) + self.handlers_connected = False + self.app.ui.notebook.setDisabled(False) + + def on_mouse_move(self, event): + pass + + def on_mouse_release(self, event): + if self.app.is_legacy is False: + event_pos = event.pos + right_button = 2 + self.app.event_is_dragging = self.app.event_is_dragging + else: + event_pos = (event.xdata, event.ydata) + right_button = 3 + self.app.event_is_dragging = self.app.ui.popMenu.mouse_is_panning + + if event.button == 1: + pos_canvas = self.canvas.translate_coords(event_pos) + if self.app.grid_status(): + pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) + else: + pos = (pos_canvas[0], pos_canvas[1]) + + if 'manual' not in self.points: + self.points['manual'] = [] + self.points['manual'].append(pos) + + self.app.inform.emit( + '%s: %d. %s' % + (_("Added marker"), len(self.points['manual']), + _("Click to add next marker or right click to finish."))) + + elif event.button == right_button and self.app.event_is_dragging is False: + self.handle_manual_placement() class CornersUI: diff --git a/appPlugins/ToolFiducials.py b/appPlugins/ToolFiducials.py index b11bc5c4..9682624f 100644 --- a/appPlugins/ToolFiducials.py +++ b/appPlugins/ToolFiducials.py @@ -189,6 +189,9 @@ class ToolFiducials(AppTool): obj_name = obj.options['name'] self.ui.grb_object_combo.set_value(obj_name) + if obj is None: + self.ui.grb_object_combo.setCurrentIndex(0) + def change_level(self, level): """ @@ -598,12 +601,16 @@ class ToolFiducials(AppTool): self.on_exit() def on_mouse_release(self, event): - if event.button == 1: - if self.app.is_legacy is False: - event_pos = event.pos - else: - event_pos = (event.xdata, event.ydata) + if self.app.is_legacy is False: + event_pos = event.pos + right_button = 2 + self.app.event_is_dragging = self.app.event_is_dragging + else: + event_pos = (event.xdata, event.ydata) + right_button = 3 + self.app.event_is_dragging = self.app.ui.popMenu.mouse_is_panning + if event.button == 1: pos_canvas = self.canvas.translate_coords(event_pos) if self.app.grid_status(): pos = self.app.geo_editor.snap(pos_canvas[0], pos_canvas[1]) @@ -619,7 +626,7 @@ class ToolFiducials(AppTool): ) self.check_points() - if event.button == 2: + elif event.button == right_button and self.app.event_is_dragging is False: self.on_exit(cancelled=True) def check_points(self): diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index 0e6c0405..f8b10fb1 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -430,14 +430,17 @@ class ToolMilling(AppTool, Excellon): if not selected_obj: self.ui.target_radio.set_value('geo') - - if selected_obj.kind == 'excellon': - self.ui.target_radio.set_value('exc') - self.ui.object_combo.set_value(selected_obj.options['name']) - - if selected_obj.kind == 'geometry': - self.ui.target_radio.set_value('geo') - self.ui.object_combo.set_value(selected_obj.options['name']) + self.ui.object_combo.setCurrentIndex(0) + else: + if selected_obj.kind == 'excellon': + self.ui.target_radio.set_value('exc') + self.ui.object_combo.set_value(selected_obj.options['name']) + elif selected_obj.kind == 'geometry': + self.ui.target_radio.set_value('geo') + self.ui.object_combo.set_value(selected_obj.options['name']) + else: + self.ui.target_radio.set_value('geo') + self.ui.object_combo.setCurrentIndex(0) except Exception as err: self.app.log.error("ToolMilling.set_tool_ui() --> %s" % str(err))