diff --git a/.gitignore b/.gitignore index f957e1b3..30a8ae85 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ build/ .DS_Store .AppleDouble .LSOverride +.vscode diff --git a/Bookmark.py b/Bookmark.py index 796c1105..a3b6629d 100644 --- a/Bookmark.py +++ b/Bookmark.py @@ -75,7 +75,7 @@ class BookmarkManager(QtWidgets.QWidget): new_vlay = QtWidgets.QVBoxLayout() layout.addLayout(new_vlay) - new_title_lbl = FCLabel('%s' % _("New Bookmark")) + new_title_lbl = FCLabel('%s' % _("New Bookmark"), bold=True) new_vlay.addWidget(new_title_lbl) grid0 = GLay(v_spacing=5, h_spacing=3) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0b2b544..d97cbc40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ CHANGELOG for FlatCAM Evo beta - replaced all the FCLabel widgets that have color HTML with the new FCLabel widget that uses parameters for 'color' and weight - minor changes - added a way to allow patching FCLabel widget colors for certain cases without having to pass them each instance +- some changes in the theme selection, added that the default situation is where no theme is applied +- some string changes 17.04.2022 @@ -7472,4 +7474,3 @@ Previously added features by Dennis - Groups in Project view. - Pan view by dragging in visualizer window with pressed MMB. - OpenGL-based visualizer. - diff --git a/appDatabase.py b/appDatabase.py index 8f21063a..0d487586 100644 --- a/appDatabase.py +++ b/appDatabase.py @@ -226,7 +226,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.dia_entry, 1, 1) # Tool Tolerance - self.tol_label = FCLabel("%s:" % _("Diameter Tolerance")) + self.tol_label = FCLabel('%s:' % _("Diameter Tolerance"), bold=True) self.tol_label.setToolTip( _("Tool tolerance. This tool will be used if the desired tool diameter\n" "is within the tolerance specified here.") @@ -262,7 +262,7 @@ class ToolsDB2UI: self.grid_tool.addWidget(self.tol_max_entry, 6, 1) # Tool Object Type - self.tool_op_label = FCLabel('%s:' % _('Target')) + self.tool_op_label = FCLabel('%s:' % _('Target'), bold=True) self.tool_op_label.setToolTip( _("The kind of Application Tool where this tool is to be used.")) diff --git a/appEditors/AppExcEditor.py b/appEditors/AppExcEditor.py index 5d701f71..91bf4cf9 100644 --- a/appEditors/AppExcEditor.py +++ b/appEditors/AppExcEditor.py @@ -4054,7 +4054,7 @@ class AppExcEditorUI: self.name_box.addWidget(self.name_entry) # Tools Drills Table Title - self.tools_table_label = FCLabel("%s" % _('Tools Table')) + self.tools_table_label = FCLabel('%s' % _('Tools Table'), bold=True) self.tools_table_label.setToolTip( _("Tools in this Excellon object\n" "when are used for drilling.") @@ -4091,7 +4091,7 @@ class AppExcEditorUI: self.ui_vertical_lay.addWidget(separator_line) # Add a new Tool - self.addtool_label = FCLabel('%s' % _('Add/Delete Tool')) + self.addtool_label = FCLabel('%s' % _('Add/Delete Tool'), bold=True) self.addtool_label.setToolTip( _("Add/Delete a tool to the tool list\n" "for this Excellon object.") @@ -4157,7 +4157,7 @@ class AppExcEditorUI: self.resize_grid.setContentsMargins(0, 0, 0, 0) self.resize_frame.setLayout(self.resize_grid) - self.drillresize_label = FCLabel('%s' % _("Resize Tool")) + self.drillresize_label = FCLabel('%s' % _("Resize Tool"), bold=True) self.drillresize_label.setToolTip( _("Resize a drill or a selection of drills.") ) @@ -4212,7 +4212,7 @@ class AppExcEditorUI: self.array_frame.setLayout(self.array_grid) # Type of Drill Array - self.drill_array_label = FCLabel('%s' % _("Add Drill Array")) + self.drill_array_label = FCLabel('%s' % _("Add Drill Array"), bold=True) self.drill_array_label.setToolTip( _("Add an array of drills (linear or circular array)") ) @@ -4352,7 +4352,7 @@ class AppExcEditorUI: self.slot_frame.setLayout(self.slot_grid) # Slot Tile Label - self.slot_label = FCLabel('%s' % _("Slot Parameters")) + self.slot_label = FCLabel('%s' % _("Slot Parameters"), bold=True) self.slot_label.setToolTip( _("Parameters for adding a slot (hole with oval shape)\n" "either single or as an part of an array.") @@ -4424,7 +4424,7 @@ class AppExcEditorUI: self.slot_array_frame.setLayout(self.slot_array_grid) # Slot Array Title - self.slot_array_label = FCLabel('%s' % _("Slot Array Parameters")) + self.slot_array_label = FCLabel('%s' % _("Slot Array Parameters"), bold=True) self.slot_array_label.setToolTip( _("Parameters for the array of slots (linear or circular array)") ) diff --git a/appEditors/AppGeoEditor.py b/appEditors/AppGeoEditor.py index 8183c40d..c32d2e89 100644 --- a/appEditors/AppGeoEditor.py +++ b/appEditors/AppGeoEditor.py @@ -3096,7 +3096,7 @@ class AppGeoEditor(QtCore.QObject): self.tools_box.addLayout(self.grid_d) # Tool diameter - tooldia_lbl = FCLabel('%s:' % _("Tool dia")) + tooldia_lbl = FCLabel('%s' % _("Tool dia"), bold=True) tooldia_lbl.setToolTip( _("Edited tool diameter.") ) @@ -3108,7 +3108,7 @@ class AppGeoEditor(QtCore.QObject): self.grid_d.addWidget(tooldia_lbl, 0, 0) self.grid_d.addWidget(self.tooldia_entry, 0, 1) # Tree Widget Title - tw_label = FCLabel('%s:' % _("Geometry Table")) + tw_label = FCLabel('%s' % _("Geometry Table"), bold=True) tw_label.setToolTip( _("The list of geometry elements inside the edited object.") ) @@ -3148,35 +3148,35 @@ class AppGeoEditor(QtCore.QObject): grid0.addWidget(separator_line, 2, 0, 1, 3) # Parameters Title - param_title = FCLabel('%s:' % _("Parameters")) + param_title = FCLabel('%s' % _("Parameters"), bold=True) param_title.setToolTip( _("Geometry parameters.") ) grid0.addWidget(param_title, 4, 0, 1, 3) # Is Valid - is_valid_lbl = FCLabel('%s:' % _("Is Valid")) + is_valid_lbl = FCLabel('%s' % _("Is Valid"), bold=True) self.is_valid_entry = FCLabel('None') grid0.addWidget(is_valid_lbl, 10, 0) grid0.addWidget(self.is_valid_entry, 10, 1, 1, 2) # Is Empty - is_empty_lbl = FCLabel('%s:' % _("Is Empty")) + is_empty_lbl = FCLabel('%s' % _("Is Empty"), bold=True) self.is_empty_entry = FCLabel('None') grid0.addWidget(is_empty_lbl, 12, 0) grid0.addWidget(self.is_empty_entry, 12, 1, 1, 2) # Is Ring - is_ring_lbl = FCLabel('%s:' % _("Is Ring")) + is_ring_lbl = FCLabel('%s' % _("Is Ring"), bold=True) self.is_ring_entry = FCLabel('None') grid0.addWidget(is_ring_lbl, 14, 0) grid0.addWidget(self.is_ring_entry, 14, 1, 1, 2) # Is CCW - is_ccw_lbl = FCLabel('%s:' % _("Is CCW")) + is_ccw_lbl = FCLabel('%s' % _("Is CCW"), bold=True) self.is_ccw_entry = FCLabel('None') self.change_orientation_btn = FCButton(_("Change")) self.change_orientation_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/orientation32.png')) @@ -3189,14 +3189,14 @@ class AppGeoEditor(QtCore.QObject): grid0.addWidget(self.change_orientation_btn, 16, 2) # Is Simple - is_simple_lbl = FCLabel('%s:' % _("Is Simple")) + is_simple_lbl = FCLabel('%s' % _("Is Simple"), bold=True) self.is_simple_entry = FCLabel('None') grid0.addWidget(is_simple_lbl, 18, 0) grid0.addWidget(self.is_simple_entry, 18, 1, 1, 2) # Length - len_lbl = FCLabel('%s:' % _("Length")) + len_lbl = FCLabel('%s' % _("Length"), bold=True) len_lbl.setToolTip( _("The length of the geometry element.") ) @@ -3207,7 +3207,7 @@ class AppGeoEditor(QtCore.QObject): grid0.addWidget(self.geo_len_entry, 20, 1, 1, 2) # Coordinates - coords_lbl = FCLabel('%s:' % _("Coordinates")) + coords_lbl = FCLabel('%s' % _("Coordinates"), bold=True) coords_lbl.setToolTip( _("The coordinates of the selected geometry element.") ) @@ -3220,7 +3220,7 @@ class AppGeoEditor(QtCore.QObject): grid0.addWidget(self.geo_coords_entry, 24, 0, 1, 3) # Vertex Points Number - vertex_lbl = FCLabel('%s:' % _("Vertex Points")) + vertex_lbl = FCLabel('%s' % _("Vertex Points"), bold=True) vertex_lbl.setToolTip( _("The number of vertex points in the selected geometry element.") ) diff --git a/appEditors/AppGerberEditor.py b/appEditors/AppGerberEditor.py index 6613ecc5..90a9cd9e 100644 --- a/appEditors/AppGerberEditor.py +++ b/appEditors/AppGerberEditor.py @@ -6174,7 +6174,7 @@ class AppGerberEditorUI: # ############################################################################################################# # #################################### Gerber Apertures Table ################################################# # ############################################################################################################# - self.apertures_table_label = FCLabel('%s:' % _('Apertures')) + self.apertures_table_label = FCLabel('%s:' % _('Apertures'), bold=True) self.apertures_table_label.setToolTip( _("Apertures Table for the Gerber Object.") ) @@ -6225,7 +6225,7 @@ class AppGerberEditorUI: self.apertures_box.addLayout(grid1) # Title - apadd_del_lbl = FCLabel('%s:' % _('Add/Delete Aperture')) + apadd_del_lbl = FCLabel('%s:' % _('Add/Delete Aperture'), bold=True) apadd_del_lbl.setToolTip( _("Add/Delete an aperture in the aperture table") ) @@ -6334,7 +6334,7 @@ class AppGerberEditorUI: self.shape_grid.addWidget(separator_line, 2, 0, 1, 3) # Parameters Title - param_title = FCLabel('%s' % _("Parameters")) + param_title = FCLabel('%s' % _("Parameters"), bold=True) param_title.setToolTip( _("Geometry parameters.") ) @@ -6343,7 +6343,7 @@ class AppGerberEditorUI: p_grid = GLay(v_spacing=5, h_spacing=3, c_stretch=[0, 0, 0, 1, 0]) # Is Valid - valid_lbl = FCLabel('%s:' % _("Valid")) + valid_lbl = FCLabel('%s' % _("Valid"), bold=True) valid_lbl.setToolTip( _("Show if the selected polygon is valid.") ) @@ -6352,7 +6352,7 @@ class AppGerberEditorUI: p_grid.addWidget(self.is_valid_entry, 0, 1) # Area - area_lbl = FCLabel('%s:' % _("Area")) + area_lbl = FCLabel('%s' % _("Area"), bold=True) area_lbl.setToolTip( _("Show the area of the selected polygon.") ) @@ -6397,7 +6397,7 @@ class AppGerberEditorUI: self.shape_grid.addWidget(separator_line, 12, 0, 1, 3) # Simplification Title - simplif_lbl = FCLabel('%s:' % _("Simplification")) + simplif_lbl = FCLabel('%s' % _("Simplification"), bold=True) simplif_lbl.setToolTip( _("Simplify a geometry by reducing its vertex points number.") ) @@ -6445,7 +6445,7 @@ class AppGerberEditorUI: self.buffer_tool_frame.hide() # Title - buf_title_lbl = FCLabel('%s:' % _('Buffer Aperture')) + buf_title_lbl = FCLabel('%s:' % _('Buffer Aperture'), bold=True) buf_title_lbl.setToolTip( _("Buffer a aperture in the aperture list") ) @@ -6503,7 +6503,7 @@ class AppGerberEditorUI: self.scale_tool_frame.hide() # Title - scale_title_lbl = FCLabel('%s:' % _('Scale Aperture')) + scale_title_lbl = FCLabel('%s:' % _('Scale Aperture'), bold=True) scale_title_lbl.setToolTip( _("Scale a aperture in the aperture list") ) @@ -6552,7 +6552,7 @@ class AppGerberEditorUI: self.ma_tools_box.addWidget(separator_line) # Title - ma_title_lbl = FCLabel('%s:' % _('Mark polygons')) + ma_title_lbl = FCLabel('%s:' % _('Mark polygons'), bold=True) ma_title_lbl.setToolTip( _("Mark the polygon areas.") ) @@ -6632,7 +6632,7 @@ class AppGerberEditorUI: self.array_box.addLayout(array_grid) # Title - self.padarray_label = FCLabel('%s' % _("Add Pad Array")) + self.padarray_label = FCLabel('%s' % _("Add Pad Array"), bold=True) self.padarray_label.setToolTip( _("Add an array of pads (linear or circular array)") ) diff --git a/appEditors/geo_plugins/GeoCirclePlugin.py b/appEditors/geo_plugins/GeoCirclePlugin.py index 397b2451..5b86414c 100644 --- a/appEditors/geo_plugins/GeoCirclePlugin.py +++ b/appEditors/geo_plugins/GeoCirclePlugin.py @@ -187,7 +187,7 @@ class CircleEditorUI: self.circle_tool_box.addLayout(grid0) # Position - self.pos_lbl = FCLabel('%s' % _("Position")) + self.pos_lbl = FCLabel('%s' % _("Position"), bold=True) grid0.addWidget(self.pos_lbl, 0, 0, 1, 3) # X Pos @@ -246,7 +246,7 @@ class CircleEditorUI: self.layout.addStretch(1) # Note - self.note_lbl = FCLabel('%s' % _("Note")) + self.note_lbl = FCLabel('%s' % _("Note"), bold=True) 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) diff --git a/appEditors/geo_plugins/GeoCopyPlugin.py b/appEditors/geo_plugins/GeoCopyPlugin.py index b10a2955..3f7aa75b 100644 --- a/appEditors/geo_plugins/GeoCopyPlugin.py +++ b/appEditors/geo_plugins/GeoCopyPlugin.py @@ -164,7 +164,7 @@ class CopyEditorUI: grid0.addWidget(separator_line, 4, 0, 1, 2) # Type of Array - self.mode_label = FCLabel('%s:' % _("Mode")) + self.mode_label = FCLabel('%s:' % _("Mode"), bold=True) self.mode_label.setToolTip( _("Single copy or special (array of copies)") ) diff --git a/appEditors/geo_plugins/GeoRectanglePlugin.py b/appEditors/geo_plugins/GeoRectanglePlugin.py index 9acc15d6..d76a9aed 100644 --- a/appEditors/geo_plugins/GeoRectanglePlugin.py +++ b/appEditors/geo_plugins/GeoRectanglePlugin.py @@ -220,7 +220,7 @@ class RectangleEditorUI: self.rect_tool_box.addLayout(grid0) # Anchor - self.anchor_lbl = FCLabel('%s:' % _("Anchor")) + self.anchor_lbl = FCLabel('%s:' % _("Anchor"), bold=True) choices = [ {"label": _("T Left"), "value": "tl"}, {"label": _("T Right"), "value": "tr"}, @@ -233,7 +233,7 @@ class RectangleEditorUI: grid0.addWidget(self.anchor_radio, 0, 1) # Position - self.pos_lbl = FCLabel('%s' % _("Position")) + self.pos_lbl = FCLabel('%s' % _("Position"), bold=True) grid0.addWidget(self.pos_lbl, 2, 0, 1, 2) # X Pos @@ -277,7 +277,7 @@ class RectangleEditorUI: grid0.addWidget(self.radius_entry, 10, 1) # Size - self.size_lbl = FCLabel('%s' % _("Size")) + self.size_lbl = FCLabel('%s' % _("Size"), bold=True) grid0.addWidget(self.size_lbl, 12, 0, 1, 2) # Length @@ -300,7 +300,7 @@ class RectangleEditorUI: self.layout.addStretch(1) # Note - self.note_lbl = FCLabel('%s' % _("Note")) + self.note_lbl = FCLabel('%s' % _("Note"), bold=True) 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) diff --git a/appEditors/geo_plugins/GeoSimplificationPlugin.py b/appEditors/geo_plugins/GeoSimplificationPlugin.py index d350813e..adcd898d 100644 --- a/appEditors/geo_plugins/GeoSimplificationPlugin.py +++ b/appEditors/geo_plugins/GeoSimplificationPlugin.py @@ -196,7 +196,7 @@ class SimplificationEditorUI: self.simp_tools_box.addLayout(grid0) # Coordinates - coords_lbl = FCLabel('%s:' % _("Coordinates")) + coords_lbl = FCLabel('%s' % _("Coordinates"), bold=True) coords_lbl.setToolTip( _("The coordinates of the selected geometry element.") ) @@ -209,7 +209,7 @@ class SimplificationEditorUI: grid0.addWidget(self.geo_coords_entry, 24, 0, 1, 3) # Vertex Points Number - vertex_lbl = FCLabel('%s:' % _("Vertex Points")) + vertex_lbl = FCLabel('%s' % _("Vertex Points"), bold=True) vertex_lbl.setToolTip( _("The number of vertex points in the selected geometry element.") ) @@ -225,14 +225,14 @@ class SimplificationEditorUI: grid0.addWidget(separator_line, 28, 0, 1, 3) # Simplification Title - simplif_lbl = FCLabel('%s:' % _("Simplification")) + simplif_lbl = FCLabel('%s' % _("Simplification"), bold=True) simplif_lbl.setToolTip( _("Simplify a geometry by reducing its vertex points number.") ) grid0.addWidget(simplif_lbl, 30, 0, 1, 3) # Simplification Tolerance - simplification_tol_lbl = FCLabel('%s:' % _("Tolerance")) + simplification_tol_lbl = FCLabel('%s' % _("Tolerance"), bold=True) simplification_tol_lbl.setToolTip( _("All points in the simplified object will be\n" "within the tolerance distance of the original geometry.") diff --git a/appGUI/MainGUI.py b/appGUI/MainGUI.py index 56bd706b..b1ec442b 100644 --- a/appGUI/MainGUI.py +++ b/appGUI/MainGUI.py @@ -41,6 +41,8 @@ import gettext import appTranslation as fcTranslate import builtins +import darkdetect + fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext @@ -52,8 +54,40 @@ class MainGUI(QtWidgets.QMainWindow): final_save = QtCore.pyqtSignal(name='saveBeforeExit') # screenChanged = QtCore.pyqtSignal(QtGui.QScreen, QtGui.QScreen) + # Mapping of colors used for text on Light theme to + # similar colors safe for use on Dark theme + # 'input_color': (light_color, dark_color), + theme_safe_colors = { + "blue": "#1F80FF", + "brown": "#CC9966", + "darkgreen": "#008015", + "darkorange": "darkorange", + "green": "#00CC22", + "indigo": "#9457EB", + "magenta": "magenta", + "orange": "orange", + "purple": "#B284BE", + "red": "salmon", + "teal": "teal", + "tomato": "tomato", + } + def theme_safe_color(self, color): - return color + """ + Some colors do not work well with light or dark backgrounds making them unreadable in the wrong + theme. For an approved color value this will return a similar color better suited for the current theme. + + :param color: color to be replaced + :return: similar color better suited for dark or light theme + """ + + if color in self.theme_safe_colors: + if self.app.options['global_theme'] == 'light': + return color + else: + return self.theme_safe_colors[color] + else: + return color # https://www.w3.org/TR/SVG11/types.html#ColorKeywords def __init__(self, app): @@ -2360,7 +2394,7 @@ class MainGUI(QtWidgets.QMainWindow): self.app.log.debug("Clearing the settings in QSettings. GUI settings cleared.") theme_settings = QtCore.QSettings("Open Source", "FlatCAM") - theme_settings.setValue('theme', 'white') + theme_settings.setValue('theme', 'light') del theme_settings diff --git a/appGUI/ObjectUI.py b/appGUI/ObjectUI.py index 143cac9c..a7b757eb 100644 --- a/appGUI/ObjectUI.py +++ b/appGUI/ObjectUI.py @@ -40,12 +40,12 @@ class ObjectUI(QtWidgets.QWidget): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' layout = QtWidgets.QVBoxLayout() self.setLayout(layout) @@ -197,7 +197,7 @@ class GerberObjectUI(ObjectUI): plot_grid.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter) gen_frame.setLayout(plot_grid) - self.plot_options_label = FCLabel("%s:" % _("Plot Options")) + self.plot_options_label = FCLabel('%s:' % _("Plot Options"), bold=True) plot_grid.addWidget(self.plot_options_label, 0, 0) @@ -219,7 +219,7 @@ class GerberObjectUI(ObjectUI): self.name_hlay = QtWidgets.QHBoxLayout() plot_grid.addLayout(self.name_hlay, 1, 0, 1, 3) - name_label = FCLabel("%s:" % _("Name")) + name_label = FCLabel('%s:' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self.name_hlay.addWidget(name_label) @@ -482,7 +482,7 @@ class GerberObjectUI(ObjectUI): # Non-Copper Regions Frame # ############################################################################################################# # ## Non-copper regions - self.noncopper_label = FCLabel("%s" % _("Non-copper regions")) + self.noncopper_label = FCLabel('%s' % _("Non-copper regions"), bold=True) self.noncopper_label.setToolTip( _("Create polygons covering the\n" "areas without copper on the PCB.\n" @@ -530,7 +530,7 @@ class GerberObjectUI(ObjectUI): # Bounding Box Frame # ############################################################################################################# # ## Bounding box - self.boundingbox_label = FCLabel('%s' % _('Bounding Box')) + self.boundingbox_label = FCLabel('%s' % _('Bounding Box'), bold=True) self.boundingbox_label.setToolTip( _("Create a geometry surrounding the Gerber object.\n" "Square shape.") @@ -589,12 +589,12 @@ class ExcellonObjectUI(ObjectUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' ObjectUI.__init__(self, title=_('Excellon Object'), icon_file=self.resource_loc + '/drill32.png', @@ -617,7 +617,7 @@ class ExcellonObjectUI(ObjectUI): gen_frame.setLayout(plot_grid) # Plot options - self.plot_options_label = FCLabel("%s: " % _("Plot Options")) + self.plot_options_label = FCLabel('%s: ' % _("Plot Options"), bold=True) # Solid CB self.solid_cb = FCCheckBox(label=_('Solid')) @@ -638,7 +638,7 @@ class ExcellonObjectUI(ObjectUI): # ## Object name self.name_hlay = QtWidgets.QHBoxLayout() - name_label = FCLabel("%s: " % _("Name")) + name_label = FCLabel('%s: ' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self.name_hlay.addWidget(name_label) @@ -844,7 +844,7 @@ class ExcellonObjectUI(ObjectUI): # ############################################################################################################# # Milling Drill Holes Frame # ############################################################################################################# - self.mill_hole_label = FCLabel('%s' % _('Milling Geometry')) + self.mill_hole_label = FCLabel('%s' % _('Milling Geometry'), bold=True) self.mill_hole_label.setToolTip( _("Create Geometry for milling holes.\n" "Select from the Tools Table above the hole dias to be\n" @@ -926,12 +926,12 @@ class GeometryObjectUI(ObjectUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' super(GeometryObjectUI, self).__init__( title=_('Geometry Object'), @@ -953,7 +953,7 @@ class GeometryObjectUI(ObjectUI): plot_grid.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter) gen_frame.setLayout(plot_grid) - self.plot_options_label = FCLabel("%s:" % _("Plot Options")) + self.plot_options_label = FCLabel('%s:' % _("Plot Options"), bold=True) self.plot_options_label.setMinimumWidth(90) plot_grid.addWidget(self.plot_options_label, 0, 0) @@ -970,7 +970,7 @@ class GeometryObjectUI(ObjectUI): self.name_hlay = QtWidgets.QHBoxLayout() plot_grid.addLayout(self.name_hlay, 2, 0, 1, 3) - name_label = FCLabel("%s:" % _("Name")) + name_label = FCLabel('%s:' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self.name_hlay.addWidget(name_label) @@ -1033,7 +1033,7 @@ class GeometryObjectUI(ObjectUI): self.tt_frame.setLayout(tt_grid) # ### Tools #### - self.tools_table_label = FCLabel('%s:' % _('Tools Table')) + self.tools_table_label = FCLabel('%s:' % _('Tools Table'), bold=True) self.tools_table_label.setToolTip( _("Tools in this Geometry object used for cutting.\n" "The 'Offset' entry will set an offset for the cut.\n" @@ -1182,7 +1182,7 @@ class GeometryObjectUI(ObjectUI): # Simplification Frame # ############################################################################################################# # Simplification Title - simplif_lbl = FCLabel('%s:' % _("Simplification")) + simplif_lbl = FCLabel('%s' % _("Simplification"), bold=True) simplif_lbl.setToolTip( _("Simplify a geometry by reducing its vertex points number.") ) @@ -1267,12 +1267,12 @@ class CNCObjectUI(ObjectUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' ObjectUI.__init__(self, title=_('CNC Job Object'), icon_file=self.resource_loc + '/cnc32.png', parent=parent, @@ -1296,7 +1296,7 @@ class CNCObjectUI(ObjectUI): gen_frame.setLayout(grid0) # Plot Options - self.cncplot_method_label = FCLabel("%s: " % _("Plot Options")) + self.cncplot_method_label = FCLabel('%s: ' % _("Plot Options"), bold=True) self.cncplot_method_label.setToolTip( _( "This selects the kind of geometries on the canvas to plot.\n" @@ -1319,7 +1319,7 @@ class CNCObjectUI(ObjectUI): grid0.addLayout(self.name_hlay, 2, 0, 1, 3) # ## Object name - name_label = FCLabel("%s: " % _("Name")) + name_label = FCLabel('%s: ' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) @@ -1387,7 +1387,7 @@ class CNCObjectUI(ObjectUI): grid_par.addWidget(self.estimated_frame, 4, 0, 1, 3) # Travelled Distance - self.t_distance_label = FCLabel("%s:" % _("Travelled distance")) + self.t_distance_label = FCLabel('%s:' % _("Travelled distance"), bold=True) self.t_distance_label.setToolTip( _("This is the total travelled distance on X-Y plane.\n" "In current units.") @@ -1400,7 +1400,7 @@ class CNCObjectUI(ObjectUI): estimated_grid.addWidget(self.units_label, 0, 2) # Estimated Time - self.t_time_label = FCLabel("%s:" % _("Estimated time")) + self.t_time_label = FCLabel('%s:' % _("Estimated time"), bold=True) self.t_time_label.setToolTip( _("This is the estimated time to do the routing/drilling,\n" "without the time spent in ToolChange events.") @@ -1456,7 +1456,7 @@ class CNCObjectUI(ObjectUI): grid1.addLayout(hlay, 0, 0, 1, 2) # CNC Tools Table for plot - self.cnc_tools_table_label = FCLabel('%s' % _('CNC Tools Table')) + self.cnc_tools_table_label = FCLabel('%s' % _('CNC Tools Table'), bold=True) self.cnc_tools_table_label.setToolTip( _( "Tools in this CNCJob object used for cutting.\n" @@ -1585,12 +1585,12 @@ class ScriptObjectUI(ObjectUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' ObjectUI.__init__(self, title=_('Script Object'), icon_file=self.resource_loc + '/script_new24.png', @@ -1602,7 +1602,7 @@ class ScriptObjectUI(ObjectUI): self.name_hlay = QtWidgets.QHBoxLayout() self.custom_box.addLayout(self.name_hlay) - name_label = FCLabel("%s:" % _("Name")) + name_label = FCLabel('%s:' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self.name_hlay.addWidget(name_label) @@ -1652,12 +1652,12 @@ class DocumentObjectUI(ObjectUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: - self.resource_loc = 'assets/resources' + self.resource_loc = 'assets/resources/dark_resources' ObjectUI.__init__(self, title=_('Document Object'), icon_file=self.resource_loc + '/notes16_1.png', @@ -1669,7 +1669,7 @@ class DocumentObjectUI(ObjectUI): self.name_hlay = QtWidgets.QHBoxLayout() self.custom_box.addLayout(self.name_hlay) - name_label = FCLabel("%s:" % _("Name")) + name_label = FCLabel('%s:' % _("Name"), bold=True) self.name_entry = FCEntry() self.name_entry.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus) self.name_hlay.addWidget(name_label) diff --git a/appGUI/PlotCanvas.py b/appGUI/PlotCanvas.py index 2253ce71..0d40cf9f 100644 --- a/appGUI/PlotCanvas.py +++ b/appGUI/PlotCanvas.py @@ -54,9 +54,14 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' - if theme == 'white': + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: self.line_color = (0.3, 0.0, 0.0, 1.0) # self.rect_hud_color = Color('#0000FF10') self.rect_hud_color = Color('#80808040') @@ -384,9 +389,14 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' - if theme == 'white': + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: color = 'dimgray' else: color = '#dededeff' @@ -712,7 +722,7 @@ class CursorBig(QtCore.QObject): # if 'edge_color' in kwargs: # color = kwargs['edge_color'] # else: - # if self.app.options['global_theme'] == 'white': + # if self.app.options['global_theme'] == 'light': # color = '#000000FF' # else: # color = '#FFFFFFFF' diff --git a/appGUI/PlotCanvas3d.py b/appGUI/PlotCanvas3d.py index 98051ece..748b459c 100644 --- a/appGUI/PlotCanvas3d.py +++ b/appGUI/PlotCanvas3d.py @@ -66,14 +66,19 @@ class PlotCanvas3d(QtCore.QObject, scene.SceneCanvas): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' + + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False if settings.contains("axis_font_size"): a_fsize = settings.value('axis_font_size', type=int) else: a_fsize = 8 - if theme == 'white': + if (theme == 'default' or theme == 'light') and not dark_canvas: theme_color = Color('#FFFFFF') tick_color = Color('#000000') back_color = str(QPalette().color(QPalette.ColorRole.Window).name()) @@ -131,7 +136,7 @@ class PlotCanvas3d(QtCore.QObject, scene.SceneCanvas): # self.xaxis.link_view(self.view) # self.yaxis.link_view(self.view) - # if theme == 'white': + # if theme == 'light': # self.grid = scene.GridLines(parent=self.view.scene, color='dimgray') # else: # self.grid = scene.GridLines(parent=self.view.scene, color='#dededeff') diff --git a/appGUI/PlotCanvasLegacy.py b/appGUI/PlotCanvasLegacy.py index 2b5609e8..17590476 100644 --- a/appGUI/PlotCanvasLegacy.py +++ b/appGUI/PlotCanvasLegacy.py @@ -82,7 +82,18 @@ class CanvasCache(QtCore.QObject): self.axes.set_xticks([]) self.axes.set_yticks([]) - if self.app.options['global_theme'] == 'white': + settings = QtCore.QSettings("Open Source", "FlatCAM") + if settings.contains("theme"): + theme = settings.value('theme', type=str) + else: + theme = 'default' + + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: self.axes.set_facecolor('#FFFFFF') else: self.axes.set_facecolor('#000000') @@ -154,7 +165,7 @@ class PlotCanvasLegacy(QtCore.QObject): self.app = app - if self.app.options['global_theme'] == 'white': + if self.app.options['global_theme'] in ['default', 'light']: theme_color = '#FFFFFF' tick_color = '#000000' self.rect_hud_color = '#0000FF10' @@ -446,7 +457,7 @@ class PlotCanvasLegacy(QtCore.QObject): super().__init__() self.p = plotcanvas - units = self.p.app.app_units + # units = self.p.app.app_units # self._text = 'Dx: %s [%s]\nDy: %s [%s]\n\nX: %s [%s]\nY: %s [%s]' % \ # ('0.0000', units, '0.0000', units, '0.0000', units, '0.0000', units) self.on_update_text_hud() @@ -639,7 +650,7 @@ class PlotCanvasLegacy(QtCore.QObject): if self.app.options["global_cursor_color_enabled"]: color = self.app.options["global_cursor_color"] else: - if self.app.options['global_theme'] == 'white': + if self.app.options['global_theme'] == 'light': color = '#000000' else: color = '#FFFFFF' @@ -694,7 +705,7 @@ class PlotCanvasLegacy(QtCore.QObject): if color: color = color else: - if self.app.options['global_theme'] == 'white': + if self.app.options['global_theme'] == 'light': color = '#000000' else: color = '#FFFFFF' @@ -737,7 +748,7 @@ class PlotCanvasLegacy(QtCore.QObject): self.canvas.blit(self.axes.bbox) def clear_cursor(self, state): - if self.app.options['global_theme'] == 'white': + if self.app.options['global_theme'] == 'light': color = '#000000' else: color = '#FFFFFF' diff --git a/appGUI/VisPyCanvas.py b/appGUI/VisPyCanvas.py index 597980d3..35d86aa4 100644 --- a/appGUI/VisPyCanvas.py +++ b/appGUI/VisPyCanvas.py @@ -39,9 +39,14 @@ class VisPyCanvas(scene.SceneCanvas): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' - if theme == 'white': + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: theme_color = Color('#FFFFFF') tick_color = Color('#000000') back_color = str(QPalette().color(QPalette.ColorRole.Window).name()) @@ -97,10 +102,15 @@ class VisPyCanvas(scene.SceneCanvas): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' + + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False self.view = view - if theme == 'white': + if (theme == 'default' or theme == 'light') and not dark_canvas: self.grid = scene.GridLines(parent=self.view.scene, color='dimgray') else: self.grid = scene.GridLines(parent=self.view.scene, color='#dededeff') diff --git a/appGUI/preferences/PreferencesUIManager.py b/appGUI/preferences/PreferencesUIManager.py index a5acde02..35a4a37d 100644 --- a/appGUI/preferences/PreferencesUIManager.py +++ b/appGUI/preferences/PreferencesUIManager.py @@ -73,8 +73,8 @@ class PreferencesUIManager(QtCore.QObject): "global_tpdf_rmargin": self.ui.general_pref_form.general_app_group.rmargin_entry, # General GUI Preferences - "global_theme": self.ui.general_pref_form.general_gui_group.theme_radio, - "global_gray_icons": self.ui.general_pref_form.general_gui_group.gray_icons_cb, + "global_appearance": self.ui.general_pref_form.general_gui_group.appearance_radio, + "global_dark_canvas": self.ui.general_pref_form.general_gui_group.dark_canvas_cb, "global_layout": self.ui.general_pref_form.general_gui_group.layout_combo, "global_hover_shape": self.ui.general_pref_form.general_gui_group.hover_cb, "global_selection_shape": self.ui.general_pref_form.general_gui_group.selection_cb, @@ -1064,20 +1064,26 @@ class PreferencesUIManager(QtCore.QObject): # make sure we update the self.current_defaults dict used to undo changes to self.defaults self.defaults.current_defaults.update(self.defaults) - # deal with theme change - theme_settings = QtCore.QSettings("Open Source", "FlatCAM") - if theme_settings.contains("theme"): - theme = theme_settings.value('theme', type=str) + # deal with appearance change + appearance_settings = QtCore.QSettings("Open Source", "FlatCAM") + if appearance_settings.contains("appearance"): + appearance = appearance_settings.value('appearance', type=str) else: - theme = 'white' + appearance = None + + if appearance_settings.contains("dark_canvas"): + dark_canvas = appearance_settings.value('dark_canvas', type=bool) + else: + dark_canvas = None should_restart = False - theme_new_val = self.ui.general_pref_form.general_gui_group.theme_radio.get_value() + appearance_new_val = self.ui.general_pref_form.general_gui_group.appearance_radio.get_value() + dark_canvas_new_val = self.ui.general_pref_form.general_gui_group.dark_canvas_cb.get_value() ge = self.defaults["global_graphic_engine"] ge_val = self.ui.general_pref_form.general_app_group.ge_radio.get_value() - if theme_new_val != theme or ge != ge_val: + if appearance_new_val != appearance or ge != ge_val or dark_canvas_new_val != dark_canvas: msgbox = FCMessageBox(parent=self.ui) title = _("Application will restart") txt = _("Are you sure you want to continue?") @@ -1094,17 +1100,24 @@ class PreferencesUIManager(QtCore.QObject): msgbox.exec() response = msgbox.clickedButton() - if theme_new_val != theme: + if appearance_new_val != appearance: if response == bt_yes: - theme_settings.setValue('theme', theme_new_val) - - # This will write the setting to the platform specific storage. - del theme_settings - + appearance_settings.setValue('appearance', appearance_new_val) should_restart = True else: - self.ui.general_pref_form.general_gui_group.theme_radio.set_value(theme) - else: + self.ui.general_pref_form.general_gui_group.appearance_radio.set_value(appearance) + + if dark_canvas_new_val != dark_canvas: + if response == bt_yes: + appearance_settings.setValue('dark_canvas', dark_canvas_new_val) + should_restart = True + else: + self.ui.general_pref_form.general_gui_group.dark_canvas_cb.set_value(dark_canvas) + + # This will write the setting to the platform specific storage. + del appearance_settings + + if ge != ge_val: if response == bt_yes: self.defaults["global_graphic_engine"] = ge_val should_restart = True diff --git a/appGUI/preferences/excellon/ExcellonOptPrefGroupUI.py b/appGUI/preferences/excellon/ExcellonOptPrefGroupUI.py index 3c0f5fdb..c62b2296 100644 --- a/appGUI/preferences/excellon/ExcellonOptPrefGroupUI.py +++ b/appGUI/preferences/excellon/ExcellonOptPrefGroupUI.py @@ -38,7 +38,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): param_frame.setLayout(param_grid) # ### Milling Holes ## ## - self.mill_hole_label = FCLabel('%s' % _('Mill Holes')) + self.mill_hole_label = FCLabel('%s' % _('Mill Holes'), bold=True) self.mill_hole_label.setToolTip( _("Create Geometry for milling holes.") ) diff --git a/appGUI/preferences/general/GeneralAPPSetGroupUI.py b/appGUI/preferences/general/GeneralAPPSetGroupUI.py index 44fd77c4..b7d92edf 100644 --- a/appGUI/preferences/general/GeneralAPPSetGroupUI.py +++ b/appGUI/preferences/general/GeneralAPPSetGroupUI.py @@ -26,9 +26,9 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': self.resource_loc = 'assets/resources' else: self.resource_loc = 'assets/resources' @@ -496,9 +496,14 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' - if theme == 'white': + if theme_settings.contains("dark_canvas"): + dark_canvas = theme_settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: self.app.cursor_color_3D = 'black' else: self.app.cursor_color_3D = 'gray' @@ -509,4 +514,4 @@ class GeneralAPPSetGroupUI(OptionsGroupUI): def on_axis_color_entry(self): self.app.options['global_axis_color'] = self.axis_color_entry.get_value() - self.app.plotcanvas.apply_axis_color() \ No newline at end of file + self.app.plotcanvas.apply_axis_color() diff --git a/appGUI/preferences/general/GeneralAppPrefGroupUI.py b/appGUI/preferences/general/GeneralAppPrefGroupUI.py index ef32a068..a5346b49 100644 --- a/appGUI/preferences/general/GeneralAppPrefGroupUI.py +++ b/appGUI/preferences/general/GeneralAppPrefGroupUI.py @@ -89,7 +89,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI): grid1_frame.setLayout(grid1) # Graphic Engine for FlatCAM - self.ge_label = FCLabel('%s:' % _('Graphic Engine')) + self.ge_label = FCLabel('%s:' % _('Graphic Engine'), bold=True) self.ge_label.setToolTip(_("Choose what graphic engine to use in FlatCAM.\n" "Legacy(2D) -> reduced functionality, slow performance but enhanced compatibility.\n" "OpenGL(3D) -> full functionality, high performance\n" diff --git a/appGUI/preferences/general/GeneralAppSettingsGroupUI.py b/appGUI/preferences/general/GeneralAppSettingsGroupUI.py index 0bea646b..60bbc5fa 100644 --- a/appGUI/preferences/general/GeneralAppSettingsGroupUI.py +++ b/appGUI/preferences/general/GeneralAppSettingsGroupUI.py @@ -292,9 +292,14 @@ class GeneralAppSettingsGroupUI(OptionsGroupUI2): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' - if theme == 'white': + if theme_settings.contains("dark_canvas"): + dark_canvas = theme_settings.value('dark_canvas', type=bool) + else: + dark_canvas = False + + if (theme == 'default' or theme == 'light') and not dark_canvas: self.app.cursor_color_3D = 'black' else: self.app.cursor_color_3D = 'gray' diff --git a/appGUI/preferences/general/GeneralGUIPrefGroupUI.py b/appGUI/preferences/general/GeneralGUIPrefGroupUI.py index 9d1ba15a..e846d1e0 100644 --- a/appGUI/preferences/general/GeneralGUIPrefGroupUI.py +++ b/appGUI/preferences/general/GeneralGUIPrefGroupUI.py @@ -35,28 +35,36 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): par_frame.setLayout(grid0) # Theme selection - self.theme_label = FCLabel('%s:' % _('Theme')) - self.theme_label.setToolTip( + self.appearance_label = FCLabel('%s' % _('Theme'), bold=True) + self.appearance_label.setToolTip( _("Select a theme for the application.\n" "It will theme the plot area.") ) - self.theme_radio = RadioSet([ - {"label": _("Light"), "value": "white"}, - {"label": _("Dark"), "value": "black"} + self.appearance_radio = RadioSet([ + {"label": _("Default"), "value": "default"}, + {"label": _("Auto"), "value": "auto"}, + {"label": _("Light"), "value": "light"}, + {"label": _("Dark"), "value": "dark"} ], compact=True) - - grid0.addWidget(self.theme_label, 0, 0) - grid0.addWidget(self.theme_radio, 0, 1) - - # Enable Gray Icons - self.gray_icons_cb = FCCheckBox('%s' % _('Use Gray Icons')) - self.gray_icons_cb.setToolTip( - _("Check this box to use a set of icons with\n" - "a lighter (gray) color. To be used when a\n" - "full dark theme is applied.") + self.appearance_radio.setToolTip( + _("The theme can be:\n" + "Default: Default theme\n" + "Auto: Matches mode from OS\n" + "Light: Light mode\n" + "Dark: Dark mode") ) - grid0.addWidget(self.gray_icons_cb, 2, 0, 1, 3) + + # Dark Canvas + self.dark_canvas_cb = FCCheckBox('%s' % _('Dark Canvas')) + self.dark_canvas_cb.setToolTip( + _("Check this box to force the use of dark canvas\n" + "even if a dark theme is not selected.") + ) + + grid0.addWidget(self.appearance_label, 0, 0, 1, 2) + grid0.addWidget(self.appearance_radio, 1, 0, 1, 3) + grid0.addWidget(self.dark_canvas_cb, 2, 0, 1, 3) # self.theme_button = FCButton(_("Apply Theme")) # self.theme_button.setToolTip( @@ -156,7 +164,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): color_frame.setLayout(grid1) # Plot Selection (left - right) Color - self.sel_lr_label = FCLabel('%s' % _('Left-Right Selection Color')) + self.sel_lr_label = FCLabel('%s' % _('Left-Right Selection Color'), bold=True) grid1.addWidget(self.sel_lr_label, 0, 0, 1, 2) self.sl_color_label = FCLabel('%s:' % _('Outline')) @@ -196,7 +204,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): grid1.addWidget(separator_line, 8, 0, 1, 2) # Plot Selection (left - right) Color - self.sel_rl_label = FCLabel('%s' % _('Right-Left Selection Color')) + self.sel_rl_label = FCLabel('%s' % _('Right-Left Selection Color'), bold=True) grid1.addWidget(self.sel_rl_label, 10, 0, 1, 2) # Plot Selection (right - left) Line Color @@ -241,7 +249,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): # ----------------------- Editor Color ----------------------------- # ------------------------------------------------------------------ - self.editor_color_label = FCLabel('%s' % _('Editor Color')) + self.editor_color_label = FCLabel('%s' % _('Editor Color'), bold=True) grid1.addWidget(self.editor_color_label, 20, 0, 1, 2) # Editor Draw Color @@ -273,7 +281,7 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): # ----------------------- Project Settings ----------------------------- # ------------------------------------------------------------------ # Light Theme - self.proj_settings_l_label = FCLabel('%s - %s' % (_('Project Items Color'), _("Light"))) + self.proj_settings_l_label = FCLabel('%s' % _("Light"), bold=True) grid1.addWidget(self.proj_settings_l_label, 28, 0, 1, 2) # Project Tab items color @@ -299,8 +307,13 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI): grid1.addWidget(self.proj_color_dis_l_label, 32, 0) grid1.addWidget(self.proj_color_dis_light_entry, 32, 1) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + grid1.addWidget(separator_line, 33, 0, 1, 2) + # Dark Theme - self.proj_settings_d_label = FCLabel('%s - %s' % (_('Project Items Color'), _("Dark"))) + self.proj_settings_d_label = FCLabel('%s' % _("Dark"), bold=True) grid1.addWidget(self.proj_settings_d_label, 34, 0, 1, 2) # Project Tab items color diff --git a/appGUI/preferences/tools/Tools2CThievingPrefGroupUI.py b/appGUI/preferences/tools/Tools2CThievingPrefGroupUI.py index 4c85b0ea..c274284d 100644 --- a/appGUI/preferences/tools/Tools2CThievingPrefGroupUI.py +++ b/appGUI/preferences/tools/Tools2CThievingPrefGroupUI.py @@ -142,7 +142,7 @@ class Tools2CThievingPrefGroupUI(OptionsGroupUI): # ############################################################################################################# # DOTS Grid Parameters Frame # ############################################################################################################# - self.dots_label = FCLabel('%s:' % _("Dots Grid Parameters")) + self.dots_label = FCLabel('%s' % _("Dots Grid Parameters"), bold=True) self.layout.addWidget(self.dots_label) dots_frame = FCFrame() @@ -181,7 +181,7 @@ class Tools2CThievingPrefGroupUI(OptionsGroupUI): # ############################################################################################################# # Squares Grid Parameters Frame # ############################################################################################################# - self.squares_label = FCLabel('%s:' % _("Squares Grid Parameters")) + self.squares_label = FCLabel('%s' % _("Squares Grid Parameters"), bold=True) self.layout.addWidget(self.squares_label) square_frame = FCFrame() @@ -220,7 +220,7 @@ class Tools2CThievingPrefGroupUI(OptionsGroupUI): # ############################################################################################################# # Lines Grid Parameters Frame # ############################################################################################################# - self.lines_label = FCLabel('%s:' % _("Lines Grid Parameters")) + self.lines_label = FCLabel('%s' % _("Lines Grid Parameters"), bold=True) self.layout.addWidget(self.lines_label) line_frame = FCFrame() diff --git a/appGUI/preferences/tools/ToolsFilmPrefGroupUI.py b/appGUI/preferences/tools/ToolsFilmPrefGroupUI.py index 187a8158..ef75ae59 100644 --- a/appGUI/preferences/tools/ToolsFilmPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsFilmPrefGroupUI.py @@ -44,11 +44,6 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI): _("A value greater than 1 will compact the film\n" "while a value less than 1 will jolt it.") ) - self.film_scale_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_scale_cb, 2, 0, 1, 2) # SCALE FRAME @@ -109,11 +104,6 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI): _("Positive values will skew to the right\n" "while negative values will skew to the left.") ) - self.film_skew_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_skew_cb, 8, 0, 1, 2) # SKEW FRAME @@ -171,11 +161,6 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI): self.film_mirror_cb.setToolTip( _("Mirror the film geometry on the selected axis or on both.") ) - self.film_mirror_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_mirror_cb, 12, 0, 1, 2) self.film_mirror_axis = RadioSet([{'label': _('X'), 'value': 'x'}, diff --git a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py index c0fdd5a4..0a041e38 100644 --- a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py @@ -39,7 +39,7 @@ class ToolsISOPrefGroupUI(OptionsGroupUI): par_frame.setLayout(par_grid) # Tool Dias - isotdlabel = FCLabel('%s:' % _('Tools Dia')) + isotdlabel = FCLabel('%s:' % _('Tools Dia'), color='green', bold=True) isotdlabel.setToolTip( _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" diff --git a/appGUI/preferences/tools/ToolsMillPrefGroupUI.py b/appGUI/preferences/tools/ToolsMillPrefGroupUI.py index 65cd74ea..00793fb0 100644 --- a/appGUI/preferences/tools/ToolsMillPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsMillPrefGroupUI.py @@ -38,7 +38,7 @@ class ToolsMillPrefGroupUI(OptionsGroupUI): param_frame.setLayout(param_grid) # Tooldia - tdlabel = FCLabel('%s:' % _('Tools Dia')) + tdlabel = FCLabel('%s:' % _('Tools Dia'), color='green', bold=True) tdlabel.setToolTip( _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" diff --git a/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py b/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py index b2dddf3f..c547ebb5 100644 --- a/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py @@ -40,7 +40,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): par_frame.setLayout(par_grid) # Tools Diameters - ncctdlabel = FCLabel('%s:' % _('Tools Dia')) + ncctdlabel = FCLabel('%s:' % _('Tools Dia'), color='green', bold=True) ncctdlabel.setToolTip( _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" diff --git a/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py b/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py index 85cbfc0a..789de600 100644 --- a/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py @@ -42,7 +42,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): par_frame.setLayout(param_grid) # Tool dia - ptdlabel = FCLabel('%s:' % _('Tools Dia')) + ptdlabel = FCLabel('%s:' % _('Tools Dia'), color='green', bold=True) ptdlabel.setToolTip( _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" diff --git a/appGUI/preferences/tools/ToolsSolderpastePrefGroupUI.py b/appGUI/preferences/tools/ToolsSolderpastePrefGroupUI.py index 0349b352..d4a83813 100644 --- a/appGUI/preferences/tools/ToolsSolderpastePrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsSolderpastePrefGroupUI.py @@ -39,7 +39,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): param_frame.setLayout(param_grid) # Nozzle Tool Diameters - nozzletdlabel = FCLabel('%s:' % _('Tools Dia')) + nozzletdlabel = FCLabel('%s:' % _('Tools Dia'), color='green', bold=True) nozzletdlabel.setToolTip( _("Diameters of the tools, separated by comma.\n" "The value of the diameter has to use the dot decimals separator.\n" @@ -51,7 +51,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI): param_grid.addWidget(self.nozzle_tool_dia_entry, 0, 1) # New Nozzle Tool Dia - self.addtool_entry_lbl = FCLabel('%s:' % _('New Nozzle Dia')) + self.addtool_entry_lbl = FCLabel('%s:' % _('New Nozzle Dia'), bold=True) self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool to add in the Tool Table") ) diff --git a/appGUI/preferences/utilities/AutoCompletePrefGroupUI.py b/appGUI/preferences/utilities/AutoCompletePrefGroupUI.py index ee8f2e88..93139239 100644 --- a/appGUI/preferences/utilities/AutoCompletePrefGroupUI.py +++ b/appGUI/preferences/utilities/AutoCompletePrefGroupUI.py @@ -33,7 +33,7 @@ class AutoCompletePrefGroupUI(OptionsGroupUI): hlay0.addWidget(self.del_all_btn) # ## Gerber associations - self.grb_list_label = FCLabel("%s:" % _("Keywords list")) + self.grb_list_label = FCLabel('%s:' % _("Keywords list"), bold=True) self.grb_list_label.setToolTip( _("List of keywords used by\n" "the autocompleter in FlatCAM.\n" diff --git a/appGUI/preferences/utilities/FAExcPrefGroupUI.py b/appGUI/preferences/utilities/FAExcPrefGroupUI.py index 8e3c1c8e..68a6a5f7 100644 --- a/appGUI/preferences/utilities/FAExcPrefGroupUI.py +++ b/appGUI/preferences/utilities/FAExcPrefGroupUI.py @@ -43,7 +43,7 @@ class FAExcPrefGroupUI(OptionsGroupUI): self.vertical_lay.addLayout(hlay0) # # ## Excellon associations - list_label = FCLabel("%s:" % _("Extensions list")) + list_label = FCLabel('%s:' % _("Extensions list"), bold=True) list_label.setToolTip( _("List of file extensions to be\n" "associated with FlatCAM.") diff --git a/appGUI/preferences/utilities/FAGcoPrefGroupUI.py b/appGUI/preferences/utilities/FAGcoPrefGroupUI.py index 84697c77..9df84f31 100644 --- a/appGUI/preferences/utilities/FAGcoPrefGroupUI.py +++ b/appGUI/preferences/utilities/FAGcoPrefGroupUI.py @@ -34,7 +34,7 @@ class FAGcoPrefGroupUI(OptionsGroupUI): hlay0.addWidget(self.del_all_btn) # ## G-Code associations - self.gco_list_label = FCLabel("%s:" % _("Extensions list")) + self.gco_list_label = FCLabel('%s:' % _("Extensions list"), bold=True) self.gco_list_label.setToolTip( _("List of file extensions to be\n" "associated with FlatCAM.") diff --git a/appGUI/preferences/utilities/FAGrbPrefGroupUI.py b/appGUI/preferences/utilities/FAGrbPrefGroupUI.py index fe1dbf53..dcec8eca 100644 --- a/appGUI/preferences/utilities/FAGrbPrefGroupUI.py +++ b/appGUI/preferences/utilities/FAGrbPrefGroupUI.py @@ -33,7 +33,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI): hlay0.addWidget(self.del_all_btn) # ## Gerber associations - self.grb_list_label = FCLabel("%s:" % _("Extensions list")) + self.grb_list_label = FCLabel('%s:' % _("Extensions list"), bold=True) self.grb_list_label.setToolTip( _("List of file extensions to be\n" "associated with FlatCAM.") diff --git a/appMain.py b/appMain.py index 37e74ba8..aed6b931 100644 --- a/appMain.py +++ b/appMain.py @@ -108,6 +108,8 @@ import gettext import appTranslation as fcTranslate import builtins +import darkdetect + if sys.platform == 'win32': import winreg @@ -610,6 +612,22 @@ class App(QtCore.QObject): # self.preferencesUiManager.show_preferences_gui() + # Set global_theme based on appearance + if self.options["global_appearance"] == 'auto': + if darkdetect.isDark(): + theme = 'dark' + else: + theme = 'light' + else: + if self.options["global_appearance"] == 'default': + theme = 'default' + elif self.options["global_appearance"] == 'dark': + theme = 'dark' + else: + theme = 'light' + + self.options["global_theme"] = theme + self.app_units = self.options["units"] self.default_units = self.defaults["units"] @@ -618,16 +636,14 @@ class App(QtCore.QObject): else: self.decimals = int(self.options['decimals_inch']) - if self.options["global_gray_icons"] is False: + if self.options["global_theme"] == 'default': self.resource_location = 'assets/resources' + elif self.options["global_theme"] == 'light': + self.resource_location = 'assets/resources' + self.qapp.setStyleSheet(qdarktheme.load_stylesheet('light')) else: self.resource_location = 'assets/resources/dark_resources' - - # ############################################################################################################# - # ######################################### DARK THEME ######################################################## - # ############################################################################################################# - if self.options["global_gray_icons"] is True: - qdarksheet.STYLE_SHEET = style_sheet.D_STYLE_SHEET # patching so I can do my own changes to the theme + qdarksheet.STYLE_SHEET = style_sheet.D_STYLE_SHEET self.qapp.setStyleSheet(qdarktheme.load_stylesheet()) # ########################################################################################################### @@ -1021,20 +1037,19 @@ class App(QtCore.QObject): self.FC_dark_blue = '#0000ffbf' theme_settings = QtCore.QSettings("Open Source", "FlatCAM") - if theme_settings.contains("theme"): - theme = theme_settings.value('theme', type=str) - else: - theme = 'white' + theme_settings.setValue("appearance", self.options["global_appearance"]) + theme_settings.setValue("theme", self.options["global_theme"]) + theme_settings.setValue("dark_canvas", self.options["global_dark_canvas"]) if self.options["global_cursor_color_enabled"]: self.cursor_color_3D = self.options["global_cursor_color"] else: - if theme == 'white': + if (theme == 'light' or theme == 'default') and not self.options["global_dark_canvas"]: self.cursor_color_3D = 'black' else: self.cursor_color_3D = 'gray' - # update the options dict with the setting in QSetting + # update the 'options' dict with the setting in QSetting self.options['global_theme'] = theme # ######################## @@ -8624,7 +8639,7 @@ class App(QtCore.QObject): root = d_properties_tw.invisibleRootItem() font = QtGui.QFont() font.setBold(True) - p_color = QtGui.QColor("#000000") if self.options['global_gray_icons'] is False else QtGui.QColor("#FFFFFF") + p_color = QtGui.QColor("#000000") if self.options['global_theme'] == 'light' else QtGui.QColor("#FFFFFF") # main Items categories general_cat = d_properties_tw.addParent(root, _('General'), expanded=True, color=p_color, font=font) @@ -9430,6 +9445,7 @@ class App(QtCore.QObject): return float('%.*f' % (dec_nr, float(val))) + class ArgsThread(QtCore.QObject): open_signal = pyqtSignal(list) start = pyqtSignal() diff --git a/appObjects/AppObjectTemplate.py b/appObjects/AppObjectTemplate.py index 192bb636..1e22e465 100644 --- a/appObjects/AppObjectTemplate.py +++ b/appObjects/AppObjectTemplate.py @@ -536,7 +536,7 @@ class FlatCAMObj(QtCore.QObject): font = QtGui.QFont() font.setBold(True) - p_color = QtGui.QColor("#000000") if self.app.options['global_gray_icons'] is False \ + p_color = QtGui.QColor("#000000") if self.app.options['global_theme'] == 'light' \ else QtGui.QColor("#FFFFFF") # main Items categories diff --git a/appObjects/ObjectCollection.py b/appObjects/ObjectCollection.py index d8fa9660..742aefab 100644 --- a/appObjects/ObjectCollection.py +++ b/appObjects/ObjectCollection.py @@ -508,7 +508,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): theme_settings = QtCore.QSettings("Open Source", "FlatCAM") theme = theme_settings.value('theme', type=str) - if theme in ['black', 'dark']: + if theme == 'dark': color = QColor(self.app.options['global_proj_item_color_dark'][:-2]) color_disabled = QColor(self.app.options['global_proj_item_dis_color_dark'][:-2]) else: diff --git a/appPlugins/ToolAlignObjects.py b/appPlugins/ToolAlignObjects.py index c8f1bfdb..d8e95ace 100644 --- a/appPlugins/ToolAlignObjects.py +++ b/appPlugins/ToolAlignObjects.py @@ -503,7 +503,7 @@ class AlignUI: par_frame.setLayout(grid2) # Alignment Type - self.a_type_lbl = FCLabel('%s:' % _("Alignment Type")) + self.a_type_lbl = FCLabel('%s:' % _("Alignment Type"), bold=True) self.a_type_lbl.setToolTip( _("The type of alignment can be:\n" "- Single Point -> it require a single point of sync, the action will be a translation\n" diff --git a/appPlugins/ToolCalibration.py b/appPlugins/ToolCalibration.py index a265562d..a897b58d 100644 --- a/appPlugins/ToolCalibration.py +++ b/appPlugins/ToolCalibration.py @@ -767,7 +767,7 @@ class CalibrationUI: grid_lay = GLay(v_spacing=5, h_spacing=3, c_stretch=[0, 1, 0]) self.layout.addLayout(grid_lay) - self.gcode_title_label = FCLabel('%s:' % _('Parameters')) + self.gcode_title_label = FCLabel('%s:' % _('Parameters'), bold=True) self.gcode_title_label.setToolTip( _("Parameters used when creating the GCode in this tool.") ) @@ -873,7 +873,7 @@ class CalibrationUI: grid_lay.addWidget(FCLabel(''), 9, 0, 1, 3) - step_1 = FCLabel('%s' % _("STEP 1: Acquire Calibration Points")) + step_1 = FCLabel('%s' % _("STEP 1: Acquire Calibration Points"), bold=True) step_1.setToolTip( _("Pick four points by clicking on canvas.\n" "Those four points should be in the four\n" @@ -881,7 +881,7 @@ class CalibrationUI: ) grid_lay.addWidget(step_1, 10, 0, 1, 3) - self.cal_source_lbl = FCLabel("%s:" % _("Source Type")) + self.cal_source_lbl = FCLabel('%s:' % _("Source Type"), bold=True) self.cal_source_lbl.setToolTip(_("The source of calibration points.\n" "It can be:\n" "- Object -> click a hole geo for Excellon or a pad for Gerber\n" @@ -918,7 +918,7 @@ class CalibrationUI: grid_lay.addWidget(self.object_label, 13, 0, 1, 3) grid_lay.addWidget(self.object_combo, 14, 0, 1, 3) - self.points_table_label = FCLabel('%s' % _('Calibration Points')) + self.points_table_label = FCLabel('%s' % _('Calibration Points'), bold=True) self.points_table_label.setToolTip( _("Contain the expected calibration points and the\n" "ones measured.") @@ -1090,7 +1090,7 @@ class CalibrationUI: grid_lay.addWidget(FCLabel(''), 19, 0) # STEP 2 # - step_2 = FCLabel('%s' % _("STEP 2: Verification GCode")) + step_2 = FCLabel('%s' % _("STEP 2: Verification GCode"), bold=True) step_2.setToolTip( _("Generate GCode file to locate and align the PCB by using\n" "the four points acquired above.\n" @@ -1129,7 +1129,7 @@ class CalibrationUI: grid_lay.addWidget(FCLabel(''), 23, 0, 1, 3) # STEP 3 # - step_3 = FCLabel('%s' % _("STEP 3: Adjustments")) + step_3 = FCLabel('%s' % _("STEP 3: Adjustments"), bold=True) step_3.setToolTip( _("Calculate Scale and Skew factors based on the differences (delta)\n" "found when checking the PCB pattern. The differences must be filled\n" @@ -1160,7 +1160,7 @@ class CalibrationUI: grid_lay.addWidget(FCLabel(''), 27, 0, 1, 3) # STEP 4 # - step_4 = FCLabel('%s' % _("STEP 4: Adjusted GCode")) + step_4 = FCLabel('%s' % _("STEP 4: Adjusted GCode"), bold=True) step_4.setToolTip( _("Generate verification GCode file adjusted with\n" "the factors above.") @@ -1241,7 +1241,7 @@ class CalibrationUI: """) grid_lay.addWidget(self.skew_button, 34, 0, 1, 3) - # final_factors_lbl = FCLabel('%s' % _("Final Factors")) + # final_factors_lbl = FCLabel('%s' % _("Final Factors"), bold=True) # final_factors_lbl.setToolTip( # _("Generate verification GCode file adjusted with\n" # "the factors above.") @@ -1323,7 +1323,7 @@ class CalibrationUI: grid_lay.addWidget(FCLabel(''), 44, 0, 1, 3) # STEP 5 # - step_5 = FCLabel('%s' % _("STEP 5: Calibrate FlatCAM Objects")) + step_5 = FCLabel('%s' % _("STEP 5: Calibrate FlatCAM Objects"), bold=True) step_5.setToolTip( _("Adjust the FlatCAM objects\n" "with the factors determined and verified above.") diff --git a/appPlugins/ToolCopperThieving.py b/appPlugins/ToolCopperThieving.py index debcf626..9d03c758 100644 --- a/appPlugins/ToolCopperThieving.py +++ b/appPlugins/ToolCopperThieving.py @@ -1449,7 +1449,7 @@ class ThievingUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) dots_grid.addWidget(separator_line, 0, 0, 1, 2) - self.dots_label = FCLabel('%s:' % _("Dots Grid Parameters")) + self.dots_label = FCLabel('%s' % _("Dots Grid Parameters"), bold=True) dots_grid.addWidget(self.dots_label, 2, 0, 1, 2) # Dot diameter # @@ -1495,7 +1495,7 @@ class ThievingUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) squares_grid.addWidget(separator_line, 0, 0, 1, 2) - self.squares_label = FCLabel('%s:' % _("Squares Grid Parameters")) + self.squares_label = FCLabel('%s' % _("Squares Grid Parameters"), bold=True) squares_grid.addWidget(self.squares_label, 2, 0, 1, 2) # Square Size # @@ -1541,7 +1541,7 @@ class ThievingUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) lines_grid.addWidget(separator_line, 0, 0, 1, 2) - self.lines_label = FCLabel('%s:' % _("Lines Grid Parameters")) + self.lines_label = FCLabel('%s' % _("Lines Grid Parameters"), bold=True) lines_grid.addWidget(self.lines_label, 2, 0, 1, 2) # Line Size # diff --git a/appPlugins/ToolDblSided.py b/appPlugins/ToolDblSided.py index a4149570..8643adb6 100644 --- a/appPlugins/ToolDblSided.py +++ b/appPlugins/ToolDblSided.py @@ -884,7 +884,7 @@ class DsidedUI: grid_mirror.addWidget(separator_line, 3, 0, 1, 3) # ## Reference - self.axloc_label = FCLabel('%s:' % _("Reference")) + self.axloc_label = FCLabel('%s' % _("Reference"), bold=True) self.axloc_label.setToolTip( _("The coordinates used as reference for the mirror operation.\n" "Can be:\n" @@ -980,7 +980,7 @@ class DsidedUI: grid_snap_ref.setContentsMargins(0, 0, 0, 0) self.sr_frame.setLayout(grid_snap_ref) - self.exc_hole_lbl = FCLabel('%s:' % _("Excellon")) + self.exc_hole_lbl = FCLabel('%s' % _("Excellon"), bold=True) self.exc_hole_lbl.setToolTip( _("Object that holds holes that can be picked as reference for mirroring.") ) diff --git a/appPlugins/ToolDistance.py b/appPlugins/ToolDistance.py index 316ac0ea..a7f4ec28 100644 --- a/appPlugins/ToolDistance.py +++ b/appPlugins/ToolDistance.py @@ -764,15 +764,20 @@ class Distance(AppTool): if settings.contains("theme"): theme = settings.value('theme', type=str) else: - theme = 'white' + theme = 'default' + + if settings.contains("dark_canvas"): + dark_canvas = settings.value('dark_canvas', type=bool) + else: + dark_canvas = False if self.app.use_3d_engine: - if theme == 'white': + if (theme == 'default' or theme == 'light') and not dark_canvas: color = '#000000FF' else: color = '#FFFFFFFF' else: - if theme == 'white': + if (theme == 'default' or theme == 'light') and not dark_canvas: color = '#000000' else: color = '#FFFFFF' @@ -958,7 +963,7 @@ class DistanceUI: res_grid.addWidget(separator_line, 8, 0, 1, 3) # Distance - self.total_distance_label = FCLabel("%s:" % _('DISTANCE')) + self.total_distance_label = FCLabel('%s:' % _('DISTANCE'), bold=True) self.total_distance_label.setToolTip(_("This is the point to point Euclidian distance.")) self.total_distance_entry = FCEntry() diff --git a/appPlugins/ToolExtract.py b/appPlugins/ToolExtract.py index 9585784c..b8e6cbf4 100644 --- a/appPlugins/ToolExtract.py +++ b/appPlugins/ToolExtract.py @@ -1186,7 +1186,7 @@ class ExtractUI: self.ring_box.addLayout(ring_grid) # Annular Ring value - self.ring_label = FCLabel('%s' % _("Fixed Annular Ring")) + self.ring_label = FCLabel('%s' % _("Fixed Annular Ring"), bold=True) self.ring_label.setToolTip( _("The size of annular ring.\n" "The copper sliver between the hole exterior\n" @@ -1271,7 +1271,7 @@ class ExtractUI: self.fix_frame.setLayout(fixed_grid) # Fixed Diameter - self.fixed_label = FCLabel('%s' % _("Fixed Diameter")) + self.fixed_label = FCLabel('%s' % _("Fixed Diameter"), bold=True) fixed_grid.addWidget(self.fixed_label, 2, 0, 1, 2) # Diameter value @@ -1299,7 +1299,7 @@ class ExtractUI: self.prop_frame.setLayout(prop_grid) # Proportional Diameter - self.prop_label = FCLabel('%s' % _("Proportional Diameter")) + self.prop_label = FCLabel('%s' % _("Proportional Diameter"), bold=True) prop_grid.addWidget(self.prop_label, 0, 0, 1, 2) # Diameter value diff --git a/appPlugins/ToolFilm.py b/appPlugins/ToolFilm.py index fba56017..8efffa3f 100644 --- a/appPlugins/ToolFilm.py +++ b/appPlugins/ToolFilm.py @@ -1351,11 +1351,6 @@ class FilmUI: _("A value greater than 1 will compact the film\n" "while a value less than 1 will jolt it.") ) - self.film_scale_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_scale_cb, 2, 0, 1, 2) # Scale Type @@ -1426,11 +1421,6 @@ class FilmUI: _("Positive values will skew to the right\n" "while negative values will skew to the left.") ) - self.film_skew_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_skew_cb, 14, 0, 1, 2) # Skew Type @@ -1501,11 +1491,6 @@ class FilmUI: self.film_mirror_cb.setToolTip( _("Mirror the film geometry on the selected axis or on both.") ) - self.film_mirror_cb.setStyleSheet( - """ - QCheckBox {font-weight: bold; color: black} - """ - ) adj_grid.addWidget(self.film_mirror_cb, 26, 0, 1, 2) self.film_mirror_axis = RadioSet([{'label': _('X'), 'value': 'x'}, diff --git a/appPlugins/ToolImage.py b/appPlugins/ToolImage.py index 233b353b..18791c24 100644 --- a/appPlugins/ToolImage.py +++ b/appPlugins/ToolImage.py @@ -346,7 +346,7 @@ class ImageUI: # Type of image interpretation self.image_type = RadioSet([{'label': 'B/W', 'value': 'black'}, {'label': 'Color', 'value': 'color'}]) - self.image_type_label = FCLabel("%s:" % _('Image type')) + self.image_type_label = FCLabel('%s:' % _('Image type'), bold=True) self.image_type_label.setToolTip( _("Choose a method for the image interpretation.\n" "B/W means a black & white image. Color means a colored image.") diff --git a/appPlugins/ToolIsolation.py b/appPlugins/ToolIsolation.py index 8dbc70c5..acdc7e0e 100644 --- a/appPlugins/ToolIsolation.py +++ b/appPlugins/ToolIsolation.py @@ -3470,7 +3470,7 @@ class IsoUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) new_tool_grid.addWidget(separator_line, 0, 0, 1, 3) - self.tool_sel_label = FCLabel('%s' % _('Add from DB')) + self.tool_sel_label = FCLabel('%s' % _('Add from DB'), bold=True) new_tool_grid.addWidget(self.tool_sel_label, 2, 0, 1, 3) # ### Tool Diameter #### diff --git a/appPlugins/ToolLevelling.py b/appPlugins/ToolLevelling.py index f99f5a3d..c8393041 100644 --- a/appPlugins/ToolLevelling.py +++ b/appPlugins/ToolLevelling.py @@ -1794,7 +1794,7 @@ class LevelUI: grid0 = GLay(v_spacing=5, h_spacing=3) self.al_box.addLayout(grid0) - self.al_title = FCLabel('%s' % _("Probe Points Table")) + self.al_title = FCLabel('%s' % _("Probe Points Table"), bold=True) self.al_title.setToolTip(_("Generate GCode that will obtain the height map")) self.show_al_table = FCCheckBox(_("Show")) @@ -1894,7 +1894,7 @@ class LevelUI: param_grid.addWidget(separator_line, 6, 0, 1, 2) # AUTOLEVELL MODE - al_mode_lbl = FCLabel('%s:' % _("Mode")) + al_mode_lbl = FCLabel('%s' % _("Mode"), bold=True) al_mode_lbl.setToolTip(_("Choose a mode for height map generation.\n" "- Manual: will pick a selection of probe points by clicking on canvas\n" "- Grid: will automatically generate a grid of probe points")) diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index 39ae0437..23f29e7a 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -4184,7 +4184,7 @@ class MillingUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) new_tool_grid.addWidget(separator_line, 0, 0, 1, 2) - self.tool_sel_label = FCLabel('%s' % _("Add from DB")) + self.tool_sel_label = FCLabel('%s' % _("Add from DB"), bold=True) new_tool_grid.addWidget(self.tool_sel_label, 2, 0, 1, 2) self.addtool_entry_lbl = FCLabel('%s:' % _('Tool Dia')) diff --git a/appPlugins/ToolNCC.py b/appPlugins/ToolNCC.py index 982bba2d..66f44520 100644 --- a/appPlugins/ToolNCC.py +++ b/appPlugins/ToolNCC.py @@ -4193,7 +4193,7 @@ class NccUI: # ############################################################# # ############### Tool selection ############################## # ############################################################# - self.tool_sel_label = FCLabel('%s' % _('Add from DB')) + self.tool_sel_label = FCLabel('%s' % _('Add from DB'), bold=True) new_tool_grid.addWidget(self.tool_sel_label, 2, 0, 1, 3) # ### Tool Diameter #### diff --git a/appPlugins/ToolObjectDistance.py b/appPlugins/ToolObjectDistance.py index 3679a534..88d17eb4 100644 --- a/appPlugins/ToolObjectDistance.py +++ b/appPlugins/ToolObjectDistance.py @@ -570,7 +570,7 @@ class ObjectDistanceUI: res_grid.addWidget(separator_line, 6, 0, 1, 3) # Total Distance - self.total_distance_label = FCLabel("%s:" % _('DISTANCE')) + self.total_distance_label = FCLabel('%s:' % _('DISTANCE'), bold=True) self.total_distance_label.setToolTip(_("This is the point to point Euclidian distance.")) self.total_distance_entry = FCEntry() @@ -584,7 +584,7 @@ class ObjectDistanceUI: res_grid.addWidget(FCLabel("%s" % self.units), 8, 2) # Half Point - self.half_point_label = FCLabel("%s:" % _('Half Point')) + self.half_point_label = FCLabel('%s:' % _('Half Point'), bold=True) self.half_point_label.setToolTip(_("This is the middle point of the point to point Euclidean distance.")) self.half_point_entry = FCEntry() diff --git a/appPlugins/ToolOptimal.py b/appPlugins/ToolOptimal.py index 830dea85..60d29a5d 100644 --- a/appPlugins/ToolOptimal.py +++ b/appPlugins/ToolOptimal.py @@ -494,7 +494,7 @@ class OptimalUI: self.gerber_object_combo.is_last = True self.gerber_object_combo.obj_type = "Gerber" - self.gerber_object_label = FCLabel("%s:" % _("GERBER")) + self.gerber_object_label = FCLabel('%s:' % _("GERBER"), bold=True) self.gerber_object_label.setToolTip( "Gerber object for which to find the minimum distance between copper features." ) diff --git a/appPlugins/ToolPaint.py b/appPlugins/ToolPaint.py index 620e9d2a..03690b15 100644 --- a/appPlugins/ToolPaint.py +++ b/appPlugins/ToolPaint.py @@ -3041,7 +3041,7 @@ class PaintUI: "L = laser")) # Tool Order - self.order_label = FCLabel('%s:' % _('Tool order')) + self.order_label = FCLabel('%s:' % _('Tool order'), bold=True) self.order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n" "'Default' --> means that the used order is the one in the tool table\n" "'Forward' --> means that the tools will be ordered from small to big\n" @@ -3071,7 +3071,7 @@ class PaintUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) new_tool_grid.addWidget(separator_line, 0, 0, 1, 2) - self.tool_sel_label = FCLabel('%s' % _('Add from DB')) + self.tool_sel_label = FCLabel('%s' % _('Add from DB'), bold=True) new_tool_grid.addWidget(self.tool_sel_label, 2, 0, 1, 2) # ### Tool Diameter #### diff --git a/appPlugins/ToolPanelize.py b/appPlugins/ToolPanelize.py index 6bb55144..158de065 100644 --- a/appPlugins/ToolPanelize.py +++ b/appPlugins/ToolPanelize.py @@ -1344,7 +1344,7 @@ class PanelizeUI: # Type of resulting Panel object self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'}, {'label': _('Geo'), 'value': 'geometry'}]) - self.panel_type_label = FCLabel("%s:" % _("Panel Type")) + self.panel_type_label = FCLabel('%s:' % _("Panel Type"), bold=True) self.panel_type_label.setToolTip( _("Choose the type of object for the panel object:\n" "- Gerber\n" diff --git a/appPlugins/ToolPcbWizard.py b/appPlugins/ToolPcbWizard.py index d23cd9f1..0c2cab65 100644 --- a/appPlugins/ToolPcbWizard.py +++ b/appPlugins/ToolPcbWizard.py @@ -484,7 +484,7 @@ class WizardUI: # Units type self.units_radio = RadioSet([{'label': _('Inch'), 'value': 'INCH'}, {'label': _('mm'), 'value': 'METRIC'}]) - self.units_label = FCLabel("%s:" % _('Units')) + self.units_label = FCLabel('%s:' % _('Units'), bold=True) self.units_label.setToolTip( _("The type of units that the coordinates and tool\n" "diameters are using. Can be INCH or MM.") diff --git a/appPlugins/ToolPunchGerber.py b/appPlugins/ToolPunchGerber.py index 325bb021..1d04a24f 100644 --- a/appPlugins/ToolPunchGerber.py +++ b/appPlugins/ToolPunchGerber.py @@ -2173,7 +2173,7 @@ class PunchUI: separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) grid1.addWidget(separator_line, 2, 0, 1, 2) - self.exc_label = FCLabel('%s' % _("Excellon")) + self.exc_label = FCLabel('%s' % _("Excellon"), bold=True) self.exc_label.setToolTip( _("Remove the geometry of Excellon from the Gerber to create the holes in pads.") ) @@ -2188,7 +2188,7 @@ class PunchUI: grid1.addWidget(self.exc_combo, 6, 0, 1, 2) # Fixed Dia - self.fixed_label = FCLabel('%s' % _("Fixed Diameter")) + self.fixed_label = FCLabel('%s' % _("Fixed Diameter"), bold=True) grid1.addWidget(self.fixed_label, 8, 0, 1, 2) # Diameter value @@ -2216,7 +2216,7 @@ class PunchUI: self.ring_frame.setLayout(self.ring_box) # Annular Ring value - self.ring_label = FCLabel('%s' % _("Fixed Annular Ring")) + self.ring_label = FCLabel('%s' % _("Fixed Annular Ring"), bold=True) self.ring_label.setToolTip( _("The size of annular ring.\n" "The copper sliver between the hole exterior\n" @@ -2295,7 +2295,7 @@ class PunchUI: # ############################################################################################################# # Proportional value - self.prop_label = FCLabel('%s' % _("Proportional Diameter")) + self.prop_label = FCLabel('%s' % _("Proportional Diameter"), bold=True) grid1.addWidget(self.prop_label, 14, 0, 1, 2) # Diameter value diff --git a/appPlugins/ToolReport.py b/appPlugins/ToolReport.py index c8193269..1e93783e 100644 --- a/appPlugins/ToolReport.py +++ b/appPlugins/ToolReport.py @@ -158,7 +158,7 @@ class ObjectReport(AppTool): font = QtGui.QFont() font.setBold(True) - p_color = QtGui.QColor("#000000") if self.app.options['global_gray_icons'] is False \ + p_color = QtGui.QColor("#000000") if self.app.options['global_theme'] == 'light' \ else QtGui.QColor("#FFFFFF") # main Items categories diff --git a/appPlugins/ToolSolderPaste.py b/appPlugins/ToolSolderPaste.py index d95de190..58586eed 100644 --- a/appPlugins/ToolSolderPaste.py +++ b/appPlugins/ToolSolderPaste.py @@ -1268,7 +1268,7 @@ class SolderUI: _("Tool Diameter. Its value\n" "is the width of the solder paste dispensed.")) - self.addtool_entry_lbl = FCLabel('%s:' % _('New Tool')) + self.addtool_entry_lbl = FCLabel('%s:' % _('New Tool'), bold=True) self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool to add in the Tool Table") ) diff --git a/appPlugins/ToolSub.py b/appPlugins/ToolSub.py index a6b42da3..f16de017 100644 --- a/appPlugins/ToolSub.py +++ b/appPlugins/ToolSub.py @@ -901,7 +901,7 @@ class SubUI: geo_grid = GLay(v_spacing=5, h_spacing=3) geo_frame.setLayout(geo_grid) - self.geo_title = FCLabel("%s" % _("GEOMETRY")) + self.geo_title = FCLabel('%s' % _("GEOMETRY"), bold=True) self.tools_box.addWidget(self.geo_title) # Target Geometry Object diff --git a/appTranslation.py b/appTranslation.py index 470ccaba..ed0964e9 100644 --- a/appTranslation.py +++ b/appTranslation.py @@ -93,12 +93,12 @@ def on_language_apply_click(app, restart=False): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': resource_loc = 'assets/resources' else: - resource_loc = 'assets/resources' + resource_loc = 'assets/resources/dark_resources' # do nothing if trying to apply the language that is the current language (already applied). settings = QSettings("Open Source", "FlatCAM") @@ -190,12 +190,12 @@ def restart_program(app, ask=None): if theme_settings.contains("theme"): theme = theme_settings.value('theme', type=str) else: - theme = 'white' + theme = 'light' - if theme == 'white': + if theme == 'light': resource_loc = 'assets/resources' else: - resource_loc = 'assets/resources' + resource_loc = 'assets/resources/dark_resources' # try to quit the Socket opened by ArgsThread class try: diff --git a/camlib.py b/camlib.py index 03565efc..ba507532 100644 --- a/camlib.py +++ b/camlib.py @@ -7192,7 +7192,7 @@ class CNCjob(Geometry): return try: - if self.app.options['global_theme'] == 'white': + if self.app.options['global_theme'] == 'light': obj.annotation.set(text=text, pos=pos, visible=obj.obj_options['plot'], font_size=self.app.options["cncjob_annotation_fontsize"], color=self.app.options["cncjob_annotation_fontcolor"]) diff --git a/defaults.py b/defaults.py index 1bf2634e..2cd38352 100644 --- a/defaults.py +++ b/defaults.py @@ -112,8 +112,9 @@ class AppDefaults: "global_tpdf_rmargin": 20.0, # General GUI Preferences - "global_theme": 'white', - "global_gray_icons": False, + "global_appearance": 'default', + "global_dark_canvas": False, + "global_theme": 'default', "global_layout": "compact", "global_hover_shape": False, @@ -129,8 +130,8 @@ class AppDefaults: # Project Items colors "global_proj_item_color_light": '#000000FF', "global_proj_item_dis_color_light": '#b7b7cbFF', - "global_proj_item_color_dark": '#4385C8FF', - "global_proj_item_dis_color_dark": '#61616CFF', + "global_proj_item_color_dark": '#F2F2F2FF', + "global_proj_item_dis_color_dark": '#a6a6a6ff', "global_project_autohide": True, diff --git a/requirements.txt b/requirements.txt index 37809140..be98b3e6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,4 +43,7 @@ vispy>=0.9.0 pyqtdarktheme gdal -rasterio \ No newline at end of file +rasterio + +# To detect OS dark mode +darkdetect