Parcourir la source

- added a dark theme to FlatCAM (only for canvas). The selection is done in Edit -> Preferences -> General -> GUI Settings

Marius Stanciu il y a 6 ans
Parent
commit
23da38d8f3

+ 28 - 3
FlatCAMApp.py

@@ -424,6 +424,17 @@ class App(QtCore.QObject):
 
         self.ui = FlatCAMGUI(self.version, self.beta, self)
 
+        settings = QtCore.QSettings("Open Source", "FlatCAM")
+        if settings.contains("theme"):
+            theme = settings.value('theme', type=str)
+        else:
+            theme = 'white'
+
+        if theme == 'white':
+            self.cursor_color_3D = 'black'
+        else:
+            self.cursor_color_3D = 'gray'
+
         self.ui.geom_update[int, int, int, int, int].connect(self.save_geometry)
         self.ui.final_save.connect(self.final_save)
 
@@ -484,6 +495,7 @@ class App(QtCore.QObject):
             "global_activity_icon": self.ui.general_defaults_form.general_gui_group.activity_combo,
 
             # General GUI Settings
+            "global_theme": self.ui.general_defaults_form.general_gui_set_group.theme_radio,
             "global_layout": self.ui.general_defaults_form.general_gui_set_group.layout_combo,
             "global_hover": self.ui.general_defaults_form.general_gui_set_group.hover_cb,
             "global_selection_shape": self.ui.general_defaults_form.general_gui_set_group.selection_cb,
@@ -918,6 +930,7 @@ class App(QtCore.QObject):
             "global_zdownrate": None,
 
             # General GUI Settings
+            "global_theme": 'white',
             "global_hover": False,
             "global_selection_shape": True,
             "global_layout": "compact",
@@ -1996,6 +2009,7 @@ class App(QtCore.QObject):
         # ############ GUI SETTINGS SIGNALS ###############
         # #################################################
 
+        self.ui.general_defaults_form.general_gui_set_group.theme_radio.activated_custom.connect(self.on_theme_change)
         self.ui.general_defaults_form.general_gui_set_group.cursor_radio.activated_custom.connect(self.on_cursor_type)
 
         # ########## CNC Job related signals #############
@@ -2824,6 +2838,15 @@ class App(QtCore.QObject):
                                 name)
                                )
 
+    def on_theme_change(self, val):
+        settings = QSettings("Open Source", "FlatCAM")
+        settings.setValue('theme', val)
+
+        # This will write the setting to the platform specific storage.
+        del settings
+
+        self.on_app_restart()
+
     def on_app_restart(self):
 
         # make sure that the Sys Tray icon is hidden before restart otherwise it will
@@ -2831,7 +2854,7 @@ class App(QtCore.QObject):
         try:
             self.trayIcon.hide()
         except Exception as e:
-            log.debug("App.on_app_restart() --> %s" % str(e))
+           pass
 
         fcTranslate.restart_program(app=self)
 
@@ -6958,7 +6981,8 @@ class App(QtCore.QObject):
         if self.grid_status() == True:
             # Update cursor
             self.app_cursor.set_data(np.asarray([(location[0], location[1])]),
-                                     symbol='++', edge_color='black', size=self.defaults["global_cursor_size"])
+                                     symbol='++', edge_color=self.cursor_color_3D,
+                                     size=self.defaults["global_cursor_size"])
 
         # Set the position label
         self.ui.position_label.setText("&nbsp;&nbsp;&nbsp;&nbsp;<b>X</b>: %.4f&nbsp;&nbsp;   "
@@ -7936,7 +7960,8 @@ class App(QtCore.QObject):
 
                     # Update cursor
                     self.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
-                                             symbol='++', edge_color='black', size=self.defaults["global_cursor_size"])
+                                             symbol='++', edge_color=self.cursor_color_3D,
+                                             size=self.defaults["global_cursor_size"])
                 else:
                     pos = (pos_canvas[0], pos_canvas[1])
 

+ 1 - 0
README.md

