Browse Source

CURA-4525 created CuraSceneController and took out logic from ObjectsModel and BuildPlateModel

Jack Ha 7 years ago
parent
commit
8c7a0d4a8e

+ 11 - 41
cura/BuildPlateModel.py

@@ -1,7 +1,6 @@
-from UM.Qt.ListModel import ListModel
 from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot
-from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
-from UM.Scene.SceneNode import SceneNode
+
+from UM.Qt.ListModel import ListModel
 from UM.Scene.Selection import Selection
 from UM.Logger import Logger
 from UM.Application import Application
@@ -14,7 +13,6 @@ class BuildPlateModel(ListModel):
 
     def __init__(self):
         super().__init__()
-        Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlate)  # it may be a bit inefficient when changing a lot simultaneously
         Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSelectedObjectBuildPlateNumbers)
         Selection.selectionChanged.connect(self._updateSelectedObjectBuildPlateNumbers)
 
@@ -22,50 +20,22 @@ class BuildPlateModel(ListModel):
         self._active_build_plate = -1
         self._selection_build_plates = []
 
-    @pyqtSlot(int)
-    def setActiveBuildPlate(self, nr):
-        if nr == self._active_build_plate:
-            return
-        Logger.log("d", "Select build plate: %s" % nr)
-        self._active_build_plate = nr
-        Selection.clear()
-
-        self.activeBuildPlateChanged.emit()
-
-    @pyqtProperty(int, notify = activeBuildPlateChanged)
-    def activeBuildPlate(self):
-        return self._active_build_plate
+    def setMaxBuildPlate(self, max_build_plate):
+        self._max_build_plate = max_build_plate
+        self.maxBuildPlateChanged.emit()
 
     ##  Return the highest build plate number
     @pyqtProperty(int, notify = maxBuildPlateChanged)
     def maxBuildPlate(self):
         return self._max_build_plate
 
-    def updateMaxBuildPlate(self, *args):
-        if args:
-            source = args[0]
-        else:
-            source = None
-        if not issubclass(type(source), SceneNode):
-            return
-        max_build_plate = self._calcMaxBuildPlate()
-        changed = False
-        if max_build_plate != self._max_build_plate:
-            self._max_build_plate = max_build_plate
-            changed = True
-        if changed:
-            self.maxBuildPlateChanged.emit()
-            build_plates = [{"name": "Build Plate %d" % (i + 1), "buildPlateNumber": i} for i in range(self._max_build_plate + 1)]
-            self.setItems(build_plates)
-            self.itemsChanged.emit()
+    def setActiveBuildPlate(self, nr):
+        self._active_build_plate = nr
+        self.activeBuildPlateChanged.emit()
 
-    def _calcMaxBuildPlate(self):
-        max_build_plate = 0
-        for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
-            if node.callDecoration("isSliceable"):
-                build_plate_number = node.callDecoration("getBuildPlateNumber")
-                max_build_plate = max(build_plate_number, max_build_plate)
-        return max_build_plate
+    @pyqtProperty(int, notify = activeBuildPlateChanged)
+    def activeBuildPlate(self):
+        return self._active_build_plate
 
     @staticmethod
     def createBuildPlateModel():

+ 18 - 9
cura/CuraApplication.py

@@ -33,7 +33,10 @@ from UM.Operations.GroupedOperation import GroupedOperation
 from UM.Operations.SetTransformOperation import SetTransformOperation
 
 from cura.Arranging.Arrange import Arrange
+from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
+from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
 from cura.Arranging.ShapeArray import ShapeArray
+from cura.MultiplyObjectsJob import MultiplyObjectsJob
 from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
 from cura.Operations.SetParentOperation import SetParentOperation
 from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
@@ -41,9 +44,7 @@ from cura.Scene.BlockSlicingDecorator import BlockSlicingDecorator
 from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
 from cura.Scene.CuraSceneNode import CuraSceneNode
 
-from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
-from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
-from cura.MultiplyObjectsJob import MultiplyObjectsJob
+from cura.CuraSceneController import CuraSceneController
 
 from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
 from UM.Settings.ContainerRegistry import ContainerRegistry
@@ -77,7 +78,7 @@ from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisi
 from cura.Settings.QualitySettingsModel import QualitySettingsModel
 from cura.Settings.ContainerManager import ContainerManager
 
-from cura.ObjectManager import ObjectManager
+from cura.ObjectsModel import ObjectsModel
 from cura.BuildPlateModel import BuildPlateModel
 
 from PyQt5.QtCore import QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
@@ -211,6 +212,7 @@ class CuraApplication(QtApplication):
         self._build_plate_model = None
         self._setting_inheritance_manager = None
         self._simple_mode_settings_manager = None
