Browse Source

Merge branch 'CURA-5829-Add-preview-stage' into ui_rework_4_0

Remco Burema 6 years ago
parent
commit
215fc4e8ec

+ 1 - 0
cura/CuraApplication.py

@@ -438,6 +438,7 @@ class CuraApplication(QtApplication):
             "XmlMaterialProfile", #Cura crashes without this one.
             "Toolbox", #This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
             "PrepareStage", #Cura is useless without this one since you can't load models.
+            "PreviewStage", #This shows the list of the plugin views that are installed in Cura.
             "MonitorStage", #Major part of Cura's functionality.
             "LocalFileOutputDevice", #Major part of Cura's functionality.
             "LocalContainerProvider", #Cura is useless without any profiles or setting definitions.

+ 24 - 0
cura/CuraView.py

@@ -0,0 +1,24 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtProperty, QUrl
+
+from UM.View.View import View
+
+
+# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure
+# to indicate this.
+#   MainComponent works in the same way the MainComponent of a stage.
+#   the stageMenuComponent returns an item that should be used somehwere in the stage menu. It's up to the active stage
+#   to actually do something with this.
+class CuraView(View):
+    def __init__(self, parent = None) -> None:
+        super().__init__(parent)
+
+    @pyqtProperty(QUrl, constant = True)
+    def mainComponent(self) -> QUrl:
+        return self.getDisplayComponent("main")
+
+    @pyqtProperty(QUrl, constant = True)
+    def stageMenuComponent(self) -> QUrl:
+        return self.getDisplayComponent("menu")

+ 3 - 1
plugins/MonitorStage/__init__.py

@@ -7,14 +7,16 @@ from . import MonitorStage
 from UM.i18n import i18nCatalog
 i18n_catalog = i18nCatalog("cura")
 
+
 def getMetaData():
     return {
         "stage": {
             "name": i18n_catalog.i18nc("@item:inmenu", "Monitor"),
-            "weight": 1
+            "weight": 2
         }
     }
 
+
 def register(app):
     return {
         "stage": MonitorStage.MonitorStage()

+ 18 - 0
plugins/PreviewStage/PreviewMain.qml

@@ -0,0 +1,18 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.4
+import QtQuick.Controls 1.2
+import QtQuick.Layouts 1.1
+import QtQuick.Controls.Styles 1.1
+
+import UM 1.0 as UM
+import Cura 1.0 as Cura
+
+
+Loader
+{
+    id: previewMain
+
+    source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : ""
+}

+ 94 - 0
plugins/PreviewStage/PreviewMenu.qml

@@ -0,0 +1,94 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+
+import QtQuick.Controls 1.4
+
+import UM 1.3 as UM
+import Cura 1.1 as Cura
+
+Item
+{
+    id: previewMenu
+    // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it.
+    signal showTooltip(Item item, point location, string text)
+    signal hideTooltip()
+
+    UM.I18nCatalog
+    {
+        id: catalog
+        name: "cura"
+    }
+
+    Row
+    {
+        anchors.horizontalCenter: parent.horizontalCenter
+        spacing: UM.Theme.getSize("default_margin").width
+
+        ComboBox
+        {
+            // This item contains the views selector, a combobox that is dynamically created from
+            // the list of available Views (packages that create different visualizations of the
+            // scene).
+            id: viewModeButton
+
+            style: UM.Theme.styles.combobox
+
+            model: UM.ViewModel { }
+            textRole: "name"
+
+            // update the model's active index
+            function updateItemActiveFlags()
+            {
+                currentIndex = getActiveIndex()
+                for (var i = 0; i < model.rowCount(); i++)
+                {
+                    model.getItem(i).active = (i == currentIndex)
+                }
+            }
+
+            // get the index of the active model item on start
+            function getActiveIndex()
+            {
+                for (var i = 0; i < model.rowCount(); i++)
+                {
+                    if (model.getItem(i).active)
+                    {
+                        return i;
+                    }
+                }
+                return 0
+            }
+
+            onCurrentIndexChanged:
+            {
+                if (model.getItem(currentIndex).id != undefined)
+                {
+                    UM.Controller.setActiveView(model.getItem(currentIndex).id)
+                }
+            }
+            currentIndex: getActiveIndex()
+        }
+
+        Loader
+        {
+            // TODO: Make this panel collapsable and ensure it has a standardised background.
+            id: viewPanel
+
+            property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2))
+
+            height: childrenRect.height
+            width: childrenRect.width
+
+            source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : ""
+        }
+
+        Cura.PrintSetupSelector
+        {
+            width: UM.Theme.getSize("print_setup_widget").width
+            onShowTooltip: previewMenu.showTooltip(item, location, text)
+            onHideTooltip: previewMenu.hideTooltip()
+        }
+    }
+}