@@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing.
 
 - fixed an conflict in a signal usage that was triggered by Tool SolderPaste when a new project was created
 - updated Optimal Tool to display both points coordinates that made a distance (and the minimum) not only the middle point (which is still the place where the jump happen)
+- added a dark theme to FlatCAM (only for canvas). The selection is done in Edit -> Preferences -> General -> GUI Settings
 
 6.10.2019
 

+ 2 - 2
flatcamEditors/FlatCAMExcEditor.py

@@ -3657,7 +3657,7 @@ class FlatCAMExcEditor(QtCore.QObject):
             x, y = self.app.geo_editor.snap(x, y)
 
             # Update cursor
-            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color='black',
+            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
                                          size=self.app.defaults["global_cursor_size"])
 
         self.snap_x = x
@@ -3706,7 +3706,7 @@ class FlatCAMExcEditor(QtCore.QObject):
             self.app.selection_type = None
 
         # Update cursor
-        self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color='black',
+        self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
                                      size=self.app.defaults["global_cursor_size"])
 
     def on_canvas_key_release(self, event):

+ 1 - 1
flatcamEditors/FlatCAMGeoEditor.py

@@ -3823,7 +3823,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
             x, y = self.snap(x, y)
 
             # Update cursor
-            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color='black',
+            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
                                          size=self.app.defaults["global_cursor_size"])
 
         self.snap_x = x

+ 1 - 1
flatcamEditors/FlatCAMGrbEditor.py

@@ -4446,7 +4446,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
             x, y = self.app.geo_editor.snap(x, y)
 
             # Update cursor
-            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color='black',
+            self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
                                          size=self.app.defaults["global_cursor_size"])
 
         self.snap_x = x

+ 16 - 3
flatcamGUI/PlotCanvas.py

@@ -9,7 +9,7 @@
 from PyQt5 import QtCore
 
 import logging
-from flatcamGUI.VisPyCanvas import VisPyCanvas, time
+from flatcamGUI.VisPyCanvas import VisPyCanvas, time, Color
 from flatcamGUI.VisPyVisuals import ShapeGroup, ShapeCollection, TextCollection, TextGroup, Cursor
 from vispy.scene.visuals import InfiniteLine, Line
 import numpy as np
@@ -44,6 +44,17 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
         # Parent container
         self.container = container
 
+        settings = QtCore.QSettings("Open Source", "FlatCAM")
+        if settings.contains("theme"):
+            theme = settings.value('theme', type=str)
+        else:
+            theme = 'white'
+
+        if theme == 'white':
+            self.line_color = (0.3, 0.0, 0.0, 1.0)
+        else:
+            self.line_color = (0.4, 0.4, 0.4, 1.0)
+
         # workspace lines; I didn't use the rectangle because I didn't want to add another VisPy Node,
         # which might decrease performance
         self.b_line, self.r_line, self.t_line, self.l_line = None, None, None, None
@@ -68,7 +79,6 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
         self.draw_workspace()
 
         self.line_parent = None
-        self.line_color = (0.3, 0.0, 0.0, 1.0)
         self.cursor_v_line = InfiniteLine(pos=None, color=self.line_color, vertical=True,
                                           parent=self.line_parent)
 
@@ -328,7 +338,10 @@ class CursorBig(QtCore.QObject):
         if 'edge_color' in kwargs:
             color = kwargs['edge_color']
         else:
-            color = (0.0, 0.0, 0.0, 1.0)
+            if self.app.defaults['global_theme'] == 'white':
+                color = '#000000FF'
+            else:
+                color = '#FFFFFFFF'
 
         position = [pos[0][0], pos[0][1]]
         self.mouse_position_updated.emit(position)

+ 41 - 9
flatcamGUI/PlotCanvasLegacy.py

@@ -77,6 +77,11 @@ class CanvasCache(QtCore.QObject):
         self.axes.set_xticks([])
         self.axes.set_yticks([])
 
+        if self.app.defaults['global_theme'] == 'white':
+            self.axes.set_facecolor('#FFFFFF')
+        else:
+            self.axes.set_facecolor('#000000')
+
         self.canvas = FigureCanvas(self.figure)
 
         self.cache = None
@@ -140,6 +145,13 @@ class PlotCanvasLegacy(QtCore.QObject):
 
         self.app = app
 
+        if self.app.defaults['global_theme'] == 'white':
+            theme_color = '#FFFFFF'
+            tick_color = '#000000'
+        else:
+            theme_color = '#000000'
+            tick_color = '#FFFFFF'
+
         # Options
         self.x_margin = 15  # pixels
         self.y_margin = 25  # Pixels
@@ -149,16 +161,26 @@ class PlotCanvasLegacy(QtCore.QObject):
 
         # Plots go onto a single matplotlib.figure
         self.figure = Figure(dpi=50)  # TODO: dpi needed?
-        self.figure.patch.set_visible(False)
+        self.figure.patch.set_visible(True)
+        self.figure.set_facecolor(theme_color)
 
         # These axes show the ticks and grid. No plotting done here.
         # New axes must have a label, otherwise mpl returns an existing one.
         self.axes = self.figure.add_axes([0.05, 0.05, 0.9, 0.9], label="base", alpha=0.0)
         self.axes.set_aspect(1)
-        self.axes.grid(True)
+        self.axes.grid(True, color='gray')
         self.axes.axhline(color=(0.70, 0.3, 0.3), linewidth=2)
         self.axes.axvline(color=(0.70, 0.3, 0.3), linewidth=2)
 
+        self.axes.tick_params(axis='x', color=tick_color, labelcolor=tick_color)
+        self.axes.tick_params(axis='y', color=tick_color, labelcolor=tick_color)
+        self.axes.spines['bottom'].set_color(tick_color)
+        self.axes.spines['top'].set_color(tick_color)
+        self.axes.spines['right'].set_color(tick_color)
+        self.axes.spines['left'].set_color(tick_color)
+
+        self.axes.set_facecolor(theme_color)
+
         self.ch_line = None
         self.cv_line = None
 
@@ -264,10 +286,15 @@ class PlotCanvasLegacy(QtCore.QObject):
         # else:
         #     c = MplCursor(axes=axes, color='black', linewidth=1)
 
-        if  big is True:
+        if self.app.defaults['global_theme'] == 'white':
+            color = '#000000'
+        else:
+            color = '#FFFFFF'
+
+        if big is True:
             self.big_cursor = True
-            self.ch_line = self.axes.axhline(color=(0.0, 0.0, 0.0), linewidth=1)
-            self.cv_line = self.axes.axvline(color=(0.0, 0.0, 0.0), linewidth=1)
+            self.ch_line = self.axes.axhline(color=color, linewidth=1)
+            self.cv_line = self.axes.axvline(color=color, linewidth=1)
         else:
             self.big_cursor = False
 
@@ -286,6 +313,11 @@ class PlotCanvasLegacy(QtCore.QObject):
         """
         # there is no point in drawing mouse cursor when panning as it jumps in a confusing way
         if self.app.app_cursor.enabled is True and self.panning is False:
+            if self.app.defaults['global_theme'] == 'white':
+                color = '#000000'
+            else:
+                color = '#FFFFFF'
+
             if self.big_cursor is False:
                 try:
                     x, y = self.app.geo_editor.snap(x_pos, y_pos)
@@ -294,13 +326,13 @@ class PlotCanvasLegacy(QtCore.QObject):
                     # The size of the cursor is multiplied by 1.65 because that value made the cursor similar with the
                     # one in the OpenGL(3D) graphic engine
                     pointer_size = int(float(self.app.defaults["global_cursor_size"] ) * 1.65)
-                    elements = self.axes.plot(x, y, 'k+', ms=pointer_size, mew=1, animated=True)
+                    elements = self.axes.plot(x, y, '+', color=color, ms=pointer_size, mew=1, animated=True)
                     for el in elements:
                         self.axes.draw_artist(el)
                 except Exception as e:
                     # this happen at app initialization since self.app.geo_editor does not exist yet
-                    # I could reshuffle the object instantiating order but what's the point? I could crash something else
-                    # and that's pythonic, too
+                    # I could reshuffle the object instantiating order but what's the point?
+                    # I could crash something else and that's pythonic, too
                     pass
             else:
                 self.ch_line.set_ydata(y_pos)
@@ -476,7 +508,7 @@ class PlotCanvasLegacy(QtCore.QObject):
 
         # Adjust axes
         for ax in self.figure.get_axes():
-            ax.set_xlim((x - half_width , x + half_width))
+            ax.set_xlim((x - half_width, x + half_width))
             ax.set_ylim((y - half_height, y + half_height))
 
         # Re-draw

+ 77 - 30
flatcamGUI/PreferencesUI.py

@@ -557,6 +557,27 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         # Create a form layout for the Application general settings
         self.form_box = QtWidgets.QFormLayout()
 
+        grid0 = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid0)
+        grid0.setColumnStretch(0, 0)
+        grid0.setColumnStretch(1, 1)
+
+        grid0.addWidget(QtWidgets.QLabel(''), 0, 0)
+
+        # Theme selection
+        self.theme_label = QtWidgets.QLabel('%s:' % _('Theme'))
+        self.theme_label.setToolTip(
+            _("Select a theme for FlatCAM.\n"
+              "The application will restart after change.")
+        )
+        self.theme_radio = RadioSet([
+            {"label": _("White"), "value": "white"},
+            {"label": _("Dark"), "value": "black"}
+        ], orientation='horizontal', stretch=False)
+
+        grid0.addWidget(self.theme_label, 1, 0)
+        grid0.addWidget(self.theme_radio, 1, 1)
+
         # Layout selection
         self.layout_label = QtWidgets.QLabel('%s:' % _('Layout'))
         self.layout_label.setToolTip(
@@ -568,6 +589,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         self.layout_combo.addItem("standard")
         self.layout_combo.addItem("compact")
 
+        grid0.addWidget(self.layout_label, 2, 0)
+        grid0.addWidget(self.layout_combo, 2, 1)
+
         # Set the current index for layout_combo
         settings = QSettings("Open Source", "FlatCAM")
         if settings.contains("layout"):
@@ -588,6 +612,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         self.style_combo.setCurrentIndex(index)
         self.style_combo.activated[str].connect(self.handle_style)
 
+        grid0.addWidget(self.style_label, 3, 0)
+        grid0.addWidget(self.style_combo, 3, 1)
+
         # Enable High DPI Support
         self.hdpi_label = QtWidgets.QLabel('%s:' % _('HDPI Support'))
         self.hdpi_label.setToolTip(
@@ -603,6 +630,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
             self.hdpi_cb.set_value(False)
         self.hdpi_cb.stateChanged.connect(self.handle_hdpi)
 
+        grid0.addWidget(self.hdpi_label, 4, 0)
+        grid0.addWidget(self.hdpi_cb, 4, 1)
+
         # Clear Settings
         self.clear_label = QtWidgets.QLabel('%s:' % _('Clear GUI Settings'))
         self.clear_label.setToolTip(
@@ -612,6 +642,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         self.clear_btn = FCButton(_("Clear"))
         self.clear_btn.clicked.connect(self.handle_clear)
 
+        grid0.addWidget(self.clear_label, 5, 0)
+        grid0.addWidget(self.clear_btn, 5, 1)
+
         # Enable Hover box
         self.hover_label = QtWidgets.QLabel('%s:' % _('Hover Shape'))
         self.hover_label.setToolTip(
@@ -621,6 +654,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         )
         self.hover_cb = FCCheckBox()
 
+        grid0.addWidget(self.hover_label, 6, 0)
+        grid0.addWidget(self.hover_cb, 6, 1)
+
         # Enable Selection box
         self.selection_label = QtWidgets.QLabel('%s:' % _('Sel. Shape'))
         self.selection_label.setToolTip(
@@ -631,6 +667,11 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         )
         self.selection_cb = FCCheckBox()
 
+        grid0.addWidget(self.selection_label, 7, 0)
+        grid0.addWidget(self.selection_cb, 7, 1)
+
+        grid0.addWidget(QtWidgets.QLabel(''), 8, 0)
+
         # Notebook Font Size
         self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
         self.notebook_font_size_label.setToolTip(
@@ -649,6 +690,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.notebook_font_size_spinner.set_value(12)
 
+        grid0.addWidget(self.notebook_font_size_label, 9, 0)
+        grid0.addWidget(self.notebook_font_size_spinner, 9, 1)
+
         # Axis Font Size
         self.axis_font_size_label = QtWidgets.QLabel('%s:' % _('Axis Font Size'))
         self.axis_font_size_label.setToolTip(
@@ -665,6 +709,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.axis_font_size_spinner.set_value(8)
 
+        grid0.addWidget(self.axis_font_size_label, 10, 0)
+        grid0.addWidget(self.axis_font_size_spinner, 10, 1)
+
         # TextBox Font Size
         self.textbox_font_size_label = QtWidgets.QLabel('%s:' % _('Textbox Font Size'))
         self.textbox_font_size_label.setToolTip(
@@ -682,8 +729,11 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.textbox_font_size_spinner.set_value(10)
 
+        grid0.addWidget(self.textbox_font_size_label, 11, 0)
+        grid0.addWidget(self.textbox_font_size_spinner, 11, 1)
+
         # Just to add empty rows
-        self.spacelabel = QtWidgets.QLabel('')
+        grid0.addWidget(QtWidgets.QLabel(''), 12, 0)
 
         # Splash Screen
         self.splash_label = QtWidgets.QLabel('%s:' % _('Splash Screen'))
@@ -697,6 +747,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
             self.splash_cb.set_value(False)
 
+        grid0.addWidget(self.splash_label, 13, 0)
+        grid0.addWidget(self.splash_cb, 13, 1)
+
         # Sys Tray Icon
         self.systray_label = QtWidgets.QLabel('%s:' % _('Sys Tray Icon'))
         self.systray_label.setToolTip(
@@ -704,6 +757,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         )
         self.systray_cb = FCCheckBox()
 
+        grid0.addWidget(self.systray_label, 14, 0)
+        grid0.addWidget(self.systray_cb, 14, 1)
+
         # Shell StartUp CB
         self.shell_startup_label = QtWidgets.QLabel('%s:' % _('Shell at StartUp'))
         self.shell_startup_label.setToolTip(
@@ -716,6 +772,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "start automatically at startup.")
         )
 
+        grid0.addWidget(self.shell_startup_label, 15, 0)
+        grid0.addWidget(self.shell_startup_cb, 15, 1)
+
         # Project at StartUp CB
         self.project_startup_label = QtWidgets.QLabel('%s:' % _('Project at StartUp'))
         self.project_startup_label.setToolTip(
@@ -728,6 +787,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "to be shown automatically at startup.")
         )
 
+        grid0.addWidget(self.project_startup_label, 16, 0)
+        grid0.addWidget(self.project_startup_cb, 16, 1)
+
         # Project autohide CB
         self.project_autohide_label = QtWidgets.QLabel('%s:' % _('Project AutoHide'))
         self.project_autohide_label.setToolTip(
@@ -742,6 +804,11 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "to show whenever a new object is created.")
         )
 
+        grid0.addWidget(self.project_autohide_label, 17, 0)
+        grid0.addWidget(self.project_autohide_cb, 17, 1)
+
+        grid0.addWidget(QtWidgets.QLabel(''), 18, 0)
+
         # Enable/Disable ToolTips globally
         self.toggle_tooltips_label = QtWidgets.QLabel('<b>%s:</b>' % _('Enable ToolTips'))
         self.toggle_tooltips_label.setToolTip(
@@ -754,6 +821,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "when hovering with mouse over items throughout the App.")
         )
 
+        grid0.addWidget(self.toggle_tooltips_label, 19, 0)
+        grid0.addWidget(self.toggle_tooltips_cb, 19, 1)
+
         # Mouse Cursor Shape
         self.cursor_lbl = QtWidgets.QLabel('%s:' % _('Mouse Cursor'))
         self.cursor_lbl.setToolTip(
@@ -767,6 +837,9 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
             {"label": _("Big"), "value": "big"}
         ], orientation='horizontal', stretch=False)
 
+        grid0.addWidget(self.cursor_lbl, 20, 0)
+        grid0.addWidget(self.cursor_radio, 20, 1)
+
         self.cursor_size_lbl = QtWidgets.QLabel('%s:' % _('Mouse Cursor Size'))
         self.cursor_size_lbl.setToolTip(
            _("Set the size of the mouse cursor, in pixels.")
@@ -776,34 +849,8 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         self.cursor_size_entry.set_range(10, 70)
         self.cursor_size_entry.setWrapping(True)
 
-
-        # Add (label - input field) pair to the QFormLayout
-        self.form_box.addRow(self.spacelabel, self.spacelabel)
-
-        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.hdpi_label, self.hdpi_cb)
-        self.form_box.addRow(self.clear_label, self.clear_btn)
-        self.form_box.addRow(self.hover_label, self.hover_cb)
-        self.form_box.addRow(self.selection_label, self.selection_cb)
-        self.form_box.addRow(QtWidgets.QLabel(''))
-        self.form_box.addRow(self.notebook_font_size_label, self.notebook_font_size_spinner)
-        self.form_box.addRow(self.axis_font_size_label, self.axis_font_size_spinner)
-        self.form_box.addRow(self.textbox_font_size_label, self.textbox_font_size_spinner)
-        self.form_box.addRow(QtWidgets.QLabel(''))
-        self.form_box.addRow(self.splash_label, self.splash_cb)
-        self.form_box.addRow(self.systray_label, self.systray_cb)
-        self.form_box.addRow(self.shell_startup_label, self.shell_startup_cb)
-        self.form_box.addRow(self.project_startup_label, self.project_startup_cb)
-        self.form_box.addRow(self.project_autohide_label, self.project_autohide_cb)
-        self.form_box.addRow(QtWidgets.QLabel(''))
-        self.form_box.addRow(self.toggle_tooltips_label, self.toggle_tooltips_cb)
-        self.form_box.addRow(self.cursor_lbl, self.cursor_radio)
-        self.form_box.addRow(self.cursor_size_lbl, self.cursor_size_entry)
-
-        # Add the QFormLayout that holds the Application general defaults
-        # to the main layout of this TAB
-        self.layout.addLayout(self.form_box)
+        grid0.addWidget(self.cursor_size_lbl, 21, 0)
+        grid0.addWidget(self.cursor_size_entry, 21, 1)
 
         # Delete confirmation
         self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
@@ -812,7 +859,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
               "whenever the Delete object(s) event is triggered, either by\n"
               "menu shortcut or key shortcut.")
         )
-        self.layout.addWidget(self.delete_conf_cb)
+        grid0.addWidget(self.delete_conf_cb, 22, 0, 1, 2)
 
         self.layout.addStretch()
 

+ 27 - 11
flatcamGUI/VisPyCanvas.py

@@ -25,7 +25,25 @@ class VisPyCanvas(scene.SceneCanvas):
 
         self.unfreeze()
 
-        back_color = str(QPalette().color(QPalette.Window).name())
+        settings = QSettings("Open Source", "FlatCAM")
+        if settings.contains("axis_font_size"):
+            a_fsize = settings.value('axis_font_size', type=int)
+        else:
+            a_fsize = 8
+
+        if settings.contains("theme"):
+            theme = settings.value('theme', type=str)
+        else:
+            theme = 'white'
+
+        if theme == 'white':
+            theme_color = Color('#FFFFFF')
+            tick_color = Color('#000000')
+            back_color = str(QPalette().color(QPalette.Window).name())
+        else:
+            theme_color = Color('#000000')
+            tick_color = Color('gray')
+            back_color = Color('#000000')
 
         self.central_widget.bgcolor = back_color
         self.central_widget.border_color = back_color
@@ -36,18 +54,16 @@ class VisPyCanvas(scene.SceneCanvas):
         top_padding = self.grid_widget.add_widget(row=0, col=0, col_span=2)
         top_padding.height_max = 0
 
-        settings = QSettings("Open Source", "FlatCAM")
-        if settings.contains("axis_font_size"):
-            a_fsize = settings.value('axis_font_size', type=int)
-        else:
-            a_fsize = 8
-
-        self.yaxis = scene.AxisWidget(orientation='left', axis_color='black', text_color='black', font_size=a_fsize)
+        self.yaxis = scene.AxisWidget(
+            orientation='left', axis_color=tick_color, text_color=tick_color, font_size=a_fsize
+        )
         self.yaxis.width_max = 55
         self.grid_widget.add_widget(self.yaxis, row=1, col=0)
 
-        self.xaxis = scene.AxisWidget(orientation='bottom', axis_color='black', text_color='black', font_size=a_fsize,
-                                      anchors=['center', 'bottom'])
+        self.xaxis = scene.AxisWidget(
+            orientation='bottom', axis_color=tick_color, text_color=tick_color, font_size=a_fsize,
+            anchors=['center', 'bottom']
+        )
         self.xaxis.height_max = 30
         self.grid_widget.add_widget(self.xaxis, row=2, col=1)
 
@@ -55,7 +71,7 @@ class VisPyCanvas(scene.SceneCanvas):
         # right_padding.width_max = 24
         right_padding.width_max = 0
 
-        view = self.grid_widget.add_view(row=1, col=1, border_color='black', bgcolor='white')
+        view = self.grid_widget.add_view(row=1, col=1, border_color=tick_color, bgcolor=theme_color)
         view.camera = Camera(aspect=1, rect=(-25, -25, 150, 150))
 
         # Following function was removed from 'prepare_draw()' of 'Grid' class by patch,

+ 1 - 1
flatcamTools/ToolDistance.py

@@ -382,7 +382,7 @@ class Distance(FlatCAMTool):
 
                 # Update cursor
                 self.app.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
-                                             symbol='++', edge_color='black',
+                                             symbol='++', edge_color=self.app.cursor_color_3D,
                                              size=self.app.defaults["global_cursor_size"])
             else:
                 pos = (pos_canvas[0], pos_canvas[1])

+ 2 - 1
flatcamTools/ToolNonCopperClear.py

@@ -1331,7 +1331,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
             curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1])
 
             self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
-                                         symbol='++', edge_color='black', size=self.app.defaults["global_cursor_size"])
+                                         symbol='++', edge_color=self.app.cursor_color_3D,
+                                         size=self.app.defaults["global_cursor_size"])
 
         # update the positions on status bar
         self.app.ui.position_label.setText("&nbsp;&nbsp;&nbsp;&nbsp;<b>X</b>: %.4f&nbsp;&nbsp;   "

+ 2 - 1
flatcamTools/ToolPaint.py

@@ -1199,7 +1199,8 @@ class ToolPaint(FlatCAMTool, Gerber):
             curr_pos = self.app.geo_editor.snap(curr_pos[0], curr_pos[1])
 
             self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
-                                         symbol='++', edge_color='black', size=self.app.defaults["global_cursor_size"])
+                                         symbol='++', edge_color=self.app.cursor_color_3D,
+                                         size=self.app.defaults["global_cursor_size"])
 
         # update the positions on status bar
         self.app.ui.position_label.setText("&nbsp;&nbsp;&nbsp;&nbsp;<b>X</b>: %.4f&nbsp;&nbsp;   "