+        self._cura_scene_controller = None
 
         self._additional_components = {} # Components to add to certain areas in the interface
 
@@ -398,6 +400,8 @@ class CuraApplication(QtApplication):
 
         self._plugin_registry.addSupportedPluginExtension("curaplugin", "Cura Plugin")
 
+        self.getCuraSceneController().setActiveBuildPlate(0)  # Initialize
+
     def _onEngineCreated(self):
         self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider())
 
@@ -699,8 +703,9 @@ class CuraApplication(QtApplication):
         qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager",
                                  self.getSimpleModeSettingsManager)
 
-        qmlRegisterSingletonType(ObjectManager, "Cura", 1, 2, "ObjectManager", self.getObjectManager)
+        qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 2, "ObjectsModel", self.getObjectsModel)
         qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 2, "BuildPlateModel", self.getBuildPlateModel)
+        qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController)
 
         qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
 
@@ -739,18 +744,22 @@ class CuraApplication(QtApplication):
             self._material_manager = MaterialManager.createMaterialManager()
         return self._material_manager
 
-    def getObjectManager(self, *args):
+    def getObjectsModel(self, *args):
         if self._object_manager is None:
-            self._object_manager = ObjectManager.createObjectManager()
+            self._object_manager = ObjectsModel.createObjectsModel()
         return self._object_manager
 
     def getBuildPlateModel(self, *args):
         if self._build_plate_model is None:
             self._build_plate_model = BuildPlateModel.createBuildPlateModel()
-            self._build_plate_model.setActiveBuildPlate(0)  # default value
 
         return self._build_plate_model
 
+    def getCuraSceneController(self, *args):
+        if self._cura_scene_controller is None:
+            self._cura_scene_controller = CuraSceneController.createCuraSceneController()
+        return self._cura_scene_controller
+
     def getSettingInheritanceManager(self, *args):
         if self._setting_inheritance_manager is None:
             self._setting_inheritance_manager = SettingInheritanceManager.createSettingInheritanceManager()
@@ -1115,7 +1124,7 @@ class CuraApplication(QtApplication):
                 nodes.append(node)
         job = ArrangeObjectsAllBuildPlatesJob(nodes)
         job.start()
-        self.getBuildPlateModel().setActiveBuildPlate(0)
+        self.getCuraSceneController().setActiveBuildPlate(0)  # Initialize
 
     # Single build plate
     @pyqtSlot()

+ 101 - 0
cura/CuraSceneController.py

@@ -0,0 +1,101 @@
+from UM.Logger import Logger
+
+from PyQt5.QtCore import Qt, pyqtSlot, QObject
+from PyQt5.QtWidgets import QApplication
+
+from cura.ObjectsModel import ObjectsModel
+from cura.BuildPlateModel import BuildPlateModel
+
+from UM.Application import Application
+from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from UM.Scene.SceneNode import SceneNode
+from UM.Scene.Selection import Selection
+
+
+class CuraSceneController(QObject):
+    def __init__(self, objects_model: ObjectsModel, build_plate_model: BuildPlateModel):
+        super().__init__()
+
+        self._objects_model = objects_model
+        self._build_plate_model = build_plate_model
+        self._active_build_plate = -1
+
+        self._last_selected_index = 0
+        self._max_build_plate = 1  # default
+
+        Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlate)  # it may be a bit inefficient when changing a lot simultaneously
+
+    def updateMaxBuildPlate(self, *args):
+        if args:
+            source = args[0]
+        else:
+            source = None
+        if not issubclass(type(source), SceneNode):
+            return
+        max_build_plate = self._calcMaxBuildPlate()
+        changed = False
+        if max_build_plate != self._max_build_plate:
+            self._max_build_plate = max_build_plate
+            changed = True
+        if changed:
+            self._build_plate_model.setMaxBuildPlate(self._max_build_plate)
+            build_plates = [{"name": "Build Plate %d" % (i + 1), "buildPlateNumber": i} for i in range(self._max_build_plate + 1)]
+            self._build_plate_model.setItems(build_plates)
+            # self.buildPlateItemsChanged.emit()  # TODO: necessary after setItems?
+
+    def _calcMaxBuildPlate(self):
+        max_build_plate = 0
+        for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
+            if node.callDecoration("isSliceable"):
+                build_plate_number = node.callDecoration("getBuildPlateNumber")
+                max_build_plate = max(build_plate_number, max_build_plate)
+        return max_build_plate
+
+    ##  Either select or deselect an item
+    @pyqtSlot(int)
+    def changeSelection(self, index):
+        modifiers = QApplication.keyboardModifiers()
+        ctrl_is_active = modifiers & Qt.ControlModifier
+        shift_is_active = modifiers & Qt.ShiftModifier
+
+        if ctrl_is_active:
+            item = self._objects_model.getItem(index)
+            node = item["node"]
+            if Selection.isSelected(node):
+                Selection.remove(node)
+            else:
+                Selection.add(node)
+        elif shift_is_active:
+            polarity = 1 if index + 1 > self._last_selected_index else -1
+            for i in range(self._last_selected_index, index + polarity, polarity):
+                item = self._objects_model.getItem(i)
+                node = item["node"]
+                Selection.add(node)
+        else:
+            # Single select
+            item = self._objects_model.getItem(index)
+            node = item["node"]
+            Selection.clear()
+            Selection.add(node)
+            build_plate_number = node.callDecoration("getBuildPlateNumber")
+            if build_plate_number is not None and build_plate_number != -1:
+                self._build_plate_model.setActiveBuildPlate(build_plate_number)
+
+        self._last_selected_index = index
+
+    @pyqtSlot(int)
+    def setActiveBuildPlate(self, nr):
+        if nr == self._active_build_plate:
+            return
+        Logger.log("d", "Select build plate: %s" % nr)
+        self._active_build_plate = nr
+        Selection.clear()
+
+        self._build_plate_model.setActiveBuildPlate(nr)
+        self._objects_model.setActiveBuildPlate(nr)
+
+    @staticmethod
+    def createCuraSceneController():
+        objects_model = Application.getInstance().getObjectsModel()
+        build_plate_model = Application.getInstance().getBuildPlateModel()
+        return CuraSceneController(objects_model = objects_model, build_plate_model = build_plate_model)

