diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml new file mode 100644 index 0000000000..df7e09225f --- /dev/null +++ b/plugins/PreviewStage/PreviewMain.qml @@ -0,0 +1,19 @@ +// 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 : "" + onSourceChanged: print("THE SOURCE IS", source) +} \ No newline at end of file diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index e41d4a592f..1aed95162a 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -30,4 +30,6 @@ class PreviewStage(CuraStage): 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) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 0ef08b22d7..f1bff5f3f7 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -117,7 +117,12 @@ class SimulationView(CuraView): def _onEngineCreated(self) -> None: menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), - "SimulationView.qml") + "SimulationViewMenuComponent.qml") + + main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), + "SimulationViewMainComponent.qml") + + self.addDisplayComponent("main", main_component_path) self.addDisplayComponent("menu", menu_component_path) def _evaluateCompatibilityMode(self) -> bool: diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml new file mode 100644 index 0000000000..a4ec411124 --- /dev/null +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -0,0 +1,212 @@ +// 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 + +Item +{ + property bool is_simulation_playing: false + visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity + + PathSlider + { + id: pathSlider + height: UM.Theme.getSize("slider_handle").width + width: 250 + + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("default_margin").height + + anchors.horizontalCenter: parent.horizontalCenter + + visible: !UM.SimulationView.compatibilityMode + + // Custom properties + handleValue: UM.SimulationView.currentPath + maximumValue: UM.SimulationView.numPaths + handleSize: UM.Theme.getSize("slider_handle").width + trackThickness: UM.Theme.getSize("slider_groove").width + trackColor: UM.Theme.getColor("slider_groove") + trackBorderColor: UM.Theme.getColor("slider_groove_border") + handleColor: UM.Theme.getColor("slider_handle") + handleActiveColor: UM.Theme.getColor("slider_handle_active") + rangeColor: UM.Theme.getColor("slider_groove_fill") + + // Update values when layer data changes. + Connections + { + target: UM.SimulationView + onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) + onCurrentPathChanged: + { + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (pathSlider.manuallyChanged) + { + playButton.pauseSimulation() + } + pathSlider.setHandleValue(UM.SimulationView.currentPath) + } + } + + // Ensure that the slider handlers show the correct value after switching views. + Component.onCompleted: + { + pathSlider.setHandleValue(UM.SimulationView.currentPath) + } + + } + + Button + { + id: playButton + iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg" + style: UM.Theme.styles.small_tool_button + visible: !UM.SimulationView.compatibilityMode + anchors + { + right: pathSlider.left + verticalCenter: pathSlider.verticalCenter + } + + onClicked: + { + if(is_simulation_playing) + { + pauseSimulation() + } else + { + resumeSimulation() + } + } + + function pauseSimulation() + { + UM.SimulationView.setSimulationRunning(false) + simulationTimer.stop() + is_simulation_playing = false + layerSlider.manuallyChanged = true + pathSlider.manuallyChanged = true + } + + function resumeSimulation() + { + UM.SimulationView.setSimulationRunning(true) + simulationTimer.start() + layerSlider.manuallyChanged = false + pathSlider.manuallyChanged = false + } + } + + Timer + { + id: simulationTimer + interval: 100 + running: false + repeat: true + onTriggered: + { + var currentPath = UM.SimulationView.currentPath + var numPaths = UM.SimulationView.numPaths + var currentLayer = UM.SimulationView.currentLayer + var numLayers = UM.SimulationView.numLayers + + // When the user plays the simulation, if the path slider is at the end of this layer, we start + // the simulation at the beginning of the current layer. + if (!is_simulation_playing) + { + if (currentPath >= numPaths) + { + UM.SimulationView.setCurrentPath(0) + } + else + { + UM.SimulationView.setCurrentPath(currentPath + 1) + } + } + // If the simulation is already playing and we reach the end of a layer, then it automatically + // starts at the beginning of the next layer. + else + { + if (currentPath >= numPaths) + { + // At the end of the model, the simulation stops + if (currentLayer >= numLayers) + { + playButton.pauseSimulation() + } + else + { + UM.SimulationView.setCurrentLayer(currentLayer+1) + UM.SimulationView.setCurrentPath(0) + } + } + else + { + UM.SimulationView.setCurrentPath(currentPath+1) + } + } + // The status must be set here instead of in the resumeSimulation function otherwise it won't work + // correctly, because part of the logic is in this trigger function. + is_simulation_playing = true + } + } + + LayerSlider + { + id: layerSlider + + width: UM.Theme.getSize("slider_handle").width + height: UM.Theme.getSize("layerview_menu_size").height + + anchors + { + right: parent.right + verticalCenter: parent.verticalCenter + rightMargin: UM.Theme.getSize("default_margin").width + } + + // Custom properties + upperValue: UM.SimulationView.currentLayer + lowerValue: UM.SimulationView.minimumLayer + maximumValue: UM.SimulationView.numLayers + handleSize: UM.Theme.getSize("slider_handle").width + trackThickness: UM.Theme.getSize("slider_groove").width + trackColor: UM.Theme.getColor("slider_groove") + trackBorderColor: UM.Theme.getColor("slider_groove_border") + upperHandleColor: UM.Theme.getColor("slider_handle") + lowerHandleColor: UM.Theme.getColor("slider_handle") + rangeHandleColor: UM.Theme.getColor("slider_groove_fill") + handleActiveColor: UM.Theme.getColor("slider_handle_active") + handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width + + // Update values when layer data changes + Connections + { + target: UM.SimulationView + onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) + onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) + onCurrentLayerChanged: + { + // Only pause the simulation when the layer was changed manually, not when the simulation is running + if (layerSlider.manuallyChanged) + { + playButton.pauseSimulation() + } + layerSlider.setUpperValue(UM.SimulationView.currentLayer) + } + } + + // Make sure the slider handlers show the correct value after switching views + Component.onCompleted: + { + layerSlider.setLowerValue(UM.SimulationView.minimumLayer) + layerSlider.setUpperValue(UM.SimulationView.currentLayer) + } + } +} \ No newline at end of file diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml similarity index 75% rename from plugins/SimulationView/SimulationView.qml rename to plugins/SimulationView/SimulationViewMenuComponent.qml index 7a83a07ac1..91ef7a2794 100644 --- a/plugins/SimulationView/SimulationView.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -583,230 +583,6 @@ Item } } - Item - { - id: slidersBox - - width: parent.width - height: parent.height - visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity - - anchors - { - top: parent.top - leftMargin: UM.Theme.getSize("slider_layerview_margin").height - left: parent.right - } - - PathSlider - { - id: pathSlider - - height: UM.Theme.getSize("slider_handle").width - anchors - { - verticalCenter: playButton.verticalCenter - left: playButton.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - } - visible: !UM.SimulationView.compatibilityMode - - // custom properties - handleValue: UM.SimulationView.currentPath - maximumValue: UM.SimulationView.numPaths - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - handleColor: UM.Theme.getColor("slider_handle") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - rangeColor: UM.Theme.getColor("slider_groove_fill") - - // update values when layer data changes - Connections - { - target: UM.SimulationView - onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) - onCurrentPathChanged: - { - // Only pause the simulation when the layer was changed manually, not when the simulation is running - if (pathSlider.manuallyChanged) - { - playButton.pauseSimulation() - } - pathSlider.setHandleValue(UM.SimulationView.currentPath) - } - } - - // make sure the slider handlers show the correct value after switching views - Component.onCompleted: - { - pathSlider.setHandleValue(UM.SimulationView.currentPath) - } - } - - LayerSlider - { - id: layerSlider - - width: UM.Theme.getSize("slider_handle").width - height: UM.Theme.getSize("layerview_menu_size").height - - anchors - { - bottom: !UM.SimulationView.compatibilityMode ? pathSlider.top : parent.bottom - top: parent.top - bottomMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0 - left: parent.left - leftMargin: Math.round(UM.Theme.getSize("slider_layerview_margin").width / 2) - } - - // custom properties - upperValue: UM.SimulationView.currentLayer - lowerValue: UM.SimulationView.minimumLayer - maximumValue: UM.SimulationView.numLayers - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - upperHandleColor: UM.Theme.getColor("slider_handle") - lowerHandleColor: UM.Theme.getColor("slider_handle") - rangeHandleColor: UM.Theme.getColor("slider_groove_fill") - handleActiveColor: UM.Theme.getColor("slider_handle_active") - handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width - - // update values when layer data changes - Connections - { - target: UM.SimulationView - onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) - onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) - onCurrentLayerChanged: - { - // Only pause the simulation when the layer was changed manually, not when the simulation is running - if (layerSlider.manuallyChanged) - { - playButton.pauseSimulation() - } - layerSlider.setUpperValue(UM.SimulationView.currentLayer) - } - } - - // make sure the slider handlers show the correct value after switching views - Component.onCompleted: - { - layerSlider.setLowerValue(UM.SimulationView.minimumLayer) - layerSlider.setUpperValue(UM.SimulationView.currentLayer) - } - } - - // Play simulation button - Button - { - id: playButton - iconSource: "./resources/simulation_resume.svg" - style: UM.Theme.styles.small_tool_button - visible: !UM.SimulationView.compatibilityMode - anchors - { - left: parent.left - bottom: parent.bottom - } - - property var status: 0 // indicates if it's stopped (0) or playing (1) - - onClicked: - { - switch(status) - { - case 0: - { - resumeSimulation() - break - } - case 1: - { - pauseSimulation() - break - } - } - } - - function pauseSimulation() - { - UM.SimulationView.setSimulationRunning(false) - iconSource = "./resources/simulation_resume.svg" - simulationTimer.stop() - status = 0 - layerSlider.manuallyChanged = true - pathSlider.manuallyChanged = true - } - - function resumeSimulation() - { - UM.SimulationView.setSimulationRunning(true) - iconSource = "./resources/simulation_pause.svg" - simulationTimer.start() - layerSlider.manuallyChanged = false - pathSlider.manuallyChanged = false - } - } - - Timer - { - id: simulationTimer - interval: 100 - running: false - repeat: true - onTriggered: - { - var currentPath = UM.SimulationView.currentPath - var numPaths = UM.SimulationView.numPaths - var currentLayer = UM.SimulationView.currentLayer - var numLayers = UM.SimulationView.numLayers - // When the user plays the simulation, if the path slider is at the end of this layer, we start - // the simulation at the beginning of the current layer. - if (playButton.status == 0) - { - if (currentPath >= numPaths) - { - UM.SimulationView.setCurrentPath(0) - } - else - { - UM.SimulationView.setCurrentPath(currentPath+1) - } - } - // If the simulation is already playing and we reach the end of a layer, then it automatically - // starts at the beginning of the next layer. - else - { - if (currentPath >= numPaths) - { - // At the end of the model, the simulation stops - if (currentLayer >= numLayers) - { - playButton.pauseSimulation() - } - else - { - UM.SimulationView.setCurrentLayer(currentLayer+1) - UM.SimulationView.setCurrentPath(0) - } - } - else - { - UM.SimulationView.setCurrentPath(currentPath+1) - } - } - // The status must be set here instead of in the resumeSimulation function otherwise it won't work - // correctly, because part of the logic is in this trigger function. - playButton.status = 1 - } - } - } - FontMetrics { id: fontMetrics diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index 3f89ee490f..b12e582441 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -13,7 +13,6 @@ def getMetaData(): return { "view": { "name": catalog.i18nc("@item:inlistbox", "Layer view"), - "view_panel": "SimulationView.qml", "weight": 2 } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 9f53b75dd1..e49683cb8e 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -155,24 +155,6 @@ UM.MainWindow color: UM.Theme.getColor("main_window_header_background") } - Loader - { - // The stage menu is, as the name implies, a menu that is defined by the active stage. - // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage - // without this menu! - id: stageMenu - - anchors - { - left: parent.left - right: parent.right - top: parent.top - } - - height: UM.Theme.getSize("stage_menu").height - source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" - } - Connections { target: stageMenu.item @@ -230,6 +212,22 @@ UM.MainWindow } } + Loader + { + id: viewPanel + + anchors.bottom: viewModeButton.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: viewModeButton.right + + 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.ActiveView.valid ? UM.ActiveView.activeViewPanel : "" + } + Cura.ActionPanelWidget { anchors.right: parent.right @@ -254,15 +252,26 @@ UM.MainWindow anchors.fill: parent - MouseArea + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" + } + + + Loader + { + // The stage menu is, as the name implies, a menu that is defined by the active stage. + // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage + // without this menu! + id: stageMenu + + anchors { - visible: parent.source != "" - anchors.fill: parent - acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true + left: parent.left + right: parent.right + top: parent.top } - source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" + height: UM.Theme.getSize("stage_menu").height + source: UM.Controller.activeStage != null ? UM.Controller.activeStage.stageMenuComponent : "" } UM.MessageStack