+ 51 - 0
plugins/PreviewStage/PreviewStage.py

@@ -0,0 +1,51 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import os.path
+
+from UM.Qt.QtApplication import QtApplication
+from cura.Stages.CuraStage import CuraStage
+
+from typing import TYPE_CHECKING, Optional
+
+if TYPE_CHECKING:
+    from UM.View.View import View
+
+
+##  Displays a preview of what you're about to print.
+#
+#   The Python component of this stage just loads PreviewMain.qml for display
+#   when the stage is selected, and makes sure that it reverts to the previous
+#   view when the previous stage is activated.
+class PreviewStage(CuraStage):
+    def __init__(self, application: QtApplication, parent = None) -> None:
+        super().__init__(parent)
+        self._application = application
+        self._application.engineCreatedSignal.connect(self._engineCreated)
+        self._previously_active_view = None  # type: Optional[View]
+
+    ##  When selecting the stage, remember which was the previous view so that
+    #   we can revert to that view when we go out of the stage later.
+    def onStageSelected(self) -> None:
+        self._previously_active_view = self._application.getController().getActiveView()
+
+    ##  Called when going to a different stage (away from the Preview Stage).
+    #
+    #   When going to a different stage, the view should be reverted to what it
+    #   was before. Normally, that just reverts it to solid view.
+    def onStageDeselected(self) -> None:
+        if self._previously_active_view is not None:
+            self._application.getController().setActiveView(self._previously_active_view.getPluginId())
+        self._previously_active_view = None
+
+    ##  Delayed load of the QML files.
+    #
+    #   We need to make sure that the QML engine is running before we can load
+    #   these.
+    def _engineCreated(self) -> None:
+        plugin_path = self._application.getPluginRegistry().getPluginPath(self.getPluginId())
+        if plugin_path is not None:
+            menu_component_path = os.path.join(plugin_path, "PreviewMenu.qml")
+            main_component_path = os.path.join(plugin_path, "PreviewMain.qml")
+            self.addDisplayComponent("menu", menu_component_path)
+            self.addDisplayComponent("main", main_component_path)

+ 22 - 0
plugins/PreviewStage/__init__.py

@@ -0,0 +1,22 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from . import PreviewStage
+
+from UM.i18n import i18nCatalog
+i18n_catalog = i18nCatalog("cura")
+
+
+def getMetaData():
+    return {
+        "stage": {
+            "name": i18n_catalog.i18nc("@item:inmenu", "Preview"),
+            "weight": 1
+        }
+    }
+
+
+def register(app):
+    return {
+        "stage": PreviewStage.PreviewStage(app)
+    }

+ 8 - 0
plugins/PreviewStage/plugin.json

@@ -0,0 +1,8 @@
+{
+    "name": "Preview Stage",
+    "author": "Ultimaker B.V.",
+    "version": "1.0.0",
+    "description": "Provides a preview stage in Cura.",
+    "api": 5,
+    "i18n-catalog": "cura"
+}

+ 18 - 18
plugins/SimulationView/LayerSlider.qml

