Browse Source

Merge pull request #5393 from Ultimaker/feature_model_list

Add an object list/selector
Lipu Fei 5 years ago
parent
commit
be4e05c13f

+ 3 - 2
cura/CuraApplication.py

@@ -523,6 +523,7 @@ class CuraApplication(QtApplication):
         preferences.addPreference("cura/choice_on_profile_override", "always_ask")
         preferences.addPreference("cura/choice_on_profile_override", "always_ask")
         preferences.addPreference("cura/choice_on_open_project", "always_ask")
         preferences.addPreference("cura/choice_on_open_project", "always_ask")
         preferences.addPreference("cura/use_multi_build_plate", False)
         preferences.addPreference("cura/use_multi_build_plate", False)
+        preferences.addPreference("cura/show_list_of_objects", False)
         preferences.addPreference("view/settings_list_height", 400)
         preferences.addPreference("view/settings_list_height", 400)
         preferences.addPreference("view/settings_visible", False)
         preferences.addPreference("view/settings_visible", False)
         preferences.addPreference("view/settings_xpos", 0)
         preferences.addPreference("view/settings_xpos", 0)
@@ -929,7 +930,7 @@ class CuraApplication(QtApplication):
 
 
     def getObjectsModel(self, *args):
     def getObjectsModel(self, *args):
         if self._object_manager is None:
         if self._object_manager is None:
-            self._object_manager = ObjectsModel.createObjectsModel()
+            self._object_manager = ObjectsModel(self)
         return self._object_manager
         return self._object_manager
 
 
     @pyqtSlot(result = QObject)
     @pyqtSlot(result = QObject)
@@ -1039,7 +1040,7 @@ class CuraApplication(QtApplication):
 
 
         qmlRegisterType(NetworkMJPGImage, "Cura", 1, 0, "NetworkMJPGImage")
         qmlRegisterType(NetworkMJPGImage, "Cura", 1, 0, "NetworkMJPGImage")
 
 
-        qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 0, "ObjectsModel", self.getObjectsModel)
+        qmlRegisterType(ObjectsModel, "Cura", 1, 0, "ObjectsModel")
         qmlRegisterType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel")
         qmlRegisterType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel")
         qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel")
         qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel")
         qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
         qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")

+ 19 - 11
cura/UI/ObjectsModel.py

@@ -4,7 +4,7 @@
 from collections import defaultdict
 from collections import defaultdict
 from typing import Dict
 from typing import Dict
 
 
-from PyQt5.QtCore import QTimer
+from PyQt5.QtCore import QTimer, Qt
 
 
 from UM.Application import Application
 from UM.Application import Application
 from UM.Qt.ListModel import ListModel
 from UM.Qt.ListModel import ListModel
@@ -19,8 +19,20 @@ catalog = i18nCatalog("cura")
 
 
 ##  Keep track of all objects in the project
 ##  Keep track of all objects in the project
 class ObjectsModel(ListModel):
 class ObjectsModel(ListModel):
-    def __init__(self) -> None:
-        super().__init__()
+    NameRole = Qt.UserRole + 1
+    SelectedRole = Qt.UserRole + 2
+    OutsideAreaRole = Qt.UserRole + 3
+    BuilplateNumberRole = Qt.UserRole + 4
+    NodeRole = Qt.UserRole + 5
+
+    def __init__(self, parent = None) -> None:
+        super().__init__(parent)
+
+        self.addRoleName(self.NameRole, "name")
+        self.addRoleName(self.SelectedRole, "selected")
+        self.addRoleName(self.OutsideAreaRole, "outside_build_area")
+        self.addRoleName(self.BuilplateNumberRole, "buildplate_number")
+        self.addRoleName(self.NodeRole, "node")
 
 
         Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSceneDelayed)
         Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSceneDelayed)
         Application.getInstance().getPreferences().preferenceChanged.connect(self._updateDelayed)
         Application.getInstance().getPreferences().preferenceChanged.connect(self._updateDelayed)
@@ -78,7 +90,7 @@ class ObjectsModel(ListModel):
             else:
             else:
                 is_outside_build_area = False
                 is_outside_build_area = False
                 
                 
-            #check if we already have an instance of the object based on name
+            # Check if we already have an instance of the object based on name
             name_count_dict[name] += 1
             name_count_dict[name] += 1
             name_count = name_count_dict[name]
             name_count = name_count_dict[name]
 
 
