Просмотр исходного кода

- made the app not remember the window size if the app is maximized and remember in QSettings if it was maximized. This way we can restore the maximized state but restore the windows size unmaximized
- added a button to clear de GUI preferences in Preferences -> General -> Gui Settings -> Clear GUI Settings
- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), SHIFT+X, SHIFT+Y combo keys for Skew and ALT+X, ALT+Y combo keys for Offset
- adjusted the plotcanvas.zomm_fit() function so the objects are better fit into view (with a border around)

Marius Stanciu 7 лет назад
Родитель
Сommit
8c882cfdc4
7 измененных файлов с 285 добавлено и 103 удалено
  1. 8 2
      FlatCAMApp.py
  2. 117 66
      FlatCAMEditor.py
  3. 148 34
      FlatCAMGUI.py
  4. 7 0
      PlotCanvas.py
  5. 5 1
      README.md
  6. BIN
      share/offsetx32.png
  7. BIN
      share/offsety32.png

+ 8 - 2
FlatCAMApp.py

@@ -1264,7 +1264,7 @@ class App(QtCore.QObject):
         self.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified)
         self.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified)
         self.general_defaults_form.general_gui_group.workspace_cb.stateChanged.connect(self.on_workspace)
         self.general_defaults_form.general_gui_group.workspace_cb.stateChanged.connect(self.on_workspace)
 
 
-        self.general_defaults_form.general_gui_group.layout_combo.activated.connect(self.on_layout)
+        self.general_defaults_form.general_gui_set_group.layout_combo.activated.connect(self.on_layout)
 
 
         # Modify G-CODE Plot Area TAB
         # Modify G-CODE Plot Area TAB
         self.ui.code_editor.textChanged.connect(self.handleTextChanged)
         self.ui.code_editor.textChanged.connect(self.handleTextChanged)
@@ -3378,7 +3378,7 @@ class App(QtCore.QObject):
         if lay:
         if lay:
             current_layout = lay
             current_layout = lay
         else:
         else:
-            current_layout = self.general_defaults_form.general_gui_group.layout_combo.get_value().lower()
+            current_layout = self.general_defaults_form.general_gui_set_group.layout_combo.get_value().lower()
 
 
         settings = QSettings("Open Source", "FlatCAM")
         settings = QSettings("Open Source", "FlatCAM")
         settings.setValue('layout', current_layout)
         settings.setValue('layout', current_layout)
@@ -6276,6 +6276,12 @@ class App(QtCore.QObject):
                                 self.defaults["global_def_win_w"],
                                 self.defaults["global_def_win_w"],
                                 self.defaults["global_def_win_h"])
                                 self.defaults["global_def_win_h"])
             self.ui.splitter.setSizes([self.defaults["def_notebook_width"], 0])
             self.ui.splitter.setSizes([self.defaults["def_notebook_width"], 0])
+
+            settings = QSettings("Open Source", "FlatCAM")
+            if settings.contains("maximized_gui"):
+                maximized_ui = settings.value('maximized_gui', type=bool)
+                if maximized_ui is True:
+                    self.ui.showMaximized()
         except KeyError:
         except KeyError:
             pass
             pass
 
 

+ 117 - 66
FlatCAMEditor.py

@@ -27,7 +27,7 @@ from numpy.linalg import solve
 
 
 from rtree import index as rtindex
 from rtree import index as rtindex
 from GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCEntry2, FCComboBox, FCTextAreaRich, \
 from GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCEntry2, FCComboBox, FCTextAreaRich, \
-    VerticalScrollArea, FCTable, FCDoubleSpinner, FCButton, EvalEntry2
+    VerticalScrollArea, FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog
 from ParseFont import *
 from ParseFont import *
 from vispy.scene.visuals import Markers
 from vispy.scene.visuals import Markers
 from copy import copy
 from copy import copy
@@ -110,6 +110,16 @@ class BufferSelectionTool(FlatCAMTool):
         # Init GUI
         # Init GUI
         self.buffer_distance_entry.set_value(0.01)
         self.buffer_distance_entry.set_value(0.01)
 
 
+    def run(self):
+        self.app.report_usage("Geo Editor ToolBuffer()")
+        FlatCAMTool.run(self)
+
+        # if the splitter us hidden, display it
+        if self.app.ui.splitter.sizes()[0] == 0:
+            self.app.ui.splitter.setSizes([1, 1])
+
+        self.app.ui.notebook.setTabText(2, "Buffer Tool")
+
     def on_buffer(self):
     def on_buffer(self):
         try:
         try:
             buffer_distance = float(self.buffer_distance_entry.get_value())
             buffer_distance = float(self.buffer_distance_entry.get_value())