+ 0 - 87
cura/ObjectManager.py

@@ -1,87 +0,0 @@
-from UM.Logger import Logger
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot
-from UM.Application import Application
-from UM.Qt.ListModel import ListModel
-from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
-from UM.Scene.SceneNode import SceneNode
-from UM.Scene.Selection import Selection
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QApplication
-#from cura.Scene.CuraSceneNode import CuraSceneNode
-from UM.Preferences import Preferences
-
-
-##  Keep track of all objects in the project
-class ObjectManager(ListModel):
-    def __init__(self):
-        super().__init__()
-        self._last_selected_index = 0
-        self._build_plate_model = Application.getInstance().getBuildPlateModel()
-        Application.getInstance().getController().getScene().sceneChanged.connect(self._update)
-        Preferences.getInstance().preferenceChanged.connect(self._update)
-        self._build_plate_model.activeBuildPlateChanged.connect(self._update)
-
-    def _update(self, *args):
-        nodes = []
-        filter_current_build_plate = Preferences.getInstance().getValue("view/filter_current_build_plate")
-        active_build_plate_number = self._build_plate_model.activeBuildPlate
-        for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
-            if not issubclass(type(node), SceneNode) or (not node.getMeshData() and not node.callDecoration("getLayerData")):
-                continue
-            if not node.callDecoration("isSliceable"):
-                continue
-            node_build_plate_number = node.callDecoration("getBuildPlateNumber")
-            if filter_current_build_plate and node_build_plate_number != active_build_plate_number:
-                continue
-            nodes.append({
-                "name": node.getName(),
-                "isSelected": Selection.isSelected(node),
-                "isOutsideBuildArea": node.isOutsideBuildArea(),
-                "buildPlateNumber": node_build_plate_number,
-                "node": node
-            })
-        nodes = sorted(nodes, key=lambda n: n["name"])
-        self.setItems(nodes)
-
-        self.itemsChanged.emit()
-
-    ##  Either select or deselect an item
-    @pyqtSlot(int)
-    def changeSelection(self, index):
-        modifiers = QApplication.keyboardModifiers()
-        ctrl_is_active = modifiers & Qt.ControlModifier
-        shift_is_active = modifiers & Qt.ShiftModifier
-
-        if ctrl_is_active:
-            item = self.getItem(index)
-            node = item["node"]
-            if Selection.isSelected(node):
-                Selection.remove(node)
-            else:
-                Selection.add(node)
-        elif shift_is_active:
-            polarity = 1 if index + 1 > self._last_selected_index else -1
-            for i in range(self._last_selected_index, index + polarity, polarity):
-                item = self.getItem(i)
-                node = item["node"]
-                Selection.add(node)
-        else:
-            # Single select
-            item = self.getItem(index)
-            node = item["node"]
-            Selection.clear()
-            Selection.add(node)
-            build_plate_number = node.callDecoration("getBuildPlateNumber")
-            if build_plate_number is not None and build_plate_number != -1:
-                self._build_plate_model.setActiveBuildPlate(build_plate_number)
-
-        self._last_selected_index = index
-
-        # testing
-        for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
-            if node.callDecoration("getLayerData"):
-                Logger.log("d", "   ##### NODE: %s", node)
-
-    @staticmethod
-    def createObjectManager():
-        return ObjectManager()