@@ -88,9 +100,9 @@ class ObjectsModel(ListModel):
 
 
             nodes.append({
             nodes.append({
                 "name": name,
                 "name": name,
-                "isSelected": Selection.isSelected(node),
-                "isOutsideBuildArea": is_outside_build_area,
-                "buildPlateNumber": node_build_plate_number,
+                "selected": Selection.isSelected(node),
+                "outside_build_area": is_outside_build_area,
+                "buildplate_number": node_build_plate_number,
                 "node": node
                 "node": node
             })
             })
        
        
@@ -98,7 +110,3 @@ class ObjectsModel(ListModel):
         self.setItems(nodes)
         self.setItems(nodes)
 
 
         self.itemsChanged.emit()
         self.itemsChanged.emit()
-
-    @staticmethod
-    def createObjectsModel():
-        return ObjectsModel()

+ 12 - 8
resources/qml/Cura.qml

@@ -260,15 +260,17 @@ UM.MainWindow
                 visible: CuraApplication.platformActivity && !PrintInformation.preSliced
                 visible: CuraApplication.platformActivity && !PrintInformation.preSliced
             }
             }
 
 
-            ObjectsList
+            ObjectSelector
             {
             {
-                id: objectsList
-                visible: UM.Preferences.getValue("cura/use_multi_build_plate")
+                id: objectSelector
+                visible: CuraApplication.platformActivity
                 anchors
                 anchors
                 {
                 {
-                    bottom: viewOrientationControls.top
+                    bottom: jobSpecs.top
                     left: toolbar.right
                     left: toolbar.right
-                    margins: UM.Theme.getSize("default_margin").width
+                    leftMargin: UM.Theme.getSize("default_margin").width
+                    rightMargin: UM.Theme.getSize("default_margin").width
+                    bottomMargin: UM.Theme.getSize("narrow_margin").height
                 }
                 }
             }
             }
 
 
@@ -278,10 +280,12 @@ UM.MainWindow
                 visible: CuraApplication.platformActivity
                 visible: CuraApplication.platformActivity
                 anchors
                 anchors
                 {
                 {
-                    left: parent.left
+                    left: toolbar.right
                     bottom: viewOrientationControls.top
                     bottom: viewOrientationControls.top
-                    margins: UM.Theme.getSize("default_margin").width
+                    leftMargin: UM.Theme.getSize("default_margin").width
+                    rightMargin: UM.Theme.getSize("default_margin").width
                     bottomMargin: UM.Theme.getSize("thin_margin").width
                     bottomMargin: UM.Theme.getSize("thin_margin").width
+                    topMargin: UM.Theme.getSize("thin_margin").width
                 }
                 }
             }
             }
 
 
@@ -291,7 +295,7 @@ UM.MainWindow
 
 
                 anchors
                 anchors
                 {
                 {
-                    left: parent.left
+                    left: toolbar.right
                     bottom: parent.bottom
                     bottom: parent.bottom
                     margins: UM.Theme.getSize("default_margin").width
                     margins: UM.Theme.getSize("default_margin").width
                 }
                 }

+ 1 - 1
resources/qml/JobSpecs.qml

@@ -65,7 +65,7 @@ Item
                         height: UM.Theme.getSize("save_button_specs_icons").height
                         height: UM.Theme.getSize("save_button_specs_icons").height
                         sourceSize.width: width
                         sourceSize.width: width
                         sourceSize.height: width
                         sourceSize.height: width
-                        color: control.hovered ? UM.Theme.getColor("text_scene_hover") : UM.Theme.getColor("text_scene")
+                        color: control.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text")
                         source: UM.Theme.getIcon("pencil")
                         source: UM.Theme.getIcon("pencil")
                     }
                     }
                 }
                 }

+ 55 - 0
resources/qml/ObjectItemButton.qml

@@ -0,0 +1,55 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+Button
+{
+    id: objectItemButton
+
+    width: parent.width
+    height: UM.Theme.getSize("action_button").height
+    leftPadding: UM.Theme.getSize("thin_margin").width
+    rightPadding: UM.Theme.getSize("thin_margin").width
+    checkable: true
+    hoverEnabled: true
+
+    contentItem: Item
+    {
+        width: objectItemButton.width - objectItemButton.leftPadding
+        height: UM.Theme.getSize("action_button").height
+
+        Label
+        {
+            id: buttonText
+            anchors
+            {
+                left: parent.left
+                right: parent.right
+                verticalCenter: parent.verticalCenter
+            }
+            text: objectItemButton.text
+            font: UM.Theme.getFont("default")
+            color: UM.Theme.getColor("text_scene")
+            visible: text != ""
+            renderType: Text.NativeRendering
+            verticalAlignment: Text.AlignVCenter
+            elide: Text.ElideRight
+        }
+    }
+
+    background: Rectangle
+    {
+        id: backgroundRect
+        color: objectItemButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
+        radius: UM.Theme.getSize("action_button_radius").width
+        border.width: UM.Theme.getSize("default_lining").width
+        border.color: objectItemButton.checked ? UM.Theme.getColor("primary") : "transparent"
+    }
+
+    onClicked: Cura.SceneController.changeSelection(index)
+}

+ 120 - 0
resources/qml/ObjectSelector.qml

@@ -0,0 +1,120 @@
+// Copyright (c) 2019 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Item
+{
+    id: objectSelector
+    width: UM.Theme.getSize("objects_menu_size").width
+    property bool opened: UM.Preferences.getValue("cura/show_list_of_objects")
+
+    Button
+    {
+        id: openCloseButton
+        width: parent.width
+        height: contentItem.height + bottomPadding
+        hoverEnabled: true
+        padding: 0
+        bottomPadding: UM.Theme.getSize("narrow_margin").height / 2 | 0
+
+        anchors
+        {
+            bottom: contents.top
+            horizontalCenter: parent.horizontalCenter
+        }
+
+        contentItem: Item
+        {
+            width: parent.width
+            height: label.height
+
+            UM.RecolorImage
+            {
+                id: openCloseIcon
+                width: UM.Theme.getSize("standard_arrow").width
+                height: UM.Theme.getSize("standard_arrow").height
+                sourceSize.width: width
+                anchors.left: parent.left
+                color: openCloseButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text")
+                source: objectSelector.opened ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_top")
+            }
+
+            Label
+            {
+                id: label
+                anchors.left: openCloseIcon.right
+                anchors.leftMargin: UM.Theme.getSize("default_margin").width
+                text: catalog.i18nc("@label", "Object list")
+                font: UM.Theme.getFont("default")
+                color: openCloseButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text")
+                renderType: Text.NativeRendering
+                elide: Text.ElideRight
+            }
+        }
+
+        background: Item {}
+
+        onClicked:
+        {
+            UM.Preferences.setValue("cura/show_list_of_objects", !objectSelector.opened)
+            objectSelector.opened = UM.Preferences.getValue("cura/show_list_of_objects")
+        }
+    }
+
+    Rectangle
+    {
+        id: contents
+        width: parent.width
+        visible: objectSelector.opened
+        height: visible ? scroll.height : 0
+        color: UM.Theme.getColor("main_background")
+        border.width: UM.Theme.getSize("default_lining").width
+        border.color: UM.Theme.getColor("lining")
+
+        Behavior on height { NumberAnimation { duration: 100 } }
+
+        anchors.bottom: parent.bottom
+
+        ScrollView
+        {
+            id: scroll
+            width: parent.width
+            clip: true
+            padding: UM.Theme.getSize("default_lining").width
+
+            contentItem: ListView
+            {
+                id: listView
+
+                // Can't use parent.width since the parent is the flickable component and not the ScrollView
+                width: scroll.width - scroll.leftPadding - scroll.rightPadding
+                property real maximumHeight: UM.Theme.getSize("objects_menu_size").height
+
+                // We use an extra property here, since we only want to to be informed about the content size changes.
+                onContentHeightChanged:
+                {
+                    scroll.height = Math.min(contentHeight, maximumHeight) + scroll.topPadding + scroll.bottomPadding
+                }
+
+                Component.onCompleted:
+                {
+                    scroll.height = Math.min(contentHeight, maximumHeight) + scroll.topPadding + scroll.bottomPadding
+                }
+                model: Cura.ObjectsModel {}
+
+                delegate: ObjectItemButton
+                {
+                    text: model.name
+                    width: listView.width
+
+                    checked: model.selected
+                }
+            }
+        }
+    }
+}