@@ -426,6 +436,7 @@ class PaintOptionsTool(FlatCAMTool):
         )
         )
         grid.addWidget(ovlabel, 1, 0)
         grid.addWidget(ovlabel, 1, 0)
         self.paintoverlap_entry = FCEntry()
         self.paintoverlap_entry = FCEntry()
+        self.paintoverlap_entry.setValidator(QtGui.QDoubleValidator(0.0000, 1.0000, 4))
         grid.addWidget(self.paintoverlap_entry, 1, 1)
         grid.addWidget(self.paintoverlap_entry, 1, 1)
 
 
         # Margin
         # Margin
@@ -1237,9 +1248,10 @@ class TransformEditorTool(FlatCAMTool):
                         py = 0.5 * (yminimal + ymaximal)
                         py = 0.5 * (yminimal + ymaximal)
 
 
                         sel_sha.rotate(-num, point=(px, py))
                         sel_sha.rotate(-num, point=(px, py))
-                        self.draw_app.add_shape(DrawToolShape(sel_sha.geo))
+                        self.draw_app.replot()
+                        # self.draw_app.add_shape(DrawToolShape(sel_sha.geo))
 
 
-                    self.draw_app.transform_complete.emit()
+                    # self.draw_app.transform_complete.emit()
 
 
                     self.app.inform.emit("[success] Done. Rotate completed.")
                     self.app.inform.emit("[success] Done. Rotate completed.")
 
 
@@ -1294,9 +1306,11 @@ class TransformEditorTool(FlatCAMTool):
                         elif axis is 'Y':
                         elif axis is 'Y':
                             sha.mirror('Y', (px, py))
                             sha.mirror('Y', (px, py))
                             self.app.inform.emit('[success] Flip on the X axis done ...')
                             self.app.inform.emit('[success] Flip on the X axis done ...')
-                        self.draw_app.add_shape(DrawToolShape(sha.geo))
+                        self.draw_app.replot()
 
 
-                    self.draw_app.transform_complete.emit()
+                    #     self.draw_app.add_shape(DrawToolShape(sha.geo))
+                    #
+                    # self.draw_app.transform_complete.emit()
 
 
                     self.app.progress.emit(100)
                     self.app.progress.emit(100)
 
 
@@ -1332,9 +1346,11 @@ class TransformEditorTool(FlatCAMTool):
                             sha.skew(num, 0, point=(xminimal, yminimal))
                             sha.skew(num, 0, point=(xminimal, yminimal))
                         elif axis is 'Y':
                         elif axis is 'Y':
                             sha.skew(0, num, point=(xminimal, yminimal))
                             sha.skew(0, num, point=(xminimal, yminimal))
-                        self.draw_app.add_shape(DrawToolShape(sha.geo))
+                        self.draw_app.replot()
 
 
-                    self.draw_app.transform_complete.emit()
+                    #     self.draw_app.add_shape(DrawToolShape(sha.geo))
+                    #
+                    # self.draw_app.transform_complete.emit()
 
 
                     self.app.inform.emit('[success] Skew on the %s axis done ...' % str(axis))
                     self.app.inform.emit('[success] Skew on the %s axis done ...' % str(axis))
                     self.app.progress.emit(100)
                     self.app.progress.emit(100)
@@ -1381,9 +1397,11 @@ class TransformEditorTool(FlatCAMTool):
 
 
                     for sha in shape_list:
                     for sha in shape_list:
                         sha.scale(xfactor, yfactor, point=(px, py))
                         sha.scale(xfactor, yfactor, point=(px, py))
-                        self.draw_app.add_shape(DrawToolShape(sha.geo))
+                        self.draw_app.replot()
 
 
-                    self.draw_app.transform_complete.emit()
+                    #     self.draw_app.add_shape(DrawToolShape(sha.geo))
+                    #
+                    # self.draw_app.transform_complete.emit()
 
 
                     self.app.inform.emit('[success] Scale on the %s axis done ...' % str(axis))
                     self.app.inform.emit('[success] Scale on the %s axis done ...' % str(axis))
                     self.app.progress.emit(100)
                     self.app.progress.emit(100)
@@ -1418,9 +1436,11 @@ class TransformEditorTool(FlatCAMTool):
                             sha.offset((num, 0))
                             sha.offset((num, 0))
                         elif axis is 'Y':
                         elif axis is 'Y':
                             sha.offset((0, num))
                             sha.offset((0, num))
-                        self.draw_app.add_shape(DrawToolShape(sha.geo))
+                        self.draw_app.replot()
 
 
-                    self.draw_app.transform_complete.emit()
+                    #     self.draw_app.add_shape(DrawToolShape(sha.geo))
+                    #
+                    # self.draw_app.transform_complete.emit()
 
 
                     self.app.inform.emit('[success] Offset on the %s axis done ...' % str(axis))
                     self.app.inform.emit('[success] Offset on the %s axis done ...' % str(axis))
                     self.app.progress.emit(100)
                     self.app.progress.emit(100)
@@ -1429,6 +1449,90 @@ class TransformEditorTool(FlatCAMTool):
                     self.app.inform.emit("[ERROR_NOTCL] Due of %s, Offset action was not executed." % str(e))
                     self.app.inform.emit("[ERROR_NOTCL] Due of %s, Offset action was not executed." % str(e))
                     return
                     return
 
 
+    def on_rotate_key(self):
+        val_box = FCInputDialog(title="Rotate ...",
+                                text='Enter an Angle Value (degrees):',
+                                min=-359.9999, max=360.0000, decimals=4)
+        val_box.setWindowIcon(QtGui.QIcon('share/rotate.png'))
+
+        val, ok = val_box.get_value()
+        if ok:
+            self.on_rotate(val=val)
+            self.app.inform.emit(
+                "[success] Geometry shape rotate done...")
+            return
+        else:
+            self.app.inform.emit(
+                "[WARNING_NOTCL] Geometry shape rotate cancelled...")
+
+    def on_offx_key(self):
+        units = self.app.general_options_form.general_app_group.units_radio.get_value().lower()
+
+        val_box = FCInputDialog(title="Offset on X axis ...",
+                                text=('Enter a distance Value (%s):' % str(units)),
+                                min=-9999.9999, max=10000.0000, decimals=4)
+        val_box.setWindowIcon(QtGui.QIcon('share/offsetx32.png'))
+
+        val, ok = val_box.get_value()
+        if ok:
+            self.on_offx(val=val)
+            self.app.inform.emit(
+                "[success] Geometry shape offset on X axis done...")
+            return
+        else:
+            self.app.inform.emit(
+                "[WARNING_NOTCL] Geometry shape offset X cancelled...")
+
+    def on_offy_key(self):
+        units = self.app.general_options_form.general_app_group.units_radio.get_value().lower()
+
+        val_box = FCInputDialog(title="Offset on Y axis ...",
+                                text=('Enter a distance Value (%s):' % str(units)),
+                                min=-9999.9999, max=10000.0000, decimals=4)
+        val_box.setWindowIcon(QtGui.QIcon('share/offsety32.png'))
+
+        val, ok = val_box.get_value()
+        if ok:
+            self.on_offx(val=val)
+            self.app.inform.emit(
+                "[success] Geometry shape offset on Y axis done...")
+            return
+        else:
+            self.app.inform.emit(
+                "[WARNING_NOTCL] Geometry shape offset Y cancelled...")
+
+    def on_skewx_key(self):
+        val_box = FCInputDialog(title="Skew on X axis ...",
+                                text='Enter an Angle Value (degrees):',
+                                min=-359.9999, max=360.0000, decimals=4)
+        val_box.setWindowIcon(QtGui.QIcon('share/skewX.png'))
+
+        val, ok = val_box.get_value()
+        if ok:
+            self.on_skewx(val=val)
+            self.app.inform.emit(
+                "[success] Geometry shape skew on X axis done...")
+            return
+        else:
+            self.app.inform.emit(
+                "[WARNING_NOTCL] Geometry shape skew X cancelled...")
+
+    def on_skewy_key(self):
+        val_box = FCInputDialog(title="Skew on Y axis ...",
+                                text='Enter an Angle Value (degrees):',
+                                min=-359.9999, max=360.0000, decimals=4)
+        val_box.setWindowIcon(QtGui.QIcon('share/skewY.png'))
+
+        val, ok = val_box.get_value()
+        if ok:
+            self.on_skewx(val=val)
+            self.app.inform.emit(
+                "[success] Geometry shape skew on Y axis done...")
+            return
+        else:
+            self.app.inform.emit(
+                "[WARNING_NOTCL] Geometry shape skew Y cancelled...")
+
 
 
 class DrawToolShape(object):
 class DrawToolShape(object):
     """
     """
@@ -2620,57 +2724,6 @@ class FCTransform(FCShapeTool):
         self.draw_app.transform_tool.run()
         self.draw_app.transform_tool.run()
 
 
 
 
-class FCRotate(FCShapeTool):
-    def __init__(self, draw_app):
-        FCShapeTool.__init__(self, draw_app)
-        self.name = 'rotate'
-
-        if self.draw_app.launched_from_shortcuts is True:
-            self.draw_app.launched_from_shortcuts = False
-            self.set_origin(
-                self.draw_app.snap(self.draw_app.x, self.draw_app.y))
-
-        geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y))
-
-        if isinstance(geo, DrawToolShape) and geo.geo is not None:
-            self.draw_app.draw_utility_geometry(geo=geo)
-
-        self.draw_app.app.inform.emit("Click anywhere to finish the Rotation")
-
-    def set_origin(self, origin):
-        self.origin = origin
-
-    def make(self):
-        # Create new geometry
-        # dx = self.origin[0]
-        # dy = self.origin[1]
-        self.geometry = [DrawToolShape(affinity.rotate(geom.geo, angle = -90, origin='center'))
-                         for geom in self.draw_app.get_selected()]
-        # Delete old
-        self.draw_app.delete_selected()
-        self.complete = True
-        self.draw_app.app.inform.emit("[success]Done. Geometry rotate completed.")
-
-    def on_key(self, key):
-        if key == 'Enter' or key == QtCore.Qt.Key_Enter:
-            self.make()
-            return "Done"
-
-    def click(self, point):
-        self.make()
-        return "Done."
-
-    def utility_geometry(self, data=None):
-        """
-        Temporary geometry on screen while using this tool.
-
-        :param data:
-        :return:
-        """
-        return DrawToolUtilityShape([affinity.rotate(geom.geo, angle = -90, origin='center')
-                                     for geom in self.draw_app.get_selected()])
-
-
 class FCDrillAdd(FCShapeTool):
 class FCDrillAdd(FCShapeTool):
     """
     """
     Resulting type: MultiLineString
     Resulting type: MultiLineString
@@ -3244,8 +3297,6 @@ class FlatCAMGeoEditor(QtCore.QObject):
                        "constructor": FCPaint},
                        "constructor": FCPaint},
             "move": {"button": self.app.ui.geo_move_btn,
             "move": {"button": self.app.ui.geo_move_btn,
                      "constructor": FCMove},
                      "constructor": FCMove},
-            "rotate": {"button": self.app.ui.geo_rotate_btn,
-                     "constructor": FCRotate},
             "transform": {"button": self.app.ui.geo_transform_btn,
             "transform": {"button": self.app.ui.geo_transform_btn,
                       "constructor": FCTransform},
                       "constructor": FCTransform},
             "copy": {"button": self.app.ui.geo_copy_btn,
             "copy": {"button": self.app.ui.geo_copy_btn,
@@ -4459,9 +4510,9 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
 
         results = []
         results = []
 
 
-        if tooldia <= overlap:
+        if overlap >= 1:
             self.app.inform.emit(
             self.app.inform.emit(
-                "[ERROR_NOTCL] Could not do Paint. Overlap value has to be less than Tool Dia value.")
+                "[ERROR_NOTCL] Could not do Paint. Overlap value has to be less than 1.00 (100%).")
             return
             return
 
 
         def recurse(geometry, reset=True):
         def recurse(geometry, reset=True):

+ 148 - 34
FlatCAMGUI.py

@@ -568,12 +568,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.geo_edit_toolbar.addSeparator()
         self.geo_edit_toolbar.addSeparator()
         self.geo_cutpath_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path')
         self.geo_cutpath_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path')
         self.geo_copy_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Shape(s)")
         self.geo_copy_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Shape(s)")
-        self.geo_rotate_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/rotate.png'), "Rotate Shape(s)")
-        self.geo_transform_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/transform.png'), "Transformations'")
 
 
         self.geo_delete_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'),
         self.geo_delete_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'),
                                                               "Delete Shape '-'")
                                                               "Delete Shape '-'")
-
+        self.geo_transform_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/transform.png'), "Transformations")
         self.geo_edit_toolbar.addSeparator()
         self.geo_edit_toolbar.addSeparator()
         self.geo_move_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects ")
         self.geo_move_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects ")
 
 
@@ -1143,6 +1141,38 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 			<td height="20"><strong>U</strong></td>
 			<td height="20"><strong>U</strong></td>
 			<td>&nbsp;Polygon Union Tool</td>
 			<td>&nbsp;Polygon Union Tool</td>
 		</tr>
 		</tr>
+		<tr height="20">
+			<td height="20"><strong>X</strong></td>
+			<td>&nbsp;Flip shape on X axis</td>
+		</tr>
+		<tr height="20">
+			<td height="20"><strong>Y</strong></td>
+			<td>&nbsp;Flip shape on Y axis</td>
+		</tr>
+		<tr height="20">
+			<td height="20">&nbsp;</td>
+			<td>&nbsp;</td>
+		</tr>
+        <tr height="20">
+			<td height="20"><strong>SHIFT+X</strong></td>
+			<td>&nbsp;Skew shape on X axis</td>
+		</tr>
+		<tr height="20">
+			<td height="20"><strong>SHIFT+Y</strong></td>
+			<td>&nbsp;Skew shape on Y axis</td>
+		</tr>
+		<tr height="20">
+			<td height="20">&nbsp;</td>
+			<td>&nbsp;</td>
+		</tr>
+        <tr height="20">
+			<td height="20"><strong>ALT+X</strong></td>
+			<td>&nbsp;Offset shape on X axis</td>
+		</tr>
+		<tr height="20">
+			<td height="20"><strong>ALT+Y</strong></td>
+			<td>&nbsp;Offset shape on Y axis</td>
+		</tr>
 		<tr height="20">
 		<tr height="20">
 			<td height="20">&nbsp;</td>
 			<td height="20">&nbsp;</td>
 			<td>&nbsp;</td>
 			<td>&nbsp;</td>
@@ -1491,7 +1521,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.shell_btn = self.toolbartools.addAction(QtGui.QIcon('share/shell32.png'), "&Command Line")
         self.shell_btn = self.toolbartools.addAction(QtGui.QIcon('share/shell32.png'), "&Command Line")
 
 
         ### Drill Editor Toolbar ###
         ### Drill Editor Toolbar ###
-        self.select_drill_btn = self.exc_edit_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), "Select 'Esc'")
+        self.select_drill_btn = self.exc_edit_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), "Select")
         self.add_drill_btn = self.exc_edit_toolbar.addAction(QtGui.QIcon('share/plus16.png'), 'Add Drill Hole')
         self.add_drill_btn = self.exc_edit_toolbar.addAction(QtGui.QIcon('share/plus16.png'), 'Add Drill Hole')
         self.add_drill_array_btn = self.exc_edit_toolbar.addAction(
         self.add_drill_array_btn = self.exc_edit_toolbar.addAction(
             QtGui.QIcon('share/addarray16.png'), 'Add Drill Hole Array')
             QtGui.QIcon('share/addarray16.png'), 'Add Drill Hole Array')
@@ -1526,12 +1556,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
 
         self.geo_edit_toolbar.addSeparator()
         self.geo_edit_toolbar.addSeparator()
         self.geo_cutpath_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path')
         self.geo_cutpath_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path')
-        self.geo_copy_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Objects 'c'")
-        self.geo_rotate_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/rotate.png'), "Rotate Objects 'Space'")
-        self.geo_delete_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'), "Delete Shape '-'")
+        self.geo_copy_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Objects")
+        self.geo_delete_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'), "Delete Shape")
+        self.geo_transform_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/transform.png'), "Transformations")
 
 
         self.geo_edit_toolbar.addSeparator()
         self.geo_edit_toolbar.addSeparator()
-        self.geo_move_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects 'm'")
+        self.geo_move_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects")
 
 
         ### Snap Toolbar ###
         ### Snap Toolbar ###
         # Snap GRID toolbar is always active to facilitate usage of measurements done on GRID
         # Snap GRID toolbar is always active to facilitate usage of measurements done on GRID
@@ -1908,7 +1938,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     return
                     return
 
 
             elif modifiers == QtCore.Qt.ShiftModifier:
             elif modifiers == QtCore.Qt.ShiftModifier:
-                pass
+                # Skew on X axis
+                if key == QtCore.Qt.Key_X or key == 'X':
+                    self.app.geo_editor.transform_tool.on_skewx_key()
+                    return
+
+                # Skew on Y axis
+                if key == QtCore.Qt.Key_Y or key == 'Y':
+                    self.app.geo_editor.transform_tool.on_skewy_key()
+                    return
             elif modifiers == QtCore.Qt.AltModifier:
             elif modifiers == QtCore.Qt.AltModifier:
 
 
                 # Transformation Tool
                 # Transformation Tool
@@ -1916,6 +1954,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.geo_editor.select_tool('transform')
                     self.app.geo_editor.select_tool('transform')
                     return
                     return
 
 
+                # Offset on X axis
+                if key == QtCore.Qt.Key_X or key == 'X':
+                    self.app.geo_editor.transform_tool.on_offx_key()
+                    return
+
+                # Offset on Y axis
+                if key == QtCore.Qt.Key_Y or key == 'Y':
+                    self.app.geo_editor.transform_tool.on_offy_key()
+                    return
             elif modifiers == QtCore.Qt.NoModifier:
             elif modifiers == QtCore.Qt.NoModifier:
                 # toggle display of Notebook area
                 # toggle display of Notebook area
                 if key == QtCore.Qt.Key_QuoteLeft or key == '`':
                 if key == QtCore.Qt.Key_QuoteLeft or key == '`':
@@ -1971,9 +2018,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
 
                 # Move
                 # Move
                 if key == QtCore.Qt.Key_Space or key == 'Space':
                 if key == QtCore.Qt.Key_Space or key == 'Space':
-                    self.app.geo_editor.launched_from_shortcuts = True
-                    self.app.ui.geo_rotate_btn.setChecked(True)
-                    self.app.geo_editor.on_tool_select('rotate')
+                    self.app.geo_editor.transform_tool.on_rotate_key()
 
 
                 if key == QtCore.Qt.Key_Minus or key == '-':
                 if key == QtCore.Qt.Key_Minus or key == '-':
                     self.app.plotcanvas.zoom(1 / self.app.defaults['zoom_ratio'],
                     self.app.plotcanvas.zoom(1 / self.app.defaults['zoom_ratio'],
@@ -2104,6 +2149,16 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 if key == QtCore.Qt.Key_V or key == 'V':
                 if key == QtCore.Qt.Key_V or key == 'V':
                     self.app.on_zoom_fit(None)
                     self.app.on_zoom_fit(None)
 
 
+                # Flip on X axis
+                if key == QtCore.Qt.Key_X or key == 'X':
+                    self.app.geo_editor.transform_tool.on_flipx()
+                    return
+
+                # Flip on Y axis
+                if key == QtCore.Qt.Key_Y or key == 'Y':
+                    self.app.geo_editor.transform_tool.on_flipy()
+                    return
+
                 # Propagate to tool
                 # Propagate to tool
                 response = None
                 response = None
                 if self.app.geo_editor.active_tool is not None:
                 if self.app.geo_editor.active_tool is not None:
@@ -2374,7 +2429,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         grect = self.geometry()
         grect = self.geometry()
 
 
         # self.splitter.sizes()[0] is actually the size of the "notebook"
         # self.splitter.sizes()[0] is actually the size of the "notebook"
-        self.geom_update.emit(grect.x(), grect.y(), grect.width(), grect.height(), self.splitter.sizes()[0])
+        if not self.isMaximized():
+            self.geom_update.emit(grect.x(), grect.y(), grect.width(), grect.height(), self.splitter.sizes()[0])
+
         self.final_save.emit()
         self.final_save.emit()
 
 
         if self.app.should_we_quit is True:
         if self.app.should_we_quit is True:
@@ -2387,6 +2444,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
             # save toolbar state to file
             # save toolbar state to file
             settings = QSettings("Open Source", "FlatCAM")
             settings = QSettings("Open Source", "FlatCAM")
             settings.setValue('saved_gui_state', self.saveState())
             settings.setValue('saved_gui_state', self.saveState())
+            settings.setValue('maximized_gui', self.isMaximized())
 
 
             # This will write the setting to the platform specific storage.
             # This will write the setting to the platform specific storage.
             del settings
             del settings
@@ -2409,8 +2467,13 @@ class GeneralPreferencesUI(QtWidgets.QWidget):
         self.general_gui_group = GeneralGUIPrefGroupUI()
         self.general_gui_group = GeneralGUIPrefGroupUI()
         self.general_gui_group.setFixedWidth(250)
         self.general_gui_group.setFixedWidth(250)
 
 
+        self.general_gui_set_group = GeneralGUISetGroupUI()
+        self.general_gui_set_group.setFixedWidth(250)
+
         self.layout.addWidget(self.general_app_group)
         self.layout.addWidget(self.general_app_group)
         self.layout.addWidget(self.general_gui_group)
         self.layout.addWidget(self.general_gui_group)
+        self.layout.addWidget(self.general_gui_set_group)
+
         self.layout.addStretch()
         self.layout.addStretch()
 
 
 
 
@@ -2774,6 +2837,48 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         self.form_box_child_11.addWidget(self.sel_draw_color_button)
         self.form_box_child_11.addWidget(self.sel_draw_color_button)
         self.form_box_child_11.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
         self.form_box_child_11.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
 
 
+        # Just to add empty rows
+        self.spacelabel = QtWidgets.QLabel('')
+
+        # Add (label - input field) pair to the QFormLayout
+        self.form_box.addRow(self.spacelabel, self.spacelabel)
+
+        self.form_box.addRow(self.gridx_label, self.gridx_entry)
+        self.form_box.addRow(self.gridy_label, self.gridy_entry)
+        self.form_box.addRow(self.snap_max_label, self.snap_max_dist_entry)
+
+        self.form_box.addRow(self.workspace_lbl, self.workspace_cb)
+        self.form_box.addRow(self.workspace_type_lbl, self.wk_cb)
+        self.form_box.addRow(self.spacelabel, self.spacelabel)
+        self.form_box.addRow(self.pf_color_label, self.form_box_child_1)
+        self.form_box.addRow(self.pf_alpha_label, self.form_box_child_2)
+        self.form_box.addRow(self.pl_color_label, self.form_box_child_3)
+        self.form_box.addRow(self.sf_color_label, self.form_box_child_4)
+        self.form_box.addRow(self.sf_alpha_label, self.form_box_child_5)
+        self.form_box.addRow(self.sl_color_label, self.form_box_child_6)
+        self.form_box.addRow(self.alt_sf_color_label, self.form_box_child_7)
+        self.form_box.addRow(self.alt_sf_alpha_label, self.form_box_child_8)
+        self.form_box.addRow(self.alt_sl_color_label, self.form_box_child_9)
+        self.form_box.addRow(self.draw_color_label, self.form_box_child_10)
+        self.form_box.addRow(self.sel_draw_color_label, self.form_box_child_11)
+
+        self.form_box.addRow(self.spacelabel, self.spacelabel)
+
+        # Add the QFormLayout that holds the Application general defaults
+        # to the main layout of this TAB
+        self.layout.addLayout(self.form_box)
+
+
+class GeneralGUISetGroupUI(OptionsGroupUI):
+    def __init__(self, parent=None):
+        super(GeneralGUISetGroupUI, self).__init__(self)
+
+        self.setTitle(str("GUI Settings"))
+
+        # Create a form layout for the Application general settings
+        self.form_box = QtWidgets.QFormLayout()
+
+
         # Layout selection
         # Layout selection
         self.layout_label = QtWidgets.QLabel('Layout:')
         self.layout_label = QtWidgets.QLabel('Layout:')
         self.layout_label.setToolTip(
         self.layout_label.setToolTip(
@@ -2813,35 +2918,24 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
             self.hdpi_cb.set_value(False)
             self.hdpi_cb.set_value(False)
         self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
         self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
 
 
+        # Clear Settings
+        self.clear_label = QtWidgets.QLabel('Clear GUI Settings:')
+        self.clear_label.setToolTip(
+            "Clear the GUI settings for FlatCAM,\n"
+            "such as: layout, gui state, style, hdpi support etc."
+        )
+        self.clear_btn = FCButton("Clear")
+        self.clear_btn.clicked.connect(self.handle_clear)
         # Just to add empty rows
         # Just to add empty rows
         self.spacelabel = QtWidgets.QLabel('')
         self.spacelabel = QtWidgets.QLabel('')
 
 
         # Add (label - input field) pair to the QFormLayout
         # Add (label - input field) pair to the QFormLayout
         self.form_box.addRow(self.spacelabel, self.spacelabel)
         self.form_box.addRow(self.spacelabel, self.spacelabel)
 
 
-        self.form_box.addRow(self.gridx_label, self.gridx_entry)
-        self.form_box.addRow(self.gridy_label, self.gridy_entry)
-        self.form_box.addRow(self.snap_max_label, self.snap_max_dist_entry)
-
-        self.form_box.addRow(self.workspace_lbl, self.workspace_cb)
-        self.form_box.addRow(self.workspace_type_lbl, self.wk_cb)
-        self.form_box.addRow(self.spacelabel, self.spacelabel)
-        self.form_box.addRow(self.pf_color_label, self.form_box_child_1)
-        self.form_box.addRow(self.pf_alpha_label, self.form_box_child_2)
-        self.form_box.addRow(self.pl_color_label, self.form_box_child_3)
-        self.form_box.addRow(self.sf_color_label, self.form_box_child_4)
-        self.form_box.addRow(self.sf_alpha_label, self.form_box_child_5)
-        self.form_box.addRow(self.sl_color_label, self.form_box_child_6)
-        self.form_box.addRow(self.alt_sf_color_label, self.form_box_child_7)
-        self.form_box.addRow(self.alt_sf_alpha_label, self.form_box_child_8)
-        self.form_box.addRow(self.alt_sl_color_label, self.form_box_child_9)
-        self.form_box.addRow(self.draw_color_label, self.form_box_child_10)
-        self.form_box.addRow(self.sel_draw_color_label, self.form_box_child_11)
-
-        self.form_box.addRow(self.spacelabel, self.spacelabel)
         self.form_box.addRow(self.layout_label, self.layout_combo)
         self.form_box.addRow(self.layout_label, self.layout_combo)
         self.form_box.addRow(self.style_label, self.style_combo)
         self.form_box.addRow(self.style_label, self.style_combo)
         self.form_box.addRow(self.hdpi_label, self.hdpi_cb)
         self.form_box.addRow(self.hdpi_label, self.hdpi_cb)
+        self.form_box.addRow(self.clear_label, self.clear_btn)
 
 
         # Add the QFormLayout that holds the Application general defaults
         # Add the QFormLayout that holds the Application general defaults
         # to the main layout of this TAB
         # to the main layout of this TAB
@@ -2856,13 +2950,33 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
         del settings
         del settings
 
 
     def handle_hdpi(self, state):
     def handle_hdpi(self, state):
-        # set current style
+        # set current HDPI
         settings = QSettings("Open Source", "FlatCAM")
         settings = QSettings("Open Source", "FlatCAM")
         settings.setValue('hdpi', state)
         settings.setValue('hdpi', state)
 
 
         # This will write the setting to the platform specific storage.
         # This will write the setting to the platform specific storage.
         del settings
         del settings
 
 
+    def handle_clear(self):
+        msgbox = QtWidgets.QMessageBox()
+        # msgbox.setText("<B>Save changes ...</B>")
+        msgbox.setText("Are you sure you want to delete the GUI Settings? "
+                       "\n"
+                       )
+        msgbox.setWindowTitle("Clear GUI Settings")
+        msgbox.setWindowIcon(QtGui.QIcon('share/trash32.png'))
+        msgbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
+        msgbox.setDefaultButton(QtWidgets.QMessageBox.No)
+
+        response = msgbox.exec_()
+
+        if response == QtWidgets.QMessageBox.Yes:
+            settings = QSettings("Open Source", "FlatCAM")
+            for key in settings.allKeys():
+                settings.remove(key)
+            # This will write the setting to the platform specific storage.
+            del settings
+            self.app.inform.emit("[success] GUI settings deleted ...")
 
 
 class GeneralAppPrefGroupUI(OptionsGroupUI):
 class GeneralAppPrefGroupUI(OptionsGroupUI):
     def __init__(self, parent=None):
     def __init__(self, parent=None):

+ 7 - 0
PlotCanvas.py

@@ -198,6 +198,13 @@ class PlotCanvas(QtCore.QObject):
             except TypeError:
             except TypeError:
                 pass
                 pass
 
 
+        # adjust the view camera to be slightly bigger than the bounds so the shape colleaction can be seen clearly
+        # otherwise the shape collection boundary will have no border
+        rect.left *= 0.96
+        rect.bottom *= 0.96
+        rect.right *= 1.01
+        rect.top *= 1.01
+
         self.vispy_canvas.view.camera.rect = rect
         self.vispy_canvas.view.camera.rect = rect
 
 
         self.shape_collection.unlock_updates()
         self.shape_collection.unlock_updates()

+ 5 - 1
README.md

@@ -20,7 +20,11 @@ CAD program, and create G-Code for Isolation routing.
 - finished adding Transform Tool in Geometry Editor - everything is working as intended
 - finished adding Transform Tool in Geometry Editor - everything is working as intended
 - fixed a bug in Tool Transform that made the user to not be able to capture the click coordinates with SHIFT + LMB click combo
 - fixed a bug in Tool Transform that made the user to not be able to capture the click coordinates with SHIFT + LMB click combo
 - added the ability to choose an App QStyle out of the offered choices (different for each OS) to be applied at the next app start (Preferences -> General -> Gui Pref -> Style Combobox)
 - added the ability to choose an App QStyle out of the offered choices (different for each OS) to be applied at the next app start (Preferences -> General -> Gui Pref -> Style Combobox)
-- added support for FlatCAM usage with High DPI monitors (4k). It is applied on the next app startup after change in Preferences -> General -> Gui Pref -> HDPI Support Checkbox
+- added support for FlatCAM usage with High DPI monitors (4k). It is applied on the next app startup after change in Preferences -> General -> Gui Settings -> HDPI Support Checkbox
+- made the app not remember the window size if the app is maximized and remember in QSettings if it was maximized. This way we can restore the maximized state but restore the windows size unmaximized
+- added a button to clear de GUI preferences in Preferences -> General -> Gui Settings -> Clear GUI Settings
+- added key shortcuts for the shape transformations within Geometry Editor: X, Y keys for Flip(mirror), SHIFT+X, SHIFT+Y combo keys for Skew and ALT+X, ALT+Y combo keys for Offset
+- adjusted the plotcanvas.zomm_fit() function so the objects are better fit into view (with a border around) 
 
 
 17.02.2019
 17.02.2019
 
 

BIN
share/offsetx32.png


BIN
share/offsety32.png