From 34bb741335c800e6cf585c9a75d22419b75aaca9 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 16 Apr 2022 11:46:33 +0300 Subject: [PATCH] - in Geometry Editor, in the Simplification Tool made sure that the selected shape is highlighted - in Geometry Editor, in Rectangle Tool added a modification mode where a selected shape (using the SHIFT + click combo) while the tool is active, can be modified --- CHANGELOG.md | 5 ++ appEditors/AppGeoEditor.py | 54 +++++++++++++++---- appEditors/plugins/GeoRectanglePlugin.py | 42 +++++++++++++-- appEditors/plugins/GeoSimplificationPlugin.py | 4 +- 4 files changed, 91 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcebaa04..bc5d4a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG for FlatCAM Evo beta ================================================= +16.04.2022 + +- in Geometry Editor, in the Simplification Tool made sure that the selected shape is highlighted +- in Geometry Editor, in Rectangle Tool added a modification mode where a selected shape (using the SHIFT + click combo) while the tool is active, can be modified + 15.04.2022 - in Geometry Editor moved the simplification feature in its own Editor Tool (plugin) diff --git a/appEditors/AppGeoEditor.py b/appEditors/AppGeoEditor.py index 039f8f49..16451c17 100644 --- a/appEditors/AppGeoEditor.py +++ b/appEditors/AppGeoEditor.py @@ -776,6 +776,7 @@ class FCRectangle(FCShapeTool): self.draw_app = draw_app self.app = self.draw_app.app self.plugin_name = _("Rectangle") + self.storage = self.draw_app.storage try: QtGui.QGuiApplication.restoreOverrideCursor() @@ -798,12 +799,37 @@ class FCRectangle(FCShapeTool): pass self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) - self.points.append(point) + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier: + # deselect all shapes + self.draw_app.selected = [] + for ____ in self.storage.get_objects(): + try: + __, closest_shape = self.storage.nearest(point) + # select closes shape + self.draw_app.selected.append(closest_shape) + except StopIteration: + return "" + if self.draw_app.selected: + self.draw_app.plot_all() + self.rect_tool.mode = 'change' + sel_shape_geo = self.draw_app.selected[-1].geo + geo_bounds = sel_shape_geo.bounds + # assuming that the default setting for anchor is center + origin_x_sel_geo = geo_bounds[0] + ((geo_bounds[2] - geo_bounds[0]) / 2) + self.rect_tool.ui.x_entry.set_value(origin_x_sel_geo) + origin_y_sel_geo = geo_bounds[1] + ((geo_bounds[3] - geo_bounds[1]) / 2) + self.rect_tool.ui.y_entry.set_value(origin_y_sel_geo) + self.draw_app.app.inform.emit( + _("Click on 1st corner to add a new rectangle or Apply to change the selection.")) + return + + self.rect_tool.mode = 'add' + self.points.append(point) if len(self.points) == 1: self.draw_app.app.inform.emit(_("Click on opposite corner to complete ...")) return "Click on opposite corner to complete ..." - if len(self.points) == 2: self.make() return "Done." @@ -1994,6 +2020,7 @@ class FCSimplification(FCShapeTool): self.draw_app.selected.append(closest_shape) except StopIteration: return "" + self.draw_app.plot_all() last_sel_geo = self.draw_app.selected[-1].geo self.simp_tool.calculate_coords_vertex(last_sel_geo) @@ -3262,6 +3289,7 @@ class AppGeoEditor(QtCore.QObject): :type build_ui: bool :return: None """ + ret = [] if shape is None: return @@ -3275,13 +3303,16 @@ class AppGeoEditor(QtCore.QObject): try: w_geo = shape.geoms if isinstance(shape, (MultiPolygon, MultiLineString)) else shape for subshape in w_geo: - self.add_shape(subshape) + ret_shape = self.add_shape(subshape) + ret.append(ret_shape) return except TypeError: pass if not isinstance(shape, DrawToolShape): shape = DrawToolShape(shape) + ret.append(shape) + # assert isinstance(shape, DrawToolShape), "Expected a DrawToolShape, got %s" % type(shape) assert shape.geo is not None, "Shape object has empty geometry (None)" assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \ @@ -3299,6 +3330,8 @@ class AppGeoEditor(QtCore.QObject): if build_ui is True: self.build_ui_sig.emit() # Build UI + return ret + def delete_utility_geometry(self): """ Will delete the shapes in the utility shapes storage. @@ -3420,11 +3453,12 @@ class AppGeoEditor(QtCore.QObject): modifiers = QtWidgets.QApplication.keyboardModifiers() # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier: - self.app.clipboard.setText( - self.app.options["global_point_clipboard_format"] % - (self.decimals, self.pos[0], self.decimals, self.pos[1]) - ) - return + if self.active_tool is not None and self.active_tool.name != 'rectangle': + self.app.clipboard.setText( + self.app.options["global_point_clipboard_format"] % + (self.decimals, self.pos[0], self.decimals, self.pos[1]) + ) + return # Selection with left mouse button if self.active_tool is not None: @@ -3736,15 +3770,15 @@ class AppGeoEditor(QtCore.QObject): def on_delete_btn(self): self.delete_selected() - self.plot_all() + # self.plot_all() def delete_selected(self): tempref = [s for s in self.selected] for shape in tempref: self.delete_shape(shape) - self.plot_all() self.selected = [] self.build_ui() + self.plot_all() def delete_shape(self, shape): diff --git a/appEditors/plugins/GeoRectanglePlugin.py b/appEditors/plugins/GeoRectanglePlugin.py index 053a38d7..9acc15d6 100644 --- a/appEditors/plugins/GeoRectanglePlugin.py +++ b/appEditors/plugins/GeoRectanglePlugin.py @@ -16,6 +16,7 @@ class RectangleEditorTool(AppTool): self.draw_app = draw_app self.decimals = app.decimals + self._mode = 'add' self.ui = RectangleEditorUI(layout=self.layout, rect_class=self) self.ui.pluginName = plugin_name @@ -25,7 +26,7 @@ class RectangleEditorTool(AppTool): def connect_signals_at_init(self): # Signals - self.ui.add_button.clicked.connect(self.on_add) + self.ui.add_button.clicked.connect(self.on_execute) def run(self): self.app.defaults.report_usage("Geo Editor RectangleTool()") @@ -78,8 +79,17 @@ class RectangleEditorTool(AppTool): self.draw_app.select_tool("select") self.app.ui.notebook.callback_on_close = lambda: None + def on_execute(self): + if self.mode == 'add': + self.app.log.info("RectangleEditorTool.on_add() -> adding a Rectangle shape") + self.on_add() + else: + self.app.log.info("RectangleEditorTool.on_add() -> modifying a Rectangle shape") + self.draw_app.delete_selected() + self.on_add() + self.draw_app.app.inform.emit(_("Click on 1st corner ...")) + def on_add(self): - self.app.log.info("RecrangleEditorTool.on_add() -> adding a Rectangle shape") origin = self.ui.anchor_radio.get_value() origin_x = self.ui.x_entry.get_value() origin_y = self.ui.y_entry.get_value() @@ -130,12 +140,30 @@ class RectangleEditorTool(AppTool): else: # 's' - square geo = box(minx, miny, maxx, maxy).exterior - self.draw_app.add_shape(geo) + added_shapes = self.draw_app.add_shape(geo) + for added_shape in added_shapes: + added_shape.data['type'] = _("Rectangle") self.draw_app.plot_all() def on_clear(self): self.set_tool_ui() + @property + def mode(self): + return self._mode + + @mode.setter + def mode(self, val): + self._mode = val + if self._mode == 'add': + # remove selections when adding a new rectangle + self.draw_app.selected = [] + self.ui.add_button.set_value(_("Add")) + self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png')) + else: + self.ui.add_button.set_value(_("Apply")) + self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/apply32.png')) + @property def length(self): return self.ui.length_entry.get_value() @@ -266,10 +294,18 @@ class RectangleEditorUI: # Buttons self.add_button = FCButton(_("Add")) + self.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png')) grid0.addWidget(self.add_button, 18, 0, 1, 2) self.layout.addStretch(1) + # Note + self.note_lbl = FCLabel('%s' % _("Note")) + self.layout.addWidget(self.note_lbl) + self.note_description_lbl = FCLabel('%s' % _("Shift + click to select a shape for modification.")) + self.layout.addWidget(self.note_description_lbl) + + # Signals self.corner_radio.activated_custom.connect(self.on_corner_changed) def on_corner_changed(self, val): diff --git a/appEditors/plugins/GeoSimplificationPlugin.py b/appEditors/plugins/GeoSimplificationPlugin.py index 20982fc4..7fe9938a 100644 --- a/appEditors/plugins/GeoSimplificationPlugin.py +++ b/appEditors/plugins/GeoSimplificationPlugin.py @@ -101,7 +101,7 @@ class SimplificationTool(AppTool): selected_shapes_geos.append(obj_shape.geo.simplify(tolerance=tol)) if not selected_shapes: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed.")) + self.app.inform.emit('%s' % _("Failed.")) return for shape in selected_shapes: @@ -115,6 +115,8 @@ class SimplificationTool(AppTool): last_sel_geo = selected_shapes_geos[-1] self.calculate_coords_vertex(last_sel_geo) + self.app.inform.emit('%s' % _("Done.")) + self.draw_app.plot_all() self.draw_app.interdict_selection = False self.draw_app.build_ui_sig.emit()