@@ -13,23 +13,23 @@ Item
 {
     id: sliderRoot
 
-    // handle properties
-    property real handleSize: 10
+    // Handle properties
+    property real handleSize: UM.Theme.getSize("slider_handle").width
     property real handleRadius: handleSize / 2
     property real minimumRangeHandleSize: handleSize / 2
-    property color upperHandleColor: "black"
-    property color lowerHandleColor: "black"
-    property color rangeHandleColor: "black"
-    property color handleActiveColor: "white"
-    property real handleLabelWidth: width
+    property color upperHandleColor: UM.Theme.getColor("slider_handle")
+    property color lowerHandleColor: UM.Theme.getColor("slider_handle")
+    property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill")
+    property color handleActiveColor: UM.Theme.getColor("slider_handle_active")
+    property real handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width
     property var activeHandle: upperHandle
 
-    // track properties
-    property real trackThickness: 4 // width of the slider track
+    // Track properties
+    property real trackThickness: UM.Theme.getSize("slider_groove").width // width of the slider track
     property real trackRadius: trackThickness / 2
-    property color trackColor: "white"
-    property real trackBorderWidth: 1 // width of the slider track border
-    property color trackBorderColor: "black"
+    property color trackColor: UM.Theme.getColor("slider_groove")
+    property real trackBorderWidth: 1
+    property color trackBorderColor: UM.Theme.getColor("slider_groove_border")
 
     // value properties
     property real maximumValue: 100
@@ -80,7 +80,7 @@ Item
         return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
     }
 
-    // slider track
+    // Slider track
     Rectangle
     {
         id: track
@@ -106,7 +106,7 @@ Item
         anchors.horizontalCenter: sliderRoot.horizontalCenter
         visible: sliderRoot.layersVisible
 
-        // set the new value when dragging
+        // Set the new value when dragging
         function onHandleDragged()
         {
             sliderRoot.manuallyChanged = true
@@ -169,7 +169,7 @@ Item
             height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
             x: parent.x + parent.width + UM.Theme.getSize("default_margin").width
             anchors.verticalCenter: parent.verticalCenter
-            target: Qt.point(sliderRoot.width, y + height / 2)
+            target: Qt.point(sliderRoot.width + width, y + height / 2)
             visible: sliderRoot.activeHandle == parent
 
             // custom properties
@@ -275,7 +275,7 @@ Item
             id: upperHandleLabel
 
             height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
-            x: parent.x + parent.width + UM.Theme.getSize("default_margin").width
+            x: parent.x - parent.width - width
             anchors.verticalCenter: parent.verticalCenter
             target: Qt.point(sliderRoot.width, y + height / 2)
             visible: sliderRoot.activeHandle == parent
@@ -385,9 +385,9 @@ Item
             id: lowerHandleLabel
 
             height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
-            x: parent.x + parent.width + UM.Theme.getSize("default_margin").width
+            x: parent.x - parent.width - width
             anchors.verticalCenter: parent.verticalCenter
-            target: Qt.point(sliderRoot.width, y + height / 2)
+            target: Qt.point(sliderRoot.width + width, y + height / 2)
             visible: sliderRoot.activeHandle == parent
 
             // custom properties

+ 7 - 7
plugins/SimulationView/PathSlider.qml

@@ -14,19 +14,19 @@ Item
     id: sliderRoot
 
     // handle properties
-    property real handleSize: 10
+    property real handleSize: UM.Theme.getSize("slider_handle").width
     property real handleRadius: handleSize / 2
-    property color handleColor: "black"
-    property color handleActiveColor: "white"
-    property color rangeColor: "black"
+    property color handleColor: UM.Theme.getColor("slider_handle")
+    property color handleActiveColor: UM.Theme.getColor("slider_handle_active")
+    property color rangeColor: UM.Theme.getColor("slider_groove_fill")
     property real handleLabelWidth: width
 
     // track properties
-    property real trackThickness: 4 // width of the slider track
+    property real trackThickness: UM.Theme.getSize("slider_groove").width
     property real trackRadius: trackThickness / 2
-    property color trackColor: "white"
+    property color trackColor: UM.Theme.getColor("slider_groove")
     property real trackBorderWidth: 1 // width of the slider track border
-    property color trackBorderColor: "black"
+    property color trackBorderColor: UM.Theme.getColor("slider_groove_border")
 
     // value properties
     property real maximumValue: 100

Some files were not shown because too many files changed in this diff