+ 0 - 262
resources/qml/ObjectsList.qml

@@ -1,262 +0,0 @@
-// Copyright (c) 2018 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Controls.Styles 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Dialogs 1.1
-
-import UM 1.3 as UM
-import Cura 1.0 as Cura
-
-import "Menus"
-
-Rectangle
-{
-    id: base;
-
-    color: UM.Theme.getColor("tool_panel_background")
-
-    width: UM.Theme.getSize("objects_menu_size").width
-    height: {
-        if (collapsed) {
-            return UM.Theme.getSize("objects_menu_size_collapsed").height;
-        } else {
-            return UM.Theme.getSize("objects_menu_size").height;
-        }
-    }
-    Behavior on height { NumberAnimation { duration: 100 } }
-
-    border.width: UM.Theme.getSize("default_lining").width
-    border.color: UM.Theme.getColor("lining")
-
-    property bool collapsed: true
-
-    property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
-
-    SystemPalette { id: palette }
-
-    Button {
-        id: collapseButton
-        anchors.top: parent.top
-        anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2)
-        anchors.right: parent.right
-        anchors.rightMargin: UM.Theme.getSize("default_margin").width
-
-        width: UM.Theme.getSize("standard_arrow").width
-        height: UM.Theme.getSize("standard_arrow").height
-
-        onClicked: collapsed = !collapsed
-
-        style: ButtonStyle
-        {
-            background: UM.RecolorImage
-            {
-                width: control.width
-                height: control.height
-                sourceSize.height: width
-                color:  UM.Theme.getColor("setting_control_text")
-                source: collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
-            }
-            label: Label{ }
-        }
-    }
-
-    Component {
-        id: buildPlateDelegate
-        Rectangle
-            {
-                height: childrenRect.height
-                color: multiBuildPlateModel.getItem(index).buildPlateNumber == multiBuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
-                width: parent.width
-                Label
-                {
-                    id: buildPlateNameLabel
-                    anchors.left: parent.left
-                    anchors.leftMargin: UM.Theme.getSize("default_margin").width
-                    width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30
-                    text: multiBuildPlateModel.getItem(index) ? multiBuildPlateModel.getItem(index).name : "";
-                    color: multiBuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text
-                    elide: Text.ElideRight
-                }
-
-                MouseArea
-                {
-                    anchors.fill: parent;
-                    onClicked:
-                    {
-                        Cura.SceneController.setActiveBuildPlate(index);
-                    }
-                }
-            }
-    }
-
-    ScrollView
-    {
-        id: buildPlateSelection
-        frameVisible: true
-        height: UM.Theme.getSize("build_plate_selection_size").height
-        width: parent.width - 2 * UM.Theme.getSize("default_margin").height
-        style: UM.Theme.styles.scrollview
-
-        anchors
-        {
-            top: collapseButton.bottom;
-            topMargin: UM.Theme.getSize("default_margin").height;
-            left: parent.left;
-            leftMargin: UM.Theme.getSize("default_margin").height;
-            bottomMargin: UM.Theme.getSize("default_margin").height;
-        }
-
-        Rectangle
-        {
-            parent: viewport
-            anchors.fill: parent
-            color: palette.light
-        }
-
-        ListView
-        {
-            id: buildPlateListView
-            model: multiBuildPlateModel
-            width: parent.width
-            delegate: buildPlateDelegate
-        }
-    }
-
-    Component {
-        id: objectDelegate
-        Rectangle
-            {
-                height: childrenRect.height
-                color: Cura.ObjectsModel.getItem(index).isSelected ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
-                width: parent.width
-                Label
-                {
-                    id: nodeNameLabel
-                    anchors.left: parent.left
-                    anchors.leftMargin: UM.Theme.getSize("default_margin").width
-                    width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30
-                    text: (index >= 0) && 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
-                }
-
-                Label
-                {
-                    id: buildPlateNumberLabel
-                    width: 20
-                    anchors.left: nodeNameLabel.right
-                    anchors.leftMargin: UM.Theme.getSize("default_margin").width
-                    anchors.right: parent.right
-                    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
-                }
-
-                MouseArea
-                {
-                    anchors.fill: parent;
-                    onClicked:
-                    {
-                        Cura.SceneController.changeSelection(index);
-                    }
-                }
-            }
-    }
-
-    // list all the scene nodes
-    ScrollView
-    {
-        id: objectsList
-        frameVisible: true
-        visible: !collapsed
-        width: parent.width - 2 * UM.Theme.getSize("default_margin").height
-
-        anchors
-        {
-            top: buildPlateSelection.bottom;
-            topMargin: UM.Theme.getSize("default_margin").height;
-            left: parent.left;
-            leftMargin: UM.Theme.getSize("default_margin").height;
-            bottom: filterBuildPlateCheckbox.top;
-            bottomMargin: UM.Theme.getSize("default_margin").height;
-        }
-
-        Rectangle
-        {
-            parent: viewport
-            anchors.fill: parent
-            color: palette.light
-        }
-
-        ListView
-        {
-            id: listview
-            model: Cura.ObjectsModel
-            width: parent.width
-            delegate: objectDelegate
-        }
-    }
-
-    CheckBox
-    {
-        id: filterBuildPlateCheckbox
-        visible: !collapsed
-        checked: UM.Preferences.getValue("view/filter_current_build_plate")
-        onClicked: UM.Preferences.setValue("view/filter_current_build_plate", checked)
-
-        text: catalog.i18nc("@option:check","See only current build plate");
-        style: UM.Theme.styles.checkbox;
-
-        anchors
-        {
-            left: parent.left;
-            topMargin: UM.Theme.getSize("default_margin").height;
-            bottomMargin: UM.Theme.getSize("default_margin").height;
-            leftMargin: UM.Theme.getSize("default_margin").height;
-            bottom: arrangeAllBuildPlatesButton.top;
-        }
-    }
-
-    Button
-    {
-        id: arrangeAllBuildPlatesButton;
-        text: catalog.i18nc("@action:button","Arrange to all build plates");
-        style: UM.Theme.styles.print_setup_action_button
-        height: UM.Theme.getSize("objects_menu_button").height;
-        tooltip: '';
-        anchors
-        {
-            topMargin: UM.Theme.getSize("default_margin").height;
-            left: parent.left;
-            leftMargin: UM.Theme.getSize("default_margin").height;
-            right: parent.right;
-            rightMargin: UM.Theme.getSize("default_margin").height;
-            bottom: arrangeBuildPlateButton.top;
-            bottomMargin: UM.Theme.getSize("default_margin").height;
-        }
-        action: Cura.Actions.arrangeAllBuildPlates;
-    }
-
-    Button
-    {
-        id: arrangeBuildPlateButton;
-        text: catalog.i18nc("@action:button","Arrange current build plate");
-        style: UM.Theme.styles.print_setup_action_button
-        height: UM.Theme.getSize("objects_menu_button").height;
-        tooltip: '';
-        anchors
-        {
-            topMargin: UM.Theme.getSize("default_margin").height;
-            left: parent.left;
-            leftMargin: UM.Theme.getSize("default_margin").height;
-            right: parent.right;
-            rightMargin: UM.Theme.getSize("default_margin").height;
-            bottom: parent.bottom;
-            bottomMargin: UM.Theme.getSize("default_margin").height;
-        }
-        action: Cura.Actions.arrangeAll;
-    }
-}

+ 0 - 1
resources/qml/PrinterSelector/MachineSelector.qml

@@ -135,7 +135,6 @@ Cura.ExpandablePopup
                     scroll.height = Math.min(contentHeight, maximumHeight)
                     scroll.height = Math.min(contentHeight, maximumHeight)
                     popup.height = scroll.height + buttonRow.height
                     popup.height = scroll.height + buttonRow.height
                 }
                 }
-
             }
             }
         }
         }
 
 

+ 1 - 1
resources/themes/cura-light/theme.json

@@ -581,7 +581,7 @@
 
 
         "jobspecs_line": [2.0, 2.0],
         "jobspecs_line": [2.0, 2.0],
 
 
-        "objects_menu_size": [20, 40],
+        "objects_menu_size": [15, 15],
         "objects_menu_size_collapsed": [20, 17],
         "objects_menu_size_collapsed": [20, 17],
         "build_plate_selection_size": [15, 5],
         "build_plate_selection_size": [15, 5],
         "objects_menu_button": [0.3, 2.7],
         "objects_menu_button": [0.3, 2.7],