mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 13:34:01 -06:00
Merge branch 'STAR-322_cloud-connection' of github.com:Ultimaker/Cura into STAR-322_cloud-connection
This commit is contained in:
commit
2b8c9c17bb
191 changed files with 7411 additions and 5513 deletions
|
@ -72,7 +72,7 @@ class GcodeStartEndFormatter(Formatter):
|
|||
# "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value.
|
||||
if key in kwargs["-1"]:
|
||||
value = kwargs["-1"]
|
||||
if key in kwargs[str(extruder_nr)]:
|
||||
if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]:
|
||||
value = kwargs[str(extruder_nr)][key]
|
||||
|
||||
if value == default_value_str:
|
||||
|
|
|
@ -22,7 +22,7 @@ Cura.MachineAction
|
|||
{
|
||||
id: firmwareUpdaterMachineAction
|
||||
anchors.fill: parent;
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
UM.I18nCatalog { id: catalog; name: "cura"}
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Label
|
||||
|
|
|
@ -20,7 +20,7 @@ UM.Dialog
|
|||
|
||||
GridLayout
|
||||
{
|
||||
UM.I18nCatalog{id: catalog; name:"cura"}
|
||||
UM.I18nCatalog{id: catalog; name: "cura"}
|
||||
anchors.fill: parent;
|
||||
Layout.fillWidth: true
|
||||
columnSpacing: 16 * screenScaleFactor
|
||||
|
|
|
@ -16,7 +16,7 @@ Button
|
|||
{
|
||||
id: modelCheckerButton
|
||||
|
||||
UM.I18nCatalog{id: catalog; name:"cura"}
|
||||
UM.I18nCatalog{id: catalog; name: "cura"}
|
||||
|
||||
visible: manager.hasWarnings
|
||||
tooltip: catalog.i18nc("@info:tooltip", "Some things could be problematic in this print. Click to see tips for adjustment.")
|
||||
|
|
|
@ -1,45 +1,40 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
// parent could be undefined as this component is not visible at all times
|
||||
width: parent ? parent.width : 0
|
||||
height: parent ? parent.height : 0
|
||||
|
||||
// We show a nice overlay on the 3D viewer when the current output device has no monitor view
|
||||
Rectangle
|
||||
{
|
||||
id: viewportOverlay
|
||||
|
||||
color: UM.Theme.getColor("viewport_overlay")
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onWheel: wheel.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
Loader
|
||||
{
|
||||
id: monitorViewComponent
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
property real maximumWidth: parent.width
|
||||
property real maximumHeight: parent.height
|
||||
|
||||
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
||||
visible: sourceComponent != null
|
||||
}
|
||||
}
|
||||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
// We show a nice overlay on the 3D viewer when the current output device has no monitor view
|
||||
Rectangle
|
||||
{
|
||||
id: viewportOverlay
|
||||
|
||||
color: UM.Theme.getColor("viewport_overlay")
|
||||
anchors.fill: parent
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.AllButtons
|
||||
onWheel: wheel.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
Loader
|
||||
{
|
||||
id: monitorViewComponent
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
height: parent.height
|
||||
|
||||
property real maximumWidth: parent.width
|
||||
property real maximumHeight: parent.height
|
||||
|
||||
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null
|
||||
}
|
||||
}
|
23
plugins/MonitorStage/MonitorMenu.qml
Normal file
23
plugins/MonitorStage/MonitorMenu.qml
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
signal showTooltip(Item item, point location, string text)
|
||||
signal hideTooltip()
|
||||
|
||||
Cura.MachineSelector
|
||||
{
|
||||
id: machineSelection
|
||||
headerCornerSide: Cura.RoundedRectangle.Direction.All
|
||||
width: UM.Theme.getSize("machine_selector_widget").width
|
||||
height: parent.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
|
@ -65,15 +65,10 @@ class MonitorStage(CuraStage):
|
|||
# We can only connect now, as we need to be sure that everything is loaded (plugins get created quite early)
|
||||
Application.getInstance().getMachineManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
|
||||
self._onOutputDevicesChanged()
|
||||
self._updateMainOverlay()
|
||||
self._updateSidebar()
|
||||
|
||||
def _updateMainOverlay(self):
|
||||
main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("MonitorStage"),
|
||||
"MonitorMainView.qml")
|
||||
self.addDisplayComponent("main", main_component_path)
|
||||
|
||||
def _updateSidebar(self):
|
||||
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles),
|
||||
"MonitorSidebar.qml")
|
||||
self.addDisplayComponent("sidebar", sidebar_component_path)
|
||||
plugin_path = Application.getInstance().getPluginRegistry().getPluginPath(self.getPluginId())
|
||||
if plugin_path is not None:
|
||||
menu_component_path = os.path.join(plugin_path, "MonitorMenu.qml")
|
||||
main_component_path = os.path.join(plugin_path, "MonitorMain.qml")
|
||||
self.addDisplayComponent("menu", menu_component_path)
|
||||
self.addDisplayComponent("main", main_component_path)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -55,14 +55,14 @@ class PostProcessingPlugin(QObject, Extension):
|
|||
def selectedScriptDefinitionId(self) -> Optional[str]:
|
||||
try:
|
||||
return self._script_list[self._selected_script_index].getDefinitionId()
|
||||
except:
|
||||
except IndexError:
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify=selectedIndexChanged)
|
||||
def selectedScriptStackId(self) -> Optional[str]:
|
||||
try:
|
||||
return self._script_list[self._selected_script_index].getStackId()
|
||||
except:
|
||||
except IndexError:
|
||||
return ""
|
||||
|
||||
## Execute all post-processing scripts on the gcode.
|
||||
|
|
|
@ -31,7 +31,7 @@ UM.Dialog
|
|||
|
||||
Item
|
||||
{
|
||||
UM.I18nCatalog{id: catalog; name:"cura"}
|
||||
UM.I18nCatalog{id: catalog; name: "cura"}
|
||||
id: base
|
||||
property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width)
|
||||
property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
|
||||
|
@ -260,7 +260,7 @@ UM.Dialog
|
|||
|
||||
Rectangle
|
||||
{
|
||||
color: UM.Theme.getColor("sidebar")
|
||||
color: UM.Theme.getColor("main_background")
|
||||
anchors.left: activeScripts.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.right: parent.right
|
||||
|
|
3
plugins/PostProcessingPlugin/scripts/ExampleScript.md
Normal file
3
plugins/PostProcessingPlugin/scripts/ExampleScript.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
A good example script is SearchAndReplace.py.
|
||||
If you have any questions please ask them at:
|
||||
https://github.com/Ultimaker/Cura/issues
|
|
@ -1,43 +0,0 @@
|
|||
# Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V.
|
||||
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
|
||||
from ..Script import Script
|
||||
|
||||
class ExampleScript(Script):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name":"Example script",
|
||||
"key": "ExampleScript",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"test":
|
||||
{
|
||||
"label": "Test",
|
||||
"description": "None",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.5,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "0.1",
|
||||
"maximum_value_warning": "1"
|
||||
},
|
||||
"derp":
|
||||
{
|
||||
"label": "zomg",
|
||||
"description": "afgasgfgasfgasf",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.5,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "0.1",
|
||||
"maximum_value_warning": "1"
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
return data
|
140
plugins/PrepareStage/PrepareMenu.qml
Normal file
140
plugins/PrepareStage/PrepareMenu.qml
Normal file
|
@ -0,0 +1,140 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
import QtGraphicalEffects 1.0 // For the dropshadow
|
||||
|
||||
Item
|
||||
{
|
||||
id: prepareMenu
|
||||
// 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"
|
||||
}
|
||||
|
||||
// Item to ensure that all of the buttons are nicely centered.
|
||||
Item
|
||||
{
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: openFileButton.width + itemRow.width + UM.Theme.getSize("default_margin").width
|
||||
height: parent.height
|
||||
|
||||
RowLayout
|
||||
{
|
||||
id: itemRow
|
||||
|
||||
anchors.left: openFileButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
|
||||
width: Math.round(0.9 * prepareMenu.width)
|
||||
height: parent.height
|
||||
spacing: 0
|
||||
|
||||
Cura.MachineSelector
|
||||
{
|
||||
id: machineSelection
|
||||
z: openFileButton.z - 1 //Ensure that the tooltip of the open file button stays above the item row.
|
||||
headerCornerSide: Cura.RoundedRectangle.Direction.Left
|
||||
Layout.minimumWidth: UM.Theme.getSize("machine_selector_widget").width
|
||||
Layout.maximumWidth: UM.Theme.getSize("machine_selector_widget").width
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
// Separator line
|
||||
Rectangle
|
||||
{
|
||||
height: parent.height
|
||||
width: UM.Theme.getSize("default_lining").width
|
||||
color: UM.Theme.getColor("lining")
|
||||
}
|
||||
|
||||
Cura.QuickConfigurationSelector
|
||||
{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width
|
||||
}
|
||||
|
||||
// Separator line
|
||||
Rectangle
|
||||
{
|
||||
height: parent.height
|
||||
width: UM.Theme.getSize("default_lining").width
|
||||
color: UM.Theme.getColor("lining")
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: printSetupSelectorItem
|
||||
// This is a work around to prevent the printSetupSelector from having to be re-loaded every time
|
||||
// a stage switch is done.
|
||||
children: [printSetupSelector]
|
||||
height: childrenRect.height
|
||||
width: childrenRect.width
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: openFileButton
|
||||
height: UM.Theme.getSize("stage_menu").height
|
||||
width: UM.Theme.getSize("stage_menu").height
|
||||
onClicked: Cura.Actions.open.trigger()
|
||||
hoverEnabled: true
|
||||
|
||||
contentItem: Item
|
||||
{
|
||||
anchors.fill: parent
|
||||
UM.RecolorImage
|
||||
{
|
||||
id: buttonIcon
|
||||
anchors.centerIn: parent
|
||||
source: UM.Theme.getIcon("load")
|
||||
width: UM.Theme.getSize("button_icon").width
|
||||
height: UM.Theme.getSize("button_icon").height
|
||||
color: UM.Theme.getColor("toolbar_button_text")
|
||||
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle
|
||||
{
|
||||
id: background
|
||||
height: UM.Theme.getSize("stage_menu").height
|
||||
width: UM.Theme.getSize("stage_menu").height
|
||||
|
||||
radius: UM.Theme.getSize("default_radius").width
|
||||
color: openFileButton.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
|
||||
}
|
||||
|
||||
DropShadow
|
||||
{
|
||||
id: shadow
|
||||
// Don't blur the shadow
|
||||
radius: 0
|
||||
anchors.fill: background
|
||||
source: background
|
||||
verticalOffset: 2
|
||||
visible: true
|
||||
color: UM.Theme.getColor("action_button_shadow")
|
||||
// Should always be drawn behind the background.
|
||||
z: background.z - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,14 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os.path
|
||||
from UM.Application import Application
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Resources import Resources
|
||||
from cura.Stages.CuraStage import CuraStage
|
||||
|
||||
|
||||
|
||||
## Stage for preparing model (slicing).
|
||||
class PrepareStage(CuraStage):
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
Application.getInstance().engineCreatedSignal.connect(self._engineCreated)
|
||||
|
@ -16,4 +17,7 @@ class PrepareStage(CuraStage):
|
|||
def _engineCreated(self):
|
||||
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles),
|
||||
"PrepareSidebar.qml")
|
||||
|
||||
menu_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("PrepareStage"), "PrepareMenu.qml")
|
||||
self.addDisplayComponent("menu", menu_component_path)
|
||||
self.addDisplayComponent("sidebar", sidebar_component_path)
|
||||
|
|
18
plugins/PreviewStage/PreviewMain.qml
Normal file
18
plugins/PreviewStage/PreviewMain.qml
Normal file
|
@ -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 : ""
|
||||
}
|
77
plugins/PreviewStage/PreviewMenu.qml
Normal file
77
plugins/PreviewStage/PreviewMenu.qml
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
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()
|
||||
|
||||
property real itemHeight: height - 2 * UM.Theme.getSize("default_lining").width
|
||||
|
||||
UM.I18nCatalog
|
||||
{
|
||||
id: catalog
|
||||
name: "cura"
|
||||
}
|
||||
|
||||
|
||||
Row
|
||||
{
|
||||
id: stageMenuRow
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
|
||||
Cura.ViewsSelector
|
||||
{
|
||||
id: viewsSelector
|
||||
height: parent.height
|
||||
width: UM.Theme.getSize("views_selector").width
|
||||
headerCornerSide: Cura.RoundedRectangle.Direction.Left
|
||||
}
|
||||
|
||||
// Separator line
|
||||
Rectangle
|
||||
{
|
||||
height: parent.height
|
||||
// If there is no viewPanel, we only need a single spacer, so hide this one.
|
||||
visible: viewPanel.source != ""
|
||||
width: visible ? UM.Theme.getSize("default_lining").width : 0
|
||||
|
||||
color: UM.Theme.getColor("lining")
|
||||
}
|
||||
|
||||
Loader
|
||||
{
|
||||
id: viewPanel
|
||||
height: parent.height
|
||||
width: childrenRect.width
|
||||
source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : ""
|
||||
}
|
||||
|
||||
// Separator line
|
||||
Rectangle
|
||||
{
|
||||
height: parent.height
|
||||
width: UM.Theme.getSize("default_lining").width
|
||||
color: UM.Theme.getColor("lining")
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: printSetupSelectorItem
|
||||
// This is a work around to prevent the printSetupSelector from having to be re-loaded every time
|
||||
// a stage switch is done.
|
||||
children: [printSetupSelector]
|
||||
height: childrenRect.height
|
||||
width: childrenRect.width
|
||||
}
|
||||
}
|
||||
}
|
51
plugins/PreviewStage/PreviewStage.py
Normal file
51
plugins/PreviewStage/PreviewStage.py
Normal file
|
@ -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
plugins/PreviewStage/__init__.py
Normal file
22
plugins/PreviewStage/__init__.py
Normal file
|
@ -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
plugins/PreviewStage/plugin.json
Normal file
8
plugins/PreviewStage/plugin.json
Normal file
|
@ -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"
|
||||
}
|
|
@ -13,23 +13,20 @@ 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 var activeHandle: upperHandle
|
||||
|
||||
// track properties
|
||||
property real trackThickness: 4 // 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"
|
||||
// Track properties
|
||||
property real trackThickness: UM.Theme.getSize("slider_groove").width // width of the slider track
|
||||
property real trackRadius: UM.Theme.getSize("slider_groove_radius").width
|
||||
property color trackColor: UM.Theme.getColor("slider_groove")
|
||||
|
||||
// value properties
|
||||
property real maximumValue: 100
|
||||
|
@ -80,7 +77,7 @@ Item
|
|||
return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
|
||||
}
|
||||
|
||||
// slider track
|
||||
// Slider track
|
||||
Rectangle
|
||||
{
|
||||
id: track
|
||||
|
@ -90,8 +87,6 @@ Item
|
|||
radius: sliderRoot.trackRadius
|
||||
anchors.centerIn: sliderRoot
|
||||
color: sliderRoot.trackColor
|
||||
border.width: sliderRoot.trackBorderWidth
|
||||
border.color: sliderRoot.trackBorderColor
|
||||
visible: sliderRoot.layersVisible
|
||||
}
|
||||
|
||||
|
@ -106,7 +101,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
|
||||
|
@ -140,9 +135,10 @@ Item
|
|||
|
||||
Rectangle
|
||||
{
|
||||
width: sliderRoot.trackThickness - 2 * sliderRoot.trackBorderWidth
|
||||
width: sliderRoot.trackThickness
|
||||
height: parent.height + sliderRoot.handleSize
|
||||
anchors.centerIn: parent
|
||||
radius: sliderRoot.trackRadius
|
||||
color: sliderRoot.rangeHandleColor
|
||||
}
|
||||
|
||||
|
@ -167,9 +163,9 @@ Item
|
|||
id: rangleHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - width - UM.Theme.getSize("default_margin").width
|
||||
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 +271,7 @@ Item
|
|||
id: upperHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - 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 +381,9 @@ Item
|
|||
id: lowerHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - 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
|
||||
|
|
|
@ -14,19 +14,17 @@ 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 trackRadius: trackThickness / 2
|
||||
property color trackColor: "white"
|
||||
property real trackBorderWidth: 1 // width of the slider track border
|
||||
property color trackBorderColor: "black"
|
||||
property real trackThickness: UM.Theme.getSize("slider_groove").width
|
||||
property real trackRadius: UM.Theme.getSize("slider_groove_radius").width
|
||||
property color trackColor: UM.Theme.getColor("slider_groove")
|
||||
|
||||
// value properties
|
||||
property real maximumValue: 100
|
||||
|
@ -68,8 +66,6 @@ Item
|
|||
radius: sliderRoot.trackRadius
|
||||
anchors.centerIn: sliderRoot
|
||||
color: sliderRoot.trackColor
|
||||
border.width: sliderRoot.trackBorderWidth
|
||||
border.color: sliderRoot.trackBorderColor
|
||||
visible: sliderRoot.pathsVisible
|
||||
}
|
||||
|
||||
|
@ -86,9 +82,10 @@ Item
|
|||
|
||||
Rectangle
|
||||
{
|
||||
height: sliderRoot.trackThickness - 2 * sliderRoot.trackBorderWidth
|
||||
height: sliderRoot.trackThickness
|
||||
width: parent.width + sliderRoot.handleSize
|
||||
anchors.centerIn: parent
|
||||
radius: sliderRoot.trackRadius
|
||||
color: sliderRoot.rangeColor
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ from UM.Mesh.MeshBuilder import MeshBuilder
|
|||
from UM.Message import Message
|
||||
from UM.Platform import Platform
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Qt.QtApplication import QtApplication
|
||||
from UM.Resources import Resources
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||
|
||||
|
@ -26,8 +27,8 @@ from UM.View.GL.OpenGL import OpenGL
|
|||
from UM.View.GL.OpenGLContext import OpenGLContext
|
||||
from UM.View.GL.ShaderProgram import ShaderProgram
|
||||
|
||||
from UM.View.View import View
|
||||
from UM.i18n import i18nCatalog
|
||||
from cura.CuraView import CuraView
|
||||
from cura.Scene.ConvexHullNode import ConvexHullNode
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
|
@ -48,15 +49,15 @@ catalog = i18nCatalog("cura")
|
|||
|
||||
|
||||
## View used to display g-code paths.
|
||||
class SimulationView(View):
|
||||
class SimulationView(CuraView):
|
||||
# Must match SimulationView.qml
|
||||
LAYER_VIEW_TYPE_MATERIAL_TYPE = 0
|
||||
LAYER_VIEW_TYPE_LINE_TYPE = 1
|
||||
LAYER_VIEW_TYPE_FEEDRATE = 2
|
||||
LAYER_VIEW_TYPE_THICKNESS = 3
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
def __init__(self, parent = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self._max_layers = 0
|
||||
self._current_layer_num = 0
|
||||
|
@ -113,6 +114,16 @@ class SimulationView(View):
|
|||
self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"),
|
||||
title = catalog.i18nc("@info:title", "Simulation View"))
|
||||
|
||||
QtApplication.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
|
||||
|
||||
def _onEngineCreated(self) -> None:
|
||||
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
|
||||
if plugin_path:
|
||||
self.addDisplayComponent("main", os.path.join(plugin_path, "SimulationViewMainComponent.qml"))
|
||||
self.addDisplayComponent("menu", os.path.join(plugin_path, "SimulationViewMenuComponent.qml"))
|
||||
else:
|
||||
Logger.log("e", "Unable to find the path for %s", self.getPluginId())
|
||||
|
||||
def _evaluateCompatibilityMode(self) -> bool:
|
||||
return OpenGLContext.isLegacyOpenGL() or bool(Application.getInstance().getPreferences().getValue("view/force_layer_view_compatibility_mode"))
|
||||
|
||||
|
|
|
@ -1,808 +0,0 @@
|
|||
// 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
|
||||
{
|
||||
id: base
|
||||
width:
|
||||
{
|
||||
if (UM.SimulationView.compatibilityMode)
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size_compatibility").width;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size").width;
|
||||
}
|
||||
}
|
||||
height: {
|
||||
if (viewSettings.collapsed)
|
||||
{
|
||||
if (UM.SimulationView.compatibilityMode)
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size_compatibility_collapsed").height;
|
||||
}
|
||||
return UM.Theme.getSize("layerview_menu_size_collapsed").height;
|
||||
}
|
||||
else if (UM.SimulationView.compatibilityMode)
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size_compatibility").height;
|
||||
}
|
||||
else if (UM.Preferences.getValue("layerview/layer_view_type") == 0)
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size_material_color_mode").height + UM.SimulationView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height)
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getSize("layerview_menu_size").height + UM.SimulationView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height)
|
||||
}
|
||||
}
|
||||
Behavior on height { NumberAnimation { duration: 100 } }
|
||||
|
||||
property var buttonTarget:
|
||||
{
|
||||
if(parent != null)
|
||||
{
|
||||
var force_binding = parent.y; // ensure this gets reevaluated when the panel moves
|
||||
return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y)
|
||||
}
|
||||
return Qt.point(0,0)
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: layerViewMenu
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
clip: true
|
||||
z: layerSlider.z - 1
|
||||
color: UM.Theme.getColor("tool_panel_background")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
|
||||
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: viewSettings.collapsed = !viewSettings.collapsed
|
||||
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: UM.RecolorImage
|
||||
{
|
||||
width: control.width
|
||||
height: control.height
|
||||
sourceSize.width: width
|
||||
sourceSize.height: width
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
source: viewSettings.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
|
||||
}
|
||||
label: Label{ }
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: viewSettings
|
||||
|
||||
property bool collapsed: false
|
||||
property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|")
|
||||
property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves")
|
||||
property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers")
|
||||
property bool show_skin: UM.Preferences.getValue("layerview/show_skin")
|
||||
property bool show_infill: UM.Preferences.getValue("layerview/show_infill")
|
||||
// if we are in compatibility mode, we only show the "line type"
|
||||
property bool show_legend: UM.SimulationView.compatibilityMode ? true : UM.Preferences.getValue("layerview/layer_view_type") == 1
|
||||
property bool show_gradient: UM.SimulationView.compatibilityMode ? false : UM.Preferences.getValue("layerview/layer_view_type") == 2 || UM.Preferences.getValue("layerview/layer_view_type") == 3
|
||||
property bool show_feedrate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 2
|
||||
property bool show_thickness_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 3
|
||||
property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers")
|
||||
property int top_layer_count: UM.Preferences.getValue("view/top_layer_count")
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
spacing: UM.Theme.getSize("layerview_row_spacing").height
|
||||
|
||||
Label
|
||||
{
|
||||
id: layerViewTypesLabel
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@label","Color scheme")
|
||||
font: UM.Theme.getFont("default");
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
Layout.fillWidth: true
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
}
|
||||
|
||||
ListModel // matches SimulationView.py
|
||||
{
|
||||
id: layerViewTypes
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Material Color"),
|
||||
type_id: 0
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Line Type"),
|
||||
type_id: 1
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Feedrate"),
|
||||
type_id: 2
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Layer thickness"),
|
||||
type_id: 3 // these ids match the switching in the shader
|
||||
})
|
||||
}
|
||||
|
||||
ComboBox
|
||||
{
|
||||
id: layerTypeCombobox
|
||||
anchors.left: parent.left
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
|
||||
model: layerViewTypes
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.combobox
|
||||
anchors.right: parent.right
|
||||
|
||||
onActivated:
|
||||
{
|
||||
UM.Preferences.setValue("layerview/layer_view_type", index);
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type");
|
||||
updateLegends(currentIndex);
|
||||
}
|
||||
|
||||
function updateLegends(type_id)
|
||||
{
|
||||
// update visibility of legends
|
||||
viewSettings.show_legend = UM.SimulationView.compatibilityMode || (type_id == 1);
|
||||
viewSettings.show_gradient = !UM.SimulationView.compatibilityMode && (type_id == 2 || type_id == 3);
|
||||
viewSettings.show_feedrate_gradient = viewSettings.show_gradient && (type_id == 2);
|
||||
viewSettings.show_thickness_gradient = viewSettings.show_gradient && (type_id == 3);
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: compatibilityModeLabel
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@label","Compatibility Mode")
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text")
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: UM.Theme.getSize("layerview_row").height
|
||||
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
height: Math.round(UM.Theme.getSize("default_margin").width / 2)
|
||||
width: width
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: UM.Preferences
|
||||
onPreferenceChanged:
|
||||
{
|
||||
layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type");
|
||||
layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex);
|
||||
playButton.pauseSimulation();
|
||||
viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|");
|
||||
viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves");
|
||||
viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers");
|
||||
viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin");
|
||||
viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill");
|
||||
viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers");
|
||||
viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count");
|
||||
}
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: Cura.ExtrudersModel{}
|
||||
CheckBox
|
||||
{
|
||||
id: extrudersModelCheckBox
|
||||
checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == ""
|
||||
onClicked:
|
||||
{
|
||||
viewSettings.extruder_opacities[index] = checked ? 1.0 : 0.0
|
||||
UM.Preferences.setValue("layerview/extruder_opacities", viewSettings.extruder_opacities.join("|"));
|
||||
}
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
enabled: index + 1 <= 4
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: extrudersModelCheckBox.right
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
color: model.color
|
||||
radius: Math.round(width / 2)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
visible: !viewSettings.show_legend & !viewSettings.show_gradient
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
|
||||
style: UM.Theme.styles.checkbox
|
||||
Label
|
||||
{
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: extrudersModelCheckBox.left;
|
||||
anchors.right: extrudersModelCheckBox.right;
|
||||
anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2)
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: ListModel
|
||||
{
|
||||
id: typesLegendModel
|
||||
Component.onCompleted:
|
||||
{
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Travels"),
|
||||
initialValue: viewSettings.show_travel_moves,
|
||||
preference: "layerview/show_travel_moves",
|
||||
colorId: "layerview_move_combing"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Helpers"),
|
||||
initialValue: viewSettings.show_helpers,
|
||||
preference: "layerview/show_helpers",
|
||||
colorId: "layerview_support"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Shell"),
|
||||
initialValue: viewSettings.show_skin,
|
||||
preference: "layerview/show_skin",
|
||||
colorId: "layerview_inset_0"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Infill"),
|
||||
initialValue: viewSettings.show_infill,
|
||||
preference: "layerview/show_infill",
|
||||
colorId: "layerview_infill"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
id: legendModelCheckBox
|
||||
checked: model.initialValue
|
||||
onClicked:
|
||||
{
|
||||
UM.Preferences.setValue(model.preference, checked);
|
||||
}
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: legendModelCheckBox.right
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
color: UM.Theme.getColor(model.colorId)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
visible: viewSettings.show_legend
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
|
||||
style: UM.Theme.styles.checkbox
|
||||
Label
|
||||
{
|
||||
text: label
|
||||
font: UM.Theme.getFont("default")
|
||||
elide: Text.ElideRight
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: legendModelCheckBox.left;
|
||||
anchors.right: legendModelCheckBox.right;
|
||||
anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2)
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
checked: viewSettings.only_show_top_layers
|
||||
onClicked:
|
||||
{
|
||||
UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0);
|
||||
}
|
||||
text: catalog.i18nc("@label", "Only Show Top Layers")
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.checkbox
|
||||
}
|
||||
CheckBox
|
||||
{
|
||||
checked: viewSettings.top_layer_count == 5
|
||||
onClicked:
|
||||
{
|
||||
UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1);
|
||||
}
|
||||
text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top")
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.checkbox
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: ListModel
|
||||
{
|
||||
id: typesLegendModelNoCheck
|
||||
Component.onCompleted:
|
||||
{
|
||||
typesLegendModelNoCheck.append({
|
||||
label: catalog.i18nc("@label", "Top / Bottom"),
|
||||
colorId: "layerview_skin",
|
||||
});
|
||||
typesLegendModelNoCheck.append({
|
||||
label: catalog.i18nc("@label", "Inner Wall"),
|
||||
colorId: "layerview_inset_x",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: label
|
||||
visible: viewSettings.show_legend
|
||||
id: typesLegendModelLabel
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: typesLegendModelLabel.right
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
color: UM.Theme.getColor(model.colorId)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
visible: viewSettings.show_legend
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
}
|
||||
}
|
||||
|
||||
// Text for the minimum, maximum and units for the feedrates and layer thickness
|
||||
Item
|
||||
{
|
||||
id: gradientLegend
|
||||
visible: viewSettings.show_gradient
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("layerview_row").height
|
||||
anchors
|
||||
{
|
||||
topMargin: UM.Theme.getSize("slider_layerview_margin").height
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: minText()
|
||||
anchors.left: parent.left
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
|
||||
function minText()
|
||||
{
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMinFeedrate()).toFixed(2)
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMinThickness()).toFixed(2)
|
||||
}
|
||||
}
|
||||
return catalog.i18nc("@label","min")
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: unitsText()
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
|
||||
function unitsText()
|
||||
{
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return "mm/s"
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return "mm"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: maxText()
|
||||
anchors.right: parent.right
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
|
||||
function maxText()
|
||||
{
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMaxFeedrate()).toFixed(2)
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMaxThickness()).toFixed(2)
|
||||
}
|
||||
}
|
||||
return catalog.i18nc("@label","max")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gradient colors for feedrate
|
||||
Rectangle
|
||||
{ // In QML 5.9 can be changed by LinearGradient
|
||||
// Invert values because then the bar is rotated 90 degrees
|
||||
id: feedrateGradient
|
||||
visible: viewSettings.show_feedrate_gradient
|
||||
anchors.left: parent.right
|
||||
height: parent.width
|
||||
width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
transform: Rotation {origin.x: 0; origin.y: 0; angle: 90}
|
||||
gradient: Gradient
|
||||
{
|
||||
GradientStop
|
||||
{
|
||||
position: 0.000
|
||||
color: Qt.rgba(1, 0.5, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.625
|
||||
color: Qt.rgba(0.375, 0.5, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.75
|
||||
color: Qt.rgba(0.25, 1, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 1.0
|
||||
color: Qt.rgba(0, 0, 1, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gradient colors for layer thickness (similar to parula colormap)
|
||||
Rectangle // In QML 5.9 can be changed by LinearGradient
|
||||
{
|
||||
// Invert values because then the bar is rotated 90 degrees
|
||||
id: thicknessGradient
|
||||
visible: viewSettings.show_thickness_gradient
|
||||
anchors.left: parent.right
|
||||
height: parent.width
|
||||
width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
transform: Rotation {origin.x: 0; origin.y: 0; angle: 90}
|
||||
gradient: Gradient
|
||||
{
|
||||
GradientStop
|
||||
{
|
||||
position: 0.000
|
||||
color: Qt.rgba(1, 1, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.25
|
||||
color: Qt.rgba(1, 0.75, 0.25, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.5
|
||||
color: Qt.rgba(0, 0.75, 0.5, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.75
|
||||
color: Qt.rgba(0, 0.375, 0.75, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 1.0
|
||||
color: Qt.rgba(0, 0, 0.5, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: slidersBox
|
||||
|
||||
width: parent.width
|
||||
visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
|
||||
|
||||
anchors
|
||||
{
|
||||
top: parent.bottom
|
||||
topMargin: UM.Theme.getSize("slider_layerview_margin").height
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
PathSlider
|
||||
{
|
||||
id: pathSlider
|
||||
|
||||
height: UM.Theme.getSize("slider_handle").width
|
||||
anchors.left: playButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.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
|
||||
{
|
||||
top: !UM.SimulationView.compatibilityMode ? pathSlider.bottom : parent.top
|
||||
topMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0
|
||||
right: parent.right
|
||||
rightMargin: UM.Theme.getSize("slider_layerview_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)
|
||||
}
|
||||
}
|
||||
|
||||
// Play simulation button
|
||||
Button
|
||||
{
|
||||
id: playButton
|
||||
iconSource: "./resources/simulation_resume.svg"
|
||||
style: UM.Theme.styles.small_tool_button
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
anchors
|
||||
{
|
||||
verticalCenter: pathSlider.verticalCenter
|
||||
}
|
||||
|
||||
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
|
||||
font: UM.Theme.getFont("default")
|
||||
}
|
||||
}
|
212
plugins/SimulationView/SimulationViewMainComponent.qml
Normal file
212
plugins/SimulationView/SimulationViewMainComponent.qml
Normal file
|
@ -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.4 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: UM.Theme.getSize("slider_layerview_size").height
|
||||
|
||||
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
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UM.SimpleButton
|
||||
{
|
||||
id: playButton
|
||||
iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg"
|
||||
width: UM.Theme.getSize("small_button").width
|
||||
height: UM.Theme.getSize("small_button").height
|
||||
hoverBackgroundColor: UM.Theme.getColor("small_button_hover")
|
||||
hoverColor: UM.Theme.getColor("small_button_text_hover")
|
||||
color: UM.Theme.getColor("small_button_text")
|
||||
iconMargin: 0.5 * UM.Theme.getSize("wide_lining").width
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
|
||||
Connections
|
||||
{
|
||||
target: UM.Preferences
|
||||
onPreferenceChanged:
|
||||
{
|
||||
playButton.pauseSimulation()
|
||||
}
|
||||
}
|
||||
|
||||
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("slider_layerview_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
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
530
plugins/SimulationView/SimulationViewMenuComponent.qml
Normal file
530
plugins/SimulationView/SimulationViewMenuComponent.qml
Normal file
|
@ -0,0 +1,530 @@
|
|||
// 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 QtGraphicalEffects 1.0
|
||||
|
||||
import UM 1.0 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Cura.ExpandableComponent
|
||||
{
|
||||
id: base
|
||||
|
||||
width: UM.Theme.getSize("layerview_menu_size").width
|
||||
iconSource: UM.Theme.getIcon("pencil")
|
||||
|
||||
Connections
|
||||
{
|
||||
target: UM.Preferences
|
||||
onPreferenceChanged:
|
||||
{
|
||||
layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type")
|
||||
layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex)
|
||||
viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|")
|
||||
viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves")
|
||||
viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers")
|
||||
viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin")
|
||||
viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill")
|
||||
viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers")
|
||||
viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count")
|
||||
}
|
||||
}
|
||||
|
||||
headerItem: Label
|
||||
{
|
||||
id: layerViewTypesLabel
|
||||
text: catalog.i18nc("@label", "Color scheme")
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
height: base.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
popupItem: Column
|
||||
{
|
||||
id: viewSettings
|
||||
|
||||
property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|")
|
||||
property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves")
|
||||
property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers")
|
||||
property bool show_skin: UM.Preferences.getValue("layerview/show_skin")
|
||||
property bool show_infill: UM.Preferences.getValue("layerview/show_infill")
|
||||
|
||||
// If we are in compatibility mode, we only show the "line type"
|
||||
property bool show_legend: UM.SimulationView.compatibilityMode ? true : UM.Preferences.getValue("layerview/layer_view_type") == 1
|
||||
property bool show_gradient: UM.SimulationView.compatibilityMode ? false : UM.Preferences.getValue("layerview/layer_view_type") == 2 || UM.Preferences.getValue("layerview/layer_view_type") == 3
|
||||
property bool show_feedrate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 2
|
||||
property bool show_thickness_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 3
|
||||
property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers")
|
||||
property int top_layer_count: UM.Preferences.getValue("view/top_layer_count")
|
||||
|
||||
width: UM.Theme.getSize("layerview_menu_size").width - 2 * UM.Theme.getSize("default_margin").width
|
||||
height: implicitHeight
|
||||
|
||||
spacing: UM.Theme.getSize("layerview_row_spacing").height
|
||||
|
||||
ListModel // matches SimulationView.py
|
||||
{
|
||||
id: layerViewTypes
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Material Color"),
|
||||
type_id: 0
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Line Type"),
|
||||
type_id: 1
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Feedrate"),
|
||||
type_id: 2
|
||||
})
|
||||
layerViewTypes.append({
|
||||
text: catalog.i18nc("@label:listbox", "Layer thickness"),
|
||||
type_id: 3 // these ids match the switching in the shader
|
||||
})
|
||||
}
|
||||
|
||||
ComboBox
|
||||
{
|
||||
id: layerTypeCombobox
|
||||
width: parent.width
|
||||
model: layerViewTypes
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.combobox
|
||||
|
||||
onActivated:
|
||||
{
|
||||
UM.Preferences.setValue("layerview/layer_view_type", index);
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type");
|
||||
updateLegends(currentIndex);
|
||||
}
|
||||
|
||||
function updateLegends(type_id)
|
||||
{
|
||||
// Update the visibility of the legends.
|
||||
viewSettings.show_legend = UM.SimulationView.compatibilityMode || (type_id == 1);
|
||||
viewSettings.show_gradient = !UM.SimulationView.compatibilityMode && (type_id == 2 || type_id == 3);
|
||||
viewSettings.show_feedrate_gradient = viewSettings.show_gradient && (type_id == 2);
|
||||
viewSettings.show_thickness_gradient = viewSettings.show_gradient && (type_id == 3);
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: compatibilityModeLabel
|
||||
text: catalog.i18nc("@label","Compatibility Mode")
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text")
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
height: UM.Theme.getSize("layerview_row").height
|
||||
width: parent.width
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Item // Spacer
|
||||
{
|
||||
height: Math.round(UM.Theme.getSize("default_margin").width / 2)
|
||||
width: width
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: Cura.ExtrudersModel{}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
id: extrudersModelCheckBox
|
||||
checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == ""
|
||||
height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
width: parent.width
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
enabled: index < 4
|
||||
|
||||
onClicked:
|
||||
{
|
||||
viewSettings.extruder_opacities[index] = checked ? 1.0 : 0.0
|
||||
UM.Preferences.setValue("layerview/extruder_opacities", viewSettings.extruder_opacities.join("|"));
|
||||
}
|
||||
|
||||
style: UM.Theme.styles.checkbox
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: extrudersModelCheckBox.right
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
color: model.color
|
||||
radius: Math.round(width / 2)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
visible: !viewSettings.show_legend && !viewSettings.show_gradient
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: extrudersModelCheckBox.left
|
||||
right: extrudersModelCheckBox.right
|
||||
leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2)
|
||||
rightMargin: UM.Theme.getSize("default_margin").width * 2
|
||||
}
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: ListModel
|
||||
{
|
||||
id: typesLegendModel
|
||||
Component.onCompleted:
|
||||
{
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Travels"),
|
||||
initialValue: viewSettings.show_travel_moves,
|
||||
preference: "layerview/show_travel_moves",
|
||||
colorId: "layerview_move_combing"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Helpers"),
|
||||
initialValue: viewSettings.show_helpers,
|
||||
preference: "layerview/show_helpers",
|
||||
colorId: "layerview_support"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Shell"),
|
||||
initialValue: viewSettings.show_skin,
|
||||
preference: "layerview/show_skin",
|
||||
colorId: "layerview_inset_0"
|
||||
});
|
||||
typesLegendModel.append({
|
||||
label: catalog.i18nc("@label", "Show Infill"),
|
||||
initialValue: viewSettings.show_infill,
|
||||
preference: "layerview/show_infill",
|
||||
colorId: "layerview_infill"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
id: legendModelCheckBox
|
||||
checked: model.initialValue
|
||||
onClicked: UM.Preferences.setValue(model.preference, checked)
|
||||
height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
width: parent.width
|
||||
|
||||
style: UM.Theme.styles.checkbox
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: legendModelCheckBox.right
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
color: UM.Theme.getColor(model.colorId)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
visible: viewSettings.show_legend
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: label
|
||||
font: UM.Theme.getFont("default")
|
||||
elide: Text.ElideRight
|
||||
renderType: Text.NativeRendering
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: legendModelCheckBox.left
|
||||
anchors.right: legendModelCheckBox.right
|
||||
anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2)
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
checked: viewSettings.only_show_top_layers
|
||||
onClicked: UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0)
|
||||
text: catalog.i18nc("@label", "Only Show Top Layers")
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.checkbox
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
CheckBox
|
||||
{
|
||||
checked: viewSettings.top_layer_count == 5
|
||||
onClicked: UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1)
|
||||
text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top")
|
||||
width: parent.width
|
||||
visible: UM.SimulationView.compatibilityMode
|
||||
style: UM.Theme.styles.checkbox
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: ListModel
|
||||
{
|
||||
id: typesLegendModelNoCheck
|
||||
Component.onCompleted:
|
||||
{
|
||||
typesLegendModelNoCheck.append({
|
||||
label: catalog.i18nc("@label", "Top / Bottom"),
|
||||
colorId: "layerview_skin",
|
||||
});
|
||||
typesLegendModelNoCheck.append({
|
||||
label: catalog.i18nc("@label", "Inner Wall"),
|
||||
colorId: "layerview_inset_x",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: label
|
||||
visible: viewSettings.show_legend
|
||||
id: typesLegendModelLabel
|
||||
|
||||
height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
|
||||
width: parent.width
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
renderType: Text.NativeRendering
|
||||
Rectangle
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: typesLegendModelLabel.right
|
||||
|
||||
width: UM.Theme.getSize("layerview_legend_size").width
|
||||
height: UM.Theme.getSize("layerview_legend_size").height
|
||||
|
||||
color: UM.Theme.getColor(model.colorId)
|
||||
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text for the minimum, maximum and units for the feedrates and layer thickness
|
||||
Item
|
||||
{
|
||||
id: gradientLegend
|
||||
visible: viewSettings.show_gradient
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("layerview_row").height
|
||||
|
||||
Label
|
||||
{
|
||||
text:
|
||||
{
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMinFeedrate()).toFixed(2)
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMinThickness()).toFixed(2)
|
||||
}
|
||||
}
|
||||
return catalog.i18nc("@label","min")
|
||||
}
|
||||
anchors.left: parent.left
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: {
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return "mm/s"
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return "mm"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: {
|
||||
if (UM.SimulationView.layerActivity && CuraApplication.platformActivity)
|
||||
{
|
||||
// Feedrate selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 2)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMaxFeedrate()).toFixed(2)
|
||||
}
|
||||
// Layer thickness selected
|
||||
if (UM.Preferences.getValue("layerview/layer_view_type") == 3)
|
||||
{
|
||||
return parseFloat(UM.SimulationView.getMaxThickness()).toFixed(2)
|
||||
}
|
||||
}
|
||||
return catalog.i18nc("@label","max")
|
||||
}
|
||||
|
||||
anchors.right: parent.right
|
||||
color: UM.Theme.getColor("setting_control_text")
|
||||
font: UM.Theme.getFont("default")
|
||||
}
|
||||
}
|
||||
|
||||
// Gradient colors for feedrate
|
||||
Rectangle
|
||||
{
|
||||
id: feedrateGradient
|
||||
visible: viewSettings.show_feedrate_gradient
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
|
||||
LinearGradient
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
leftMargin: UM.Theme.getSize("default_lining").width
|
||||
right: parent.right
|
||||
rightMargin: UM.Theme.getSize("default_lining").width
|
||||
top: parent.top
|
||||
topMargin: UM.Theme.getSize("default_lining").width
|
||||
bottom: parent.bottom
|
||||
bottomMargin: UM.Theme.getSize("default_lining").width
|
||||
}
|
||||
start: Qt.point(0, 0)
|
||||
end: Qt.point(parent.width, 0)
|
||||
gradient: Gradient
|
||||
{
|
||||
GradientStop
|
||||
{
|
||||
position: 0.000
|
||||
color: Qt.rgba(0, 0, 1, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.25
|
||||
color: Qt.rgba(0.25, 1, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.375
|
||||
color: Qt.rgba(0.375, 0.5, 0, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 1.0
|
||||
color: Qt.rgba(1, 0.5, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gradient colors for layer thickness (similar to parula colormap)
|
||||
Rectangle
|
||||
{
|
||||
id: thicknessGradient
|
||||
visible: viewSettings.show_thickness_gradient
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
|
||||
LinearGradient
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
leftMargin: UM.Theme.getSize("default_lining").width
|
||||
right: parent.right
|
||||
rightMargin: UM.Theme.getSize("default_lining").width
|
||||
top: parent.top
|
||||
topMargin: UM.Theme.getSize("default_lining").width
|
||||
bottom: parent.bottom
|
||||
bottomMargin: UM.Theme.getSize("default_lining").width
|
||||
}
|
||||
start: Qt.point(0, 0)
|
||||
end: Qt.point(parent.width, 0)
|
||||
gradient: Gradient
|
||||
{
|
||||
GradientStop
|
||||
{
|
||||
position: 0.000
|
||||
color: Qt.rgba(0, 0, 0.5, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.25
|
||||
color: Qt.rgba(0, 0.375, 0.75, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.5
|
||||
color: Qt.rgba(0, 0.75, 0.5, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 0.75
|
||||
color: Qt.rgba(1, 0.75, 0.25, 1)
|
||||
}
|
||||
GradientStop
|
||||
{
|
||||
position: 1.0
|
||||
color: Qt.rgba(1, 1, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FontMetrics
|
||||
{
|
||||
id: fontMetrics
|
||||
font: UM.Theme.getFont("default")
|
||||
}
|
||||
}
|
|
@ -8,19 +8,21 @@ from . import SimulationViewProxy, SimulationView
|
|||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
"view": {
|
||||
"name": catalog.i18nc("@item:inlistbox", "Layer view"),
|
||||
"view_panel": "SimulationView.qml",
|
||||
"weight": 2
|
||||
"weight": 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def createSimulationViewProxy(engine, script_engine):
|
||||
return SimulationViewProxy.SimulationViewProxy()
|
||||
|
||||
|
||||
def register(app):
|
||||
simulation_view = SimulationView.SimulationView()
|
||||
qmlRegisterSingletonType(SimulationViewProxy.SimulationViewProxy, "UM", 1, 0, "SimulationView", simulation_view.getProxy)
|
||||
return { "view": SimulationView.SimulationView()}
|
||||
return { "view": simulation_view}
|
||||
|
|
|
@ -10,7 +10,8 @@ def getMetaData():
|
|||
return {
|
||||
"view": {
|
||||
"name": i18n_catalog.i18nc("@item:inmenu", "Solid view"),
|
||||
"weight": 0
|
||||
"weight": 0,
|
||||
"visible": False
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ Window
|
|||
maximumWidth: minimumWidth
|
||||
minimumHeight: height
|
||||
maximumHeight: minimumHeight
|
||||
color: UM.Theme.getColor("sidebar")
|
||||
color: UM.Theme.getColor("main_background")
|
||||
UM.I18nCatalog
|
||||
{
|
||||
id: catalog
|
||||
name:"cura"
|
||||
name: "cura"
|
||||
}
|
||||
Item
|
||||
{
|
||||
|
|
|
@ -36,12 +36,19 @@ Item
|
|||
var pg_name = "printingGuidelines"
|
||||
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
|
||||
}
|
||||
|
||||
property var materialWebsiteUrl:
|
||||
{
|
||||
var pg_name = "website"
|
||||
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
|
||||
}
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
height: visible ? childrenRect.height : 0
|
||||
|
||||
visible: packageData.type == "material" &&
|
||||
(packageData.has_configs || technicalDataSheetUrl !== undefined ||
|
||||
safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined)
|
||||
safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined ||
|
||||
materialWebsiteUrl !== undefined)
|
||||
|
||||
Item
|
||||
{
|
||||
|
@ -83,7 +90,7 @@ Item
|
|||
model: packageData.supported_configs
|
||||
headerDelegate: Rectangle
|
||||
{
|
||||
color: UM.Theme.getColor("sidebar")
|
||||
color: UM.Theme.getColor("main_background")
|
||||
height: UM.Theme.getSize("toolbox_chart_row").height
|
||||
Label
|
||||
{
|
||||
|
@ -180,7 +187,8 @@ Item
|
|||
anchors.top: combatibilityItem.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height / 2
|
||||
visible: base.technicalDataSheetUrl !== undefined ||
|
||||
base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined
|
||||
base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined ||
|
||||
base.materialWebsiteUrl !== undefined
|
||||
height: visible ? contentHeight : 0
|
||||
text:
|
||||
{
|
||||
|
@ -208,6 +216,16 @@ Item
|
|||
var pg_name = catalog.i18nc("@action:label", "Printing Guidelines")
|
||||
result += "<a href='%1'>%2</a>".arg(base.printingGuidelinesUrl).arg(pg_name)
|
||||
}
|
||||
if (base.materialWebsiteUrl !== undefined)
|
||||
{
|
||||
if (result.length > 0)
|
||||
{
|
||||
result += "<br/>"
|
||||
}
|
||||
var pg_name = catalog.i18nc("@action:label", "Website")
|
||||
result += "<a href='%1'>%2</a>".arg(base.materialWebsiteUrl).arg(pg_name)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
font: UM.Theme.getFont("very_small")
|
||||
|
|
|
@ -37,7 +37,7 @@ Item
|
|||
leftMargin: UM.Theme.getSize("wide_margin").width
|
||||
topMargin: UM.Theme.getSize("wide_margin").height
|
||||
}
|
||||
color: white //Always a white background for image (regardless of theme).
|
||||
color: "white" //Always a white background for image (regardless of theme).
|
||||
Image
|
||||
{
|
||||
anchors.fill: parent
|
||||
|
@ -144,10 +144,6 @@ Item
|
|||
{
|
||||
return ""
|
||||
}
|
||||
if (details.author_email)
|
||||
{
|
||||
return "<a href=\"mailto:" + details.author_email+"?Subject=Cura: " + details.name + "\">" + details.author_name + "</a>"
|
||||
}
|
||||
else
|
||||
{
|
||||
return "<a href=\"" + details.website + "\">" + details.author_name + "</a>"
|
||||
|
|
|
@ -37,7 +37,7 @@ Item
|
|||
anchors.top: packageName.bottom
|
||||
width: parent.width
|
||||
text: model.description
|
||||
maximumLineCount: 6
|
||||
maximumLineCount: 25
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.WordWrap
|
||||
color: UM.Theme.getColor("text")
|
||||
|
|
|
@ -19,10 +19,10 @@ Button
|
|||
Rectangle
|
||||
{
|
||||
visible: control.active
|
||||
color: UM.Theme.getColor("sidebar_header_highlight_hover")
|
||||
color: UM.Theme.getColor("toolbox_header_highlight_hover")
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("sidebar_header_highlight").height
|
||||
height: UM.Theme.getSize("toolbox_header_highlight").height
|
||||
}
|
||||
}
|
||||
label: Label
|
||||
|
@ -32,15 +32,15 @@ Button
|
|||
{
|
||||
if(control.hovered)
|
||||
{
|
||||
return UM.Theme.getColor("topbar_button_text_hovered");
|
||||
return UM.Theme.getColor("toolbox_header_button_text_hovered");
|
||||
}
|
||||
if(control.active)
|
||||
{
|
||||
return UM.Theme.getColor("topbar_button_text_active");
|
||||
return UM.Theme.getColor("toolbox_header_button_text_active");
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("topbar_button_text_inactive");
|
||||
return UM.Theme.getColor("toolbox_header_button_text_inactive");
|
||||
}
|
||||
}
|
||||
font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic")
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1,014 KiB |
BIN
plugins/UM3NetworkPrinting/resources/png/Ultimaker 3.png
Normal file
BIN
plugins/UM3NetworkPrinting/resources/png/Ultimaker 3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 774 KiB |
BIN
plugins/UM3NetworkPrinting/resources/png/Ultimaker S5.png
Normal file
BIN
plugins/UM3NetworkPrinting/resources/png/Ultimaker S5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
|
@ -9,10 +9,10 @@ import Cura 1.0 as Cura
|
|||
|
||||
Rectangle {
|
||||
property var iconSource: null;
|
||||
color: clickArea.containsMouse ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary"); // "Cura Blue"
|
||||
color: "#0a0850" // TODO: Theme!
|
||||
height: width;
|
||||
radius: Math.round(0.5 * width);
|
||||
width: 36 * screenScaleFactor;
|
||||
width: 24 * screenScaleFactor;
|
||||
|
||||
UM.RecolorImage {
|
||||
id: icon;
|
||||
|
|
|
@ -13,7 +13,7 @@ Component {
|
|||
property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width;
|
||||
property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width;
|
||||
anchors.fill: parent;
|
||||
color: UM.Theme.getColor("sidebar");
|
||||
color: UM.Theme.getColor("main_background");
|
||||
visible: OutputDevice != null;
|
||||
|
||||
UM.I18nCatalog {
|
||||
|
|
|
@ -10,14 +10,13 @@ import QtGraphicalEffects 1.0
|
|||
|
||||
Component
|
||||
{
|
||||
Rectangle
|
||||
Item
|
||||
{
|
||||
id: monitorFrame
|
||||
|
||||
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight")
|
||||
property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width
|
||||
|
||||
color: "transparent"
|
||||
height: maximumHeight
|
||||
onVisibleChanged:
|
||||
{
|
||||
|
@ -48,13 +47,45 @@ Component
|
|||
}
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: printers
|
||||
anchors
|
||||
{
|
||||
left: queue.left
|
||||
right: queue.right
|
||||
top: parent.top
|
||||
topMargin: 48 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
height: 264 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Row
|
||||
{
|
||||
spacing: 60 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: OutputDevice.printers
|
||||
|
||||
MonitorPrinterCard
|
||||
{
|
||||
printer: modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: queue
|
||||
width: Math.min(834 * screenScaleFactor, maximumWidth)
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 400 * screenScaleFactor // TODO: Insert carousel here
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: printers.bottom
|
||||
topMargin: 48 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
|
@ -104,7 +135,6 @@ Component
|
|||
text: catalog.i18nc("@label link to connect manager", "Manage queue in Cura Connect")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MouseArea
|
||||
{
|
||||
|
@ -187,7 +217,7 @@ Component
|
|||
}
|
||||
style: UM.Theme.styles.scrollview
|
||||
visible: OutputDevice.receivedPrintJobs
|
||||
width: Math.min(834 * screenScaleFactor, maximumWidth)
|
||||
width: parent.width
|
||||
|
||||
ListView
|
||||
{
|
||||
|
@ -214,5 +244,4 @@ Component
|
|||
visible: OutputDevice.activeCameraUrl != ""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ Cura.MachineAction
|
|||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
SystemPalette { id: palette }
|
||||
UM.I18nCatalog { id: catalog; name:"cura" }
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Controls.Styles 1.3
|
||||
import QtQuick.Controls 1.4
|
||||
import UM 1.3 as UM
|
||||
|
||||
/**
|
||||
* NOTE: For most labels, a fixed height with vertical alignment is used to make
|
||||
* layouts more deterministic (like the fixed-size textboxes used in original
|
||||
* mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted
|
||||
* with '// FIXED-LINE-HEIGHT:'.
|
||||
*/
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
property var printJob: null
|
||||
property var progress:
|
||||
{
|
||||
if (!printJob)
|
||||
{
|
||||
return 0
|
||||
}
|
||||
var result = printJob.timeElapsed / printJob.timeTotal
|
||||
if (result > 1.0)
|
||||
{
|
||||
result = 1.0
|
||||
}
|
||||
return result
|
||||
}
|
||||
property var remainingTime:
|
||||
{
|
||||
if (!printJob) {
|
||||
return 0
|
||||
}
|
||||
/* Sometimes total minus elapsed is less than 0. Use Math.max() to prevent remaining
|
||||
time from ever being less than 0. Negative durations cause strange behavior such
|
||||
as displaying "-1h -1m". */
|
||||
return Math.max(printer.activePrintJob.timeTotal - printer.activePrintJob.timeElapsed, 0)
|
||||
}
|
||||
property var progressText:
|
||||
{
|
||||
if (!printJob)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
switch (printJob.state)
|
||||
{
|
||||
case "wait_cleanup":
|
||||
if (printJob.timeTotal > printJob.timeElapsed)
|
||||
{
|
||||
return catalog.i18nc("@label:status", "Aborted")
|
||||
}
|
||||
return catalog.i18nc("@label:status", "Finished")
|
||||
case "pre_print":
|
||||
case "sent_to_printer":
|
||||
return catalog.i18nc("@label:status", "Preparing")
|
||||
case "aborted":
|
||||
return catalog.i18nc("@label:status", "Aborted")
|
||||
case "wait_user_action":
|
||||
return catalog.i18nc("@label:status", "Aborted")
|
||||
case "pausing":
|
||||
return catalog.i18nc("@label:status", "Pausing")
|
||||
case "paused":
|
||||
return OutputDevice.formatDuration( remainingTime )
|
||||
case "resuming":
|
||||
return catalog.i18nc("@label:status", "Resuming")
|
||||
case "queued":
|
||||
return catalog.i18nc("@label:status", "Action required")
|
||||
default:
|
||||
return OutputDevice.formatDuration( remainingTime )
|
||||
}
|
||||
}
|
||||
width: childrenRect.width
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
ProgressBar
|
||||
{
|
||||
id: progressBar
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
value: progress;
|
||||
style: ProgressBarStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
color: "#e4e4f2" // TODO: Theme!
|
||||
implicitHeight: visible ? 8 * screenScaleFactor : 0 // TODO: Theme!
|
||||
implicitWidth: 180 * screenScaleFactor // TODO: Theme!
|
||||
radius: 4 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
progress: Rectangle
|
||||
{
|
||||
id: progressItem;
|
||||
color:
|
||||
{
|
||||
if (printJob)
|
||||
{
|
||||
var state = printJob.state
|
||||
var inactiveStates = [
|
||||
"pausing",
|
||||
"paused",
|
||||
"resuming",
|
||||
"wait_cleanup"
|
||||
]
|
||||
if (inactiveStates.indexOf(state) > -1 && remainingTime > 0)
|
||||
{
|
||||
return UM.Theme.getColor("monitor_progress_fill_inactive")
|
||||
}
|
||||
}
|
||||
return "#0a0850" // TODO: Theme!
|
||||
}
|
||||
radius: 4 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: progressLabel
|
||||
anchors
|
||||
{
|
||||
left: progressBar.right
|
||||
leftMargin: 18 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
text: progressText
|
||||
color: "#374355" // TODO: Theme!
|
||||
width: contentWidth
|
||||
font: UM.Theme.getFont("medium") // 14pt, regular
|
||||
|
||||
// FIXED-LINE-HEIGHT:
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
242
plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml
Normal file
242
plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml
Normal file
|
@ -0,0 +1,242 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Controls 2.0
|
||||
import UM 1.3 as UM
|
||||
|
||||
/**
|
||||
* A Printer Card is has two main components: the printer portion and the print
|
||||
* job portion, the latter being paired in the UI when a print job is paired
|
||||
* a printer in-cluster.
|
||||
*
|
||||
* NOTE: For most labels, a fixed height with vertical alignment is used to make
|
||||
* layouts more deterministic (like the fixed-size textboxes used in original
|
||||
* mock-ups). This is also a stand-in for CSS's 'line-height' property. Denoted
|
||||
* with '// FIXED-LINE-HEIGHT:'.
|
||||
*/
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
// The printer which all printer data is derived from
|
||||
property var printer: null
|
||||
|
||||
property var borderSize: 1 * screenScaleFactor // TODO: Theme, and remove from here
|
||||
|
||||
width: 834 * screenScaleFactor // TODO: Theme!
|
||||
height: 216 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
// Printer portion
|
||||
Rectangle
|
||||
{
|
||||
id: printerInfo
|
||||
border
|
||||
{
|
||||
color: "#EAEAEC" // TODO: Theme!
|
||||
width: borderSize // TODO: Remove once themed
|
||||
}
|
||||
color: "white" // TODO: Theme!
|
||||
width: parent.width
|
||||
height: 144 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Row
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
leftMargin: 36 * screenScaleFactor // TODO: Theme!
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
spacing: 18 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Image
|
||||
{
|
||||
id: printerImage
|
||||
width: 108 * screenScaleFactor // TODO: Theme!
|
||||
height: 108 * screenScaleFactor // TODO: Theme!
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../png/" + printer.type + ".png"
|
||||
mipmap: true
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 216 * screenScaleFactor // TODO: Theme!
|
||||
height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Label
|
||||
{
|
||||
id: printerNameLabel
|
||||
text: printer && printer.name ? printer.name : ""
|
||||
color: "#414054" // TODO: Theme!
|
||||
elide: Text.ElideRight
|
||||
font: UM.Theme.getFont("large") // 16pt, bold
|
||||
width: parent.width
|
||||
|
||||
// FIXED-LINE-HEIGHT:
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
MonitorPrinterPill
|
||||
{
|
||||
id: printerFamilyPill
|
||||
anchors
|
||||
{
|
||||
top: printerNameLabel.bottom
|
||||
topMargin: 6 * screenScaleFactor // TODO: Theme!
|
||||
left: printerNameLabel.left
|
||||
}
|
||||
text: printer.type
|
||||
}
|
||||
}
|
||||
|
||||
MonitorPrinterConfiguration
|
||||
{
|
||||
id: printerConfiguration
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
buildplate: "Glass"
|
||||
configurations:
|
||||
[
|
||||
base.printer.printerConfiguration.extruderConfigurations[0],
|
||||
base.printer.printerConfiguration.extruderConfigurations[1]
|
||||
]
|
||||
height: 72 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
}
|
||||
|
||||
PrintJobContextMenu
|
||||
{
|
||||
id: contextButton
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
rightMargin: 12 * screenScaleFactor // TODO: Theme!
|
||||
top: parent.top
|
||||
topMargin: 12 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
printJob: printer.activePrintJob
|
||||
width: 36 * screenScaleFactor // TODO: Theme!
|
||||
height: 36 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
CameraButton
|
||||
{
|
||||
id: cameraButton;
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
rightMargin: 20 * screenScaleFactor // TODO: Theme!
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 20 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
iconSource: "../svg/icons/camera.svg"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Print job portion
|
||||
Rectangle
|
||||
{
|
||||
id: printJobInfo
|
||||
anchors
|
||||
{
|
||||
top: printerInfo.bottom
|
||||
topMargin: -borderSize * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
border
|
||||
{
|
||||
color: "#EAEAEC" // TODO: Theme!
|
||||
width: borderSize // TODO: Remove once themed
|
||||
}
|
||||
color: "white" // TODO: Theme!
|
||||
height: 84 * screenScaleFactor + borderSize // TODO: Remove once themed
|
||||
width: parent.width
|
||||
|
||||
Row
|
||||
{
|
||||
anchors
|
||||
{
|
||||
fill: parent
|
||||
topMargin: 12 * screenScaleFactor + borderSize // TODO: Theme!
|
||||
bottomMargin: 12 * screenScaleFactor // TODO: Theme!
|
||||
leftMargin: 36 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
height: childrenRect.height
|
||||
spacing: 18 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Item
|
||||
{
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: printerImage.width
|
||||
height: 60 * screenScaleFactor // TODO: Theme!
|
||||
MonitorPrintJobPreview
|
||||
{
|
||||
anchors.centerIn: parent
|
||||
printJob: base.printer.activePrintJob
|
||||
size: parent.height
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
width: 216 * screenScaleFactor // TODO: Theme!
|
||||
height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
Label
|
||||
{
|
||||
id: printerJobNameLabel
|
||||
text: base.printer.activePrintJob ? base.printer.activePrintJob.name : "Untitled" // TODO: I18N
|
||||
color: "#414054" // TODO: Theme!
|
||||
elide: Text.ElideRight
|
||||
font: UM.Theme.getFont("large") // 16pt, bold
|
||||
width: parent.width
|
||||
|
||||
// FIXED-LINE-HEIGHT:
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: printerJobOwnerLabel
|
||||
anchors
|
||||
{
|
||||
top: printerJobNameLabel.bottom
|
||||
topMargin: 6 * screenScaleFactor // TODO: Theme!
|
||||
left: printerJobNameLabel.left
|
||||
}
|
||||
text: printer.activePrintJob ? printer.activePrintJob.owner : "Anonymous" // TODO: I18N
|
||||
color: "#53657d" // TODO: Theme!
|
||||
elide: Text.ElideRight
|
||||
font: UM.Theme.getFont("very_small") // 12pt, regular
|
||||
width: parent.width
|
||||
|
||||
// FIXED-LINE-HEIGHT:
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MonitorPrintJobProgressBar
|
||||
{
|
||||
anchors
|
||||
{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
printJob: printer.activePrintJob
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ Item {
|
|||
}
|
||||
contentItem: Label {
|
||||
color: UM.Theme.getColor("monitor_context_menu_dots");
|
||||
font.pixelSize: 25 * screenScaleFactor;
|
||||
font.pixelSize: 32 * screenScaleFactor;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
text: button.text;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
@ -41,7 +41,7 @@ Item {
|
|||
var states = ["queued", "sent_to_printer", "pre_print", "printing", "pausing", "paused", "resuming"];
|
||||
return states.indexOf(printJob.state) !== -1;
|
||||
}
|
||||
width: 35 * screenScaleFactor; // TODO: Theme!
|
||||
width: 36 * screenScaleFactor; // TODO: Theme!
|
||||
}
|
||||
|
||||
Popup {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="12px" height="12px" viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M4.298828,0.998047 L7.7,0.998047 L8.7,3 L12,3 L12,10 L0,10 L0,3 L3.3,3 L4.298828,0.998047 Z M6,4 C4.625211,4 3.5,5.1252 3.5,6.5 C3.5,7.8748 4.625211,9 6,9 C7.37479,9 8.5,7.8748 8.5,6.5 C8.5,5.1252 7.37479,4 6,4 Z M6,5 C6.83435,5 7.5,5.6657 7.5,6.5 C7.5,7.3343 6.83435,8 6,8 C5.165651,8 4.5,7.3343 4.5,6.5 C4.5,5.6657 5.165651,5 6,5 Z" id="Combined-Shape" fill="#0A0850" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 658 B |
|
@ -65,7 +65,6 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
self._received_print_jobs = False # type: bool
|
||||
|
||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml")
|
||||
self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterControlItem.qml")
|
||||
|
||||
# See comments about this hack with the clusterPrintersChanged signal
|
||||
self.printersChanged.connect(self.clusterPrintersChanged)
|
||||
|
|
|
@ -344,7 +344,6 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
|
||||
# Request more data if info is not complete
|
||||
if not info.address:
|
||||
Logger.log("d", "Trying to get address of %s", name)
|
||||
info = zero_conf.get_service_info(service_type, name)
|
||||
|
||||
if info:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from UM.Job import Job
|
||||
from UM.Logger import Logger
|
||||
from plugins.USBPrinting.avr_isp import ispBase
|
||||
|
||||
from .avr_isp.stk500v2 import Stk500v2
|
||||
|
||||
|
@ -14,12 +15,12 @@ from serial import Serial, SerialException
|
|||
# It tries a pre-set list of baud rates. All these baud rates are validated by requesting the temperature a few times
|
||||
# and checking if the results make sense. If getResult() is not None, it was able to find a correct baud rate.
|
||||
class AutoDetectBaudJob(Job):
|
||||
def __init__(self, serial_port):
|
||||
def __init__(self, serial_port: int) -> None:
|
||||
super().__init__()
|
||||
self._serial_port = serial_port
|
||||
self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600]
|
||||
|
||||
def run(self):
|
||||
def run(self) -> None:
|
||||
Logger.log("d", "Auto detect baud rate started.")
|
||||
wait_response_timeouts = [3, 15, 30]
|
||||
wait_bootloader_times = [1.5, 5, 15]
|
||||
|
@ -32,7 +33,7 @@ class AutoDetectBaudJob(Job):
|
|||
try:
|
||||
programmer.connect(self._serial_port)
|
||||
serial = programmer.leaveISP()
|
||||
except:
|
||||
except ispBase.IspError:
|
||||
programmer.close()
|
||||
|
||||
for retry in range(tries):
|
||||
|
@ -58,7 +59,7 @@ class AutoDetectBaudJob(Job):
|
|||
# We already have a serial connection, just change the baud rate.
|
||||
try:
|
||||
serial.baudrate = baud_rate
|
||||
except:
|
||||
except ValueError:
|
||||
continue
|
||||
sleep(wait_bootloader) # Ensure that we are not talking to the boot loader. 1.5 seconds seems to be the magic number
|
||||
successful_responses = 0
|
||||
|
@ -81,5 +82,5 @@ class AutoDetectBaudJob(Job):
|
|||
return
|
||||
|
||||
serial.write(b"M105\n")
|
||||
sleep(15) # Give the printer some time to init and try again.
|
||||
sleep(15) # Give the printer some time to init and try again.
|
||||
self.setResult(None) # Unable to detect the correct baudrate.
|
||||
|
|
46
plugins/USBPrinting/MonitorItem.qml
Normal file
46
plugins/USBPrinting/MonitorItem.qml
Normal file
|
@ -0,0 +1,46 @@
|
|||
// 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.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
Component
|
||||
{
|
||||
Item
|
||||
{
|
||||
Rectangle
|
||||
{
|
||||
anchors.right: parent.right
|
||||
width: parent.width * 0.3
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
Cura.PrintMonitor
|
||||
{
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: footerSeparator
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("wide_lining").height
|
||||
color: UM.Theme.getColor("wide_lining")
|
||||
anchors.bottom: monitorButton.top
|
||||
anchors.bottomMargin: UM.Theme.getSize("thick_margin").height
|
||||
}
|
||||
|
||||
// MonitorButton is actually the bottom footer panel.
|
||||
Cura.MonitorButton
|
||||
{
|
||||
id: monitorButton
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.i18n import i18nCatalog
|
||||
|
@ -64,7 +65,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._accepts_commands = True
|
||||
|
||||
self._paused = False
|
||||
self._printer_busy = False # when printer is preheating and waiting (M190/M109), or when waiting for action on the printer
|
||||
self._printer_busy = False # When printer is preheating and waiting (M190/M109), or when waiting for action on the printer
|
||||
|
||||
self.setConnectionText(catalog.i18nc("@info:status", "Connected via USB"))
|
||||
|
||||
|
@ -77,6 +78,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._firmware_name_requested = False
|
||||
self._firmware_updater = AvrFirmwareUpdater(self)
|
||||
|
||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml")
|
||||
|
||||
CuraApplication.getInstance().getOnExitCallbackManager().addCallback(self._checkActivePrintingUponAppExit)
|
||||
|
||||
# This is a callback function that checks if there is any printing in progress via USB when the application tries
|
||||
|
|
|
@ -19,7 +19,7 @@ Cura.MachineAction
|
|||
property bool heatupBedStarted: false
|
||||
property bool printerConnected: Cura.MachineManager.printerConnected
|
||||
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
UM.I18nCatalog { id: catalog; name: "cura"}
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
|
|
|
@ -36,7 +36,7 @@ UM.Dialog
|
|||
width: parent.width
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
UM.I18nCatalog { id: catalog; name:"cura" }
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
Button
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue