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

- fixed a bug in the FlatCAMGerber.on_mark_cb_click_table() method when moving a Gerber object
- added a way to remember the colors set for the Gerber objects; it will remember the order that they were loaded and set a color previously given

Marius Stanciu 5 лет назад
Родитель
Сommit
ebdb2b3ca0
6 измененных файлов с 135 добавлено и 4 удалено
  1. 5 0
      CHANGELOG.md
  2. 79 0
      Common.py
  3. 30 2
      appObjects/AppObject.py
  4. 5 1
      appObjects/FlatCAMGerber.py
  5. 13 0
      app_Main.py
  6. 3 1
      defaults.py

+ 5 - 0
CHANGELOG.md

@@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta
 
 =================================================
 
+20.07.2020
+
+- fixed a bug in the FlatCAMGerber.on_mark_cb_click_table() method when moving a Gerber object
+- added a way to remember the colors set for the Gerber objects; it will remember the order that they were loaded and set a color previously given
+
 18.07.2020
 
 - added some icons in the Code Editor

+ 79 - 0
Common.py

@@ -19,6 +19,7 @@ from appGUI.VisPyVisuals import ShapeCollection
 from appTool import AppTool
 
 from copy import deepcopy
+import collections
 
 import numpy as np
 
@@ -81,6 +82,84 @@ class LoudDict(dict):
         self.callback = callback
 
 
+class LoudUniqueList(list, collections.MutableSequence):
+    """
+    A List with a callback for item changes, callback which returns the index where the items are added/modified.
+    A List that will allow adding only items that are not in the list.
+    """
+
+    def __init__(self, arg=None):
+        super().__init__()
+        self.callback = lambda x: None
+
+        if not arg is None:
+            if isinstance(arg, list):
+                self.extend(arg)
+            else:
+                self.extend([arg])
+
+    def insert(self, i, v):
+        if v in self:
+            raise ValueError("One of the added items is already in the list.")
+        self.callback(i)
+        return super().insert(i, v)
+
+    def append(self, v):
+        if v in self:
+            raise ValueError("One of the added items is already in the list.")
+        l = len(self)
+        self.callback(l)
+        return super().append(v)
+
+    def extend(self, t):
+        for v in t:
+            if v in self:
+                raise ValueError("One of the added items is already in the list.")
+        l = len(self)
+        self.callback(l)
+        return super().extend(t)
+
+    def __add__(self, t):  # This is for something like `LoudUniqueList([1, 2, 3]) + list([4, 5, 6])`...
+        for v in t:
+            if v in self:
+                raise ValueError("One of the added items is already in the list.")
+        l = len(self)
+        self.callback(l)
+        return super().__add__(t)
+
+    def __iadd__(self, t):  # This is for something like `l = LoudUniqueList(); l += [1, 2, 3]`
+        for v in t:
+            if v in self:
+                raise ValueError("One of the added items is already in the list.")
+        l = len(self)
+        self.callback(l)
+        return super().__iadd__(t)
+
+    def __setitem__(self, i, v):
+        try:
+            for v1 in v:
+                if v1 in self:
+                    raise ValueError("One of the modified items is already in the list.")
+        except TypeError:
+            if v in self:
+                raise ValueError("One of the modified items is already in the list.")
+        if not v is None:
+            self.callback(i)
+        return super().__setitem__(i, v)
+
+    def set_callback(self, callback):
+        """
+        Assigns a function as callback on item change. The callback
+        will receive the index of the object that was changed.
+
+        :param callback: Function to call on item change.
+        :type callback: func
+        :return: None
+        """
+
+        self.callback = callback
+
+
 class FCSignal:
     """
     Taken from here: https://blog.abstractfactory.io/dynamic-signals-in-pyqt/

+ 30 - 2
appObjects/AppObject.py

@@ -193,14 +193,33 @@ class AppObject(QtCore.QObject):
                 log.warning("AppObject.new_object() -> The object has no bounds properties. %s" % str(e))
                 return "fail"
 
+        # ############################################################################################################
+        # Set the colors for the objects that have geometry
+        # ############################################################################################################
+        if kind != 'document' and kind != 'script':
             try:
                 if kind == 'excellon':
                     obj.fill_color = self.app.defaults["excellon_plot_fill"]
                     obj.outline_color = self.app.defaults["excellon_plot_line"]
 
                 if kind == 'gerber':
-                    obj.fill_color = self.app.defaults["gerber_plot_fill"]
-                    obj.outline_color = self.app.defaults["gerber_plot_line"]
+                    group = self.app.collection.group_items["gerber"]
+                    index = group.child_count()
+
+                    # when loading a Gerber object always create a color tuple (line color, fill_color)
+                    # and add it to the self.app.defaults["gerber_color_list"] from where it will be picked and used
+                    try:
+                        colors = self.app.defaults["gerber_color_list"][index]
+                    except IndexError:
+                        obj.outline_color = self.app.defaults["gerber_plot_line"]
+                        obj.fill_color = self.app.defaults["gerber_plot_fill"]
+                        self.app.defaults["gerber_color_list"].insert(index, (obj.outline_color, obj.fill_color))
+                        colors = self.app.defaults["gerber_color_list"][index]
+
+                    new_line_color = colors[0]
+                    new_color = colors[1]
+                    obj.outline_color = new_line_color
+                    obj.fill_color = new_color
             except Exception as e:
                 log.warning("AppObject.new_object() -> setting colors error. %s" % str(e))
 
@@ -319,6 +338,7 @@ class AppObject(QtCore.QObject):
         :param auto_select: if the newly created object to be autoselected after creation
         :return: None
         """
+
         t0 = time.time()  # DEBUG
         log.debug("on_object_created()")
 
@@ -330,6 +350,10 @@ class AppObject(QtCore.QObject):
 
         # self.app.inform.emit('[selected] %s created & selected: %s' %
         #                  (str(obj.kind).capitalize(), str(obj.options['name'])))
+
+        # #############################################################################################################
+        # ######################  Set colors for the message in the Status Bar  #######################################
+        # #############################################################################################################
         if obj.kind == 'gerber':
             self.app.inform.emit('[selected] {kind} {tx}: <span style="color:{color};">{name}</span>'.format(
                 kind=obj.kind.capitalize(),
@@ -367,7 +391,9 @@ class AppObject(QtCore.QObject):
                 name=str(obj.options['name']), tx=_("created/selected"))
             )
 
+        # #############################################################################################################
         # update the SHELL auto-completer model with the name of the new object
+        # #############################################################################################################
         self.app.shell._edit.set_model_data(self.app.myKeywords)
 
         if auto_select:
@@ -382,6 +408,8 @@ class AppObject(QtCore.QObject):
             with self.app.proc_container.new(_("Plotting")):
                 if t_obj.kind == 'cncjob':
                     t_obj.plot(kind=self.app.defaults["cncjob_plot_kind"])
+                if t_obj.kind == 'gerber':
+                    t_obj.plot(color=t_obj.outline_color, face_color=t_obj.fill_color)
                 else:
                     t_obj.plot()
 

+ 5 - 1
appObjects/FlatCAMGerber.py

@@ -1042,7 +1042,11 @@ class GerberObject(FlatCAMObj, Gerber):
 
         self.marked_rows[:] = []
 
-        aperture = self.ui.apertures_table.item(cw_row, 1).text()
+        try:
+            aperture = self.ui.apertures_table.item(cw_row, 1).text()
+        except AttributeError:
+            self.ui_connect()
+            return
 
         if self.ui.apertures_table.cellWidget(cw_row, 5).isChecked():
             self.marked_rows.append(True)

+ 13 - 0
app_Main.py

@@ -10127,6 +10127,19 @@ class App(QtCore.QObject):
                 update_colors=(new_color, new_line_color)
             )
 
+        # make sure to set the color in the Gerber colors storage self.defaults["gerber_color_list"]
+        group = self.collection.group_items["gerber"]
+        group_index = self.collection.index(group.row(), 0, QtCore.QModelIndex())
+
+        new_c = (new_color, new_line_color)
+
+        for sel_obj in sel_obj_list:
+            if sel_obj.kind == 'gerber':
+                item = sel_obj.item
+                item_index = self.collection.index(item.row(), 0, group_index)
+                idx = item_index.row()
+                self.defaults["gerber_color_list"][idx] = new_c
+
     def generate_cnc_job(self, objects):
         """
         Slot that will be called by clicking an entry in the contextual menu generated in the Project Tab tree

+ 3 - 1
defaults.py

@@ -2,7 +2,7 @@ import os
 import stat
 import sys
 from copy import deepcopy
-from Common import LoudDict
+from Common import LoudDict, LoudUniqueList
 from camlib import to_dict, CNCjob, Geometry
 import simplejson
 import logging
@@ -156,6 +156,8 @@ class FlatCAMDefaults:
         "gerber_plot": True,
         "gerber_solid": True,
         "gerber_multicolored": False,
+        "gerber_color_list": LoudUniqueList(),
+
         "gerber_circle_steps": 64,
         "gerber_use_buffer_for_union": True,
         "gerber_clean_apertures": True,