+ 49 - 0
cura/ObjectsModel.py

@@ -0,0 +1,49 @@
+from UM.Application import Application
+from UM.Qt.ListModel import ListModel
+from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from UM.Scene.SceneNode import SceneNode
+from UM.Scene.Selection import Selection
+from UM.Preferences import Preferences
+
+
+##  Keep track of all objects in the project
+class ObjectsModel(ListModel):
+    def __init__(self):
+        super().__init__()
+
+        Application.getInstance().getController().getScene().sceneChanged.connect(self._update)
+        Preferences.getInstance().preferenceChanged.connect(self._update)
+
+        self._build_plate_number = -1
+
+    def setActiveBuildPlate(self, nr):
+        self._build_plate_number = nr
+        self._update()
+
+    def _update(self, *args):
+        nodes = []
+        filter_current_build_plate = Preferences.getInstance().getValue("view/filter_current_build_plate")
+        active_build_plate_number = self._build_plate_number
+        for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
+            if not issubclass(type(node), SceneNode) or (not node.getMeshData() and not node.callDecoration("getLayerData")):
+                continue
+            if not node.callDecoration("isSliceable"):
+                continue
+            node_build_plate_number = node.callDecoration("getBuildPlateNumber")
+            if filter_current_build_plate and node_build_plate_number != active_build_plate_number:
+                continue
+            nodes.append({
+                "name": node.getName(),
+                "isSelected": Selection.isSelected(node),
+                "isOutsideBuildArea": node.isOutsideBuildArea(),
+                "buildPlateNumber": node_build_plate_number,
+                "node": node
+            })
+        nodes = sorted(nodes, key=lambda n: n["name"])
+        self.setItems(nodes)
+
+        self.itemsChanged.emit()
+
+    @staticmethod
+    def createObjectsModel():
+        return ObjectsModel()

+ 8 - 8
resources/qml/ObjectsList.qml

@@ -85,7 +85,7 @@ Rectangle
                     anchors.fill: parent;
                     onClicked:
                     {
-                        Cura.BuildPlateModel.setActiveBuildPlate(index);
+                        Cura.SceneController.setActiveBuildPlate(index);
                     }
                 }
             }
@@ -131,7 +131,7 @@ Rectangle
         Rectangle
             {
                 height: childrenRect.height
-                color: Cura.ObjectManager.getItem(index).isSelected ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
+                color: Cura.ObjectsModel.getItem(index).isSelected ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
                 width: parent.width
                 Label
                 {
@@ -139,8 +139,8 @@ Rectangle
                     anchors.left: parent.left
                     anchors.leftMargin: UM.Theme.getSize("default_margin").width
                     width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30
-                    text: Cura.ObjectManager.getItem(index) ? Cura.ObjectManager.getItem(index).name : "";
-                    color: Cura.ObjectManager.getItem(index).isSelected ? palette.highlightedText : (Cura.ObjectManager.getItem(index).isOutsideBuildArea ? palette.mid : palette.text)
+                    text: Cura.ObjectsModel.getItem(index) ? Cura.ObjectsModel.getItem(index).name : "";
+                    color: Cura.ObjectsModel.getItem(index).isSelected ? palette.highlightedText : (Cura.ObjectsModel.getItem(index).isOutsideBuildArea ? palette.mid : palette.text)
                     elide: Text.ElideRight
                 }
 
@@ -151,8 +151,8 @@ Rectangle
                     anchors.left: nodeNameLabel.right
                     anchors.leftMargin: UM.Theme.getSize("default_margin").width
                     anchors.right: parent.right
-                    text: Cura.ObjectManager.getItem(index).buildPlateNumber != -1 ? Cura.ObjectManager.getItem(index).buildPlateNumber + 1 : "";
-                    color: Cura.ObjectManager.getItem(index).isSelected ? palette.highlightedText : palette.text
+                    text: Cura.ObjectsModel.getItem(index).buildPlateNumber != -1 ? Cura.ObjectsModel.getItem(index).buildPlateNumber + 1 : "";
+                    color: Cura.ObjectsModel.getItem(index).isSelected ? palette.highlightedText : palette.text
                     elide: Text.ElideRight
                 }
 
@@ -161,7 +161,7 @@ Rectangle
                     anchors.fill: parent;
                     onClicked:
                     {
-                        Cura.ObjectManager.changeSelection(index);
+                        Cura.SceneController.changeSelection(index);
                     }
                 }
             }
@@ -195,7 +195,7 @@ Rectangle
         ListView
         {
             id: listview
-            model: Cura.ObjectManager
+            model: Cura.ObjectsModel
             width: parent.width
             delegate: objectDelegate
         }