This commit is contained in:
ChrisTerBeke 2017-12-08 09:52:06 +01:00
commit 7a6330fd08
20 changed files with 317 additions and 191 deletions

View File

@ -1,6 +1,5 @@
# Copyright (c) 2017 Ultimaker B.V. # Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtNetwork import QLocalServer from PyQt5.QtNetwork import QLocalServer
from PyQt5.QtNetwork import QLocalSocket from PyQt5.QtNetwork import QLocalSocket
@ -32,6 +31,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.SetTransformOperation import SetTransformOperation from UM.Operations.SetTransformOperation import SetTransformOperation
from cura.Arrange import Arrange from cura.Arrange import Arrange
from cura.ShapeArray import ShapeArray from cura.ShapeArray import ShapeArray
from cura.ConvexHullDecorator import ConvexHullDecorator from cura.ConvexHullDecorator import ConvexHullDecorator
@ -128,6 +128,7 @@ class CuraApplication(QtApplication):
stacksValidationFinished = pyqtSignal() # Emitted whenever a validation is finished stacksValidationFinished = pyqtSignal() # Emitted whenever a validation is finished
def __init__(self): def __init__(self):
# this list of dir names will be used by UM to detect an old cura directory # this list of dir names will be used by UM to detect an old cura directory
for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]: for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]:
Resources.addExpectedDirNameInData(dir_name) Resources.addExpectedDirNameInData(dir_name)
@ -156,7 +157,6 @@ class CuraApplication(QtApplication):
SettingDefinition.addSettingType("extruder", None, str, Validator) SettingDefinition.addSettingType("extruder", None, str, Validator)
SettingDefinition.addSettingType("optional_extruder", None, str, None) SettingDefinition.addSettingType("optional_extruder", None, str, None)
SettingDefinition.addSettingType("[int]", None, str, None) SettingDefinition.addSettingType("[int]", None, str, None)
SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues) SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
@ -181,7 +181,8 @@ class CuraApplication(QtApplication):
ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer)
## Initialise the version upgrade manager with Cura's storage paths. ## Initialise the version upgrade manager with Cura's storage paths.
import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies. # Needs to be here to prevent circular dependencies.
import UM.VersionUpgradeManager
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions( UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
{ {
@ -227,7 +228,9 @@ class CuraApplication(QtApplication):
"TranslateTool", "TranslateTool",
"FileLogger", "FileLogger",
"XmlMaterialProfile", "XmlMaterialProfile",
"PluginBrowser" "PluginBrowser",
"PrepareStage",
"MonitorStage"
]) ])
self._physics = None self._physics = None
self._volume = None self._volume = None
@ -388,7 +391,6 @@ class CuraApplication(QtApplication):
def needToShowUserAgreement(self): def needToShowUserAgreement(self):
return self._need_to_show_user_agreement return self._need_to_show_user_agreement
def setNeedToShowUserAgreement(self, set_value = True): def setNeedToShowUserAgreement(self, set_value = True):
self._need_to_show_user_agreement = set_value self._need_to_show_user_agreement = set_value
@ -666,14 +668,14 @@ class CuraApplication(QtApplication):
controller = self.getController() controller = self.getController()
controller.setActiveStage("PrepareStage")
controller.setActiveView("SolidView") controller.setActiveView("SolidView")
controller.setCameraTool("CameraTool") controller.setCameraTool("CameraTool")
controller.setSelectionTool("SelectionTool") controller.setSelectionTool("SelectionTool")
t = controller.getTool("TranslateTool") t = controller.getTool("TranslateTool")
if t: if t:
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis]) t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis, ToolHandle.ZAxis])
Selection.selectionChanged.connect(self.onSelectionChanged) Selection.selectionChanged.connect(self.onSelectionChanged)
@ -717,6 +719,7 @@ class CuraApplication(QtApplication):
run_headless = self.getCommandLineOption("headless", False) run_headless = self.getCommandLineOption("headless", False)
if not run_headless: if not run_headless:
self.initializeEngine() self.initializeEngine()
controller.setActiveStage("PrepareStage")
if run_headless or self._engine.rootObjects: if run_headless or self._engine.rootObjects:
self.closeSplash() self.closeSplash()

22
cura/Stages/CuraStage.py Normal file
View File

@ -0,0 +1,22 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, QUrl, QObject
from UM.Stage import Stage
class CuraStage(Stage):
def __init__(self, parent = None):
super().__init__(parent)
@pyqtProperty(str, constant = True)
def stageId(self):
return self.getPluginId()
@pyqtProperty(QUrl, constant = True)
def mainComponent(self):
return self.getDisplayComponent("main")
@pyqtProperty(QUrl, constant = True)
def sidebarComponent(self):
return self.getDisplayComponent("sidebar")

2
cura/Stages/__init__.py Normal file
View File

@ -0,0 +1,2 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.

View File

@ -22,9 +22,10 @@ if Platform.isLinux(): # Needed for platform.linux_distribution, which is not av
if Platform.isWindows() and hasattr(sys, "frozen"): if Platform.isWindows() and hasattr(sys, "frozen"):
try: try:
del os.environ["PYTHONPATH"] del os.environ["PYTHONPATH"]
except KeyError: pass except KeyError:
pass
#WORKAROUND: GITHUB-704 GITHUB-708 # WORKAROUND: GITHUB-704 GITHUB-708
# It looks like setuptools creates a .pth file in # It looks like setuptools creates a .pth file in
# the default /usr/lib which causes the default site-packages # the default /usr/lib which causes the default site-packages
# to be inserted into sys.path before PYTHONPATH. # to be inserted into sys.path before PYTHONPATH.
@ -45,6 +46,7 @@ def exceptHook(hook_type, value, traceback):
_crash_handler = CrashHandler(hook_type, value, traceback) _crash_handler = CrashHandler(hook_type, value, traceback)
_crash_handler.show() _crash_handler.show()
sys.excepthook = exceptHook sys.excepthook = exceptHook
# Workaround for a race condition on certain systems where there # Workaround for a race condition on certain systems where there
@ -75,7 +77,7 @@ faulthandler.enable()
# Force an instance of CuraContainerRegistry to be created and reused later. # Force an instance of CuraContainerRegistry to be created and reused later.
cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance() cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance()
# This prestart up check is needed to determine if we should start the application at all. # This pre-start up check is needed to determine if we should start the application at all.
if not cura.CuraApplication.CuraApplication.preStartUp(): if not cura.CuraApplication.CuraApplication.preStartUp():
sys.exit(0) sys.exit(0)

View File

@ -0,0 +1,39 @@
// 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
{
// 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
visible: monitorViewComponent.sourceComponent == null ? 1 : 0
MouseArea
{
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
}
Loader
{
id: monitorViewComponent
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
}
}

View File

@ -0,0 +1,73 @@
# Copyright (c) 2017 Ultimaker B.V.
# 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 monitoring a 3D printing while it's printing.
class MonitorStage(CuraStage):
def __init__(self, parent = None):
super().__init__(parent)
# Wait until QML engine is created, otherwise creating the new QML components will fail
Application.getInstance().engineCreatedSignal.connect(self._setComponents)
# Update the status icon when the output device is changed
Application.getInstance().getOutputDeviceManager().activeDeviceChanged.connect(self._setIconSource)
def _setComponents(self):
self._setMainOverlay()
self._setSidebar()
self._setIconSource()
def _setMainOverlay(self):
main_component_path = os.path.join(PluginRegistry.getInstance().getPluginPath("MonitorStage"), "MonitorMainView.qml")
self.addDisplayComponent("main", main_component_path)
def _setSidebar(self):
# TODO: currently the sidebar component for prepare and monitor stages is the same, this will change with the printer output device refactor!
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml")
self.addDisplayComponent("sidebar", sidebar_component_path)
def _setIconSource(self):
if Application.getInstance().getTheme() is not None:
icon_name = self._getActiveOutputDeviceStatusIcon()
self.setIconSource(Application.getInstance().getTheme().getIcon(icon_name))
## Find the correct status icon depending on the active output device state
def _getActiveOutputDeviceStatusIcon(self):
output_device = Application.getInstance().getOutputDeviceManager().getActiveDevice()
if not output_device:
return "tab_status_unknown"
if hasattr(output_device, "acceptsCommands") and not output_device.acceptsCommands:
return "tab_status_unknown"
if not hasattr(output_device, "printerState") or not hasattr(output_device, "jobState"):
return "tab_status_unknown"
# TODO: refactor to use enum instead of hardcoded strings?
if output_device.printerState == "maintenance":
return "tab_status_busy"
if output_device.jobState in ["printing", "pre_print", "pausing", "resuming"]:
return "tab_status_busy"
if output_device.jobState == "wait_cleanup":
return "tab_status_finished"
if output_device.jobState in ["ready", ""]:
return "tab_status_connected"
if output_device.jobState == "paused":
return "tab_status_paused"
if output_device.jobState == "error":
return "tab_status_stopped"
return "tab_status_unknown"

View File

@ -0,0 +1,20 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
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
}
}
def register(app):
return {
"stage": MonitorStage.MonitorStage()
}

View File

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

View File

@ -0,0 +1,18 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os.path
from UM.Application import Application
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)
def _engineCreated(self):
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml")
self.addDisplayComponent("sidebar", sidebar_component_path)

View File

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

View File

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

View File

@ -698,7 +698,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
if self._reply: if self._reply:
self._reply.abort() self._reply.abort()
self._stage = OutputStage.ready self._stage = OutputStage.ready
Application.getInstance().showPrintMonitor.emit(False) Application.getInstance().getController().setActiveStage("PrepareStage")
@pyqtSlot(int, result=str) @pyqtSlot(int, result=str)
def formatDuration(self, seconds): def formatDuration(self, seconds):

View File

@ -672,7 +672,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
Logger.log("d", "Attempting to perform an action without authentication for printer %s. Auth state is %s", self._key, self._authentication_state) Logger.log("d", "Attempting to perform an action without authentication for printer %s. Auth state is %s", self._key, self._authentication_state)
return return
Application.getInstance().showPrintMonitor.emit(True) Application.getInstance().getController().setActiveStage("MonitorStage")
self._print_finished = True self._print_finished = True
self.writeStarted.emit(self) self.writeStarted.emit(self)
self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list") self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list")
@ -767,7 +767,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if button == QMessageBox.Yes: if button == QMessageBox.Yes:
self.startPrint() self.startPrint()
else: else:
Application.getInstance().showPrintMonitor.emit(False) Application.getInstance().getController().setActiveStage("PrepareStage")
# For some unknown reason Cura on OSX will hang if we do the call back code # For some unknown reason Cura on OSX will hang if we do the call back code
# immediately without first returning and leaving QML's event system. # immediately without first returning and leaving QML's event system.
QTimer.singleShot(100, delayedCallback) QTimer.singleShot(100, delayedCallback)
@ -850,7 +850,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
self._write_finished = True # post_reply does not always exist, so make sure we unblock writing self._write_finished = True # post_reply does not always exist, so make sure we unblock writing
if self._post_reply: if self._post_reply:
self._finalizePostReply() self._finalizePostReply()
Application.getInstance().showPrintMonitor.emit(False) Application.getInstance().getController().setActiveStage("PrepareStage")
## Attempt to start a new print. ## Attempt to start a new print.
# This function can fail to actually start a print due to not being authenticated or another print already # This function can fail to actually start a print due to not being authenticated or another print already

View File

@ -490,7 +490,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self.setJobName(file_name) self.setJobName(file_name)
self._print_estimated_time = int(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.Seconds)) self._print_estimated_time = int(Application.getInstance().getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.Seconds))
Application.getInstance().showPrintMonitor.emit(True) Application.getInstance().getController().setActiveStage("MonitorStage")
self.startPrint() self.startPrint()
def _setEndstopState(self, endstop_key, value): def _setEndstopState(self, endstop_key, value):
@ -698,7 +698,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._is_printing = False self._is_printing = False
self._is_paused = False self._is_paused = False
self._updateJobState("ready") self._updateJobState("ready")
Application.getInstance().showPrintMonitor.emit(False) Application.getInstance().getController().setActiveStage("PrepareStage")
## Check if the process did not encounter an error yet. ## Check if the process did not encounter an error yet.
def hasError(self): def hasError(self):

View File

@ -20,14 +20,16 @@ UM.MainWindow
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
property bool showPrintMonitor: false property bool showPrintMonitor: false
// This connection is here to support legacy printer output devices that use the showPrintMonitor signal on Application to switch to the monitor stage
// It should be phased out in newer plugin versions.
Connections Connections
{ {
target: Printer target: Printer
onShowPrintMonitor: { onShowPrintMonitor: {
if (show) { if (show) {
topbar.startMonitoringPrint() UM.Controller.setActiveStage("MonitorStage")
} else { } else {
topbar.stopMonitoringPrint() UM.Controller.setActiveStage("PrepareStage")
} }
} }
} }
@ -331,7 +333,7 @@ UM.MainWindow
text: catalog.i18nc("@action:button","Open File"); text: catalog.i18nc("@action:button","Open File");
iconSource: UM.Theme.getIcon("load") iconSource: UM.Theme.getIcon("load")
style: UM.Theme.styles.tool_button style: UM.Theme.styles.tool_button
tooltip: ''; tooltip: ""
anchors anchors
{ {
top: topbar.bottom; top: topbar.bottom;
@ -358,62 +360,49 @@ UM.MainWindow
Topbar Topbar
{ {
id: topbar id: topbar
anchors.left:parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
monitoringPrint: base.showPrintMonitor
onStartMonitoringPrint: base.showPrintMonitor = true
onStopMonitoringPrint: base.showPrintMonitor = false
}
Sidebar
{
id: sidebar;
anchors
{
top: topbar.bottom;
bottom: parent.bottom;
right: parent.right;
}
z: 1
width: UM.Theme.getSize("sidebar").width;
monitoringPrint: base.showPrintMonitor
}
Rectangle
{
id: viewportOverlay
color: UM.Theme.getColor("viewport_overlay")
anchors
{
top: topbar.bottom
bottom: parent.bottom
left:parent.left
right: sidebar.left
}
visible: opacity > 0
opacity: base.showPrintMonitor ? 1 : 0
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
} }
Loader Loader
{ {
sourceComponent: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].monitorItem: null id: sidebar
visible: base.showPrintMonitor
anchors.horizontalCenter: parent.horizontalCenter anchors
anchors.verticalCenter: parent.verticalCenter {
anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2 top: topbar.bottom
anchors.verticalCenterOffset: UM.Theme.getSize("sidebar_header").height / 2 bottom: parent.bottom
property real maximumWidth: viewportOverlay.width right: parent.right
property real maximumHeight: viewportOverlay.height }
width: UM.Theme.getSize("sidebar").width
z: 1
source: UM.Controller.activeStage.sidebarComponent
}
Loader
{
id: main
anchors
{
top: topbar.bottom
bottom: parent.bottom
left: parent.left
right: sidebar.left
}
MouseArea
{
visible: UM.Controller.activeStage.mainComponent != ""
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
source: UM.Controller.activeStage.mainComponent
} }
UM.MessageStack UM.MessageStack

View File

@ -12,21 +12,23 @@ Menu
title: catalog.i18nc("@title:menu menubar:toplevel", "&View"); title: catalog.i18nc("@title:menu menubar:toplevel", "&View");
id: menu id: menu
enabled: !PrintInformation.preSliced enabled: !PrintInformation.preSliced
// main views
Instantiator Instantiator
{ {
model: UM.ViewModel { } model: UM.ViewModel{}
MenuItem MenuItem
{ {
text: model.name; text: model.name
checkable: true; checkable: true
checked: model.active; checked: model.active
exclusiveGroup: group; exclusiveGroup: group
onTriggered: UM.Controller.setActiveView(model.id); onTriggered: UM.Controller.setActiveView(model.id)
} }
onObjectAdded: menu.insertItem(index, object) onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object) onObjectRemoved: menu.removeItem(object)
} }
ExclusiveGroup { id: group; } ExclusiveGroup { id: group }
MenuSeparator {} MenuSeparator {}
MenuItem { action: Cura.Actions.homeCamera; } MenuItem { action: Cura.Actions.homeCamera; }

View File

@ -46,7 +46,7 @@ Item {
} }
function sliceOrStopSlicing() { function sliceOrStopSlicing() {
if ([1, 5].indexOf(UM.Backend.state) != -1) { if (backend != "undefined" && [1, 5].indexOf(UM.Backend.state) != -1) {
backend.forceSlice(); backend.forceSlice();
} else { } else {
backend.stopSlicing(); backend.stopSlicing();

View File

@ -24,7 +24,7 @@ Rectangle
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
property int backendState: UM.Backend.state property int backendState: UM.Backend.state
property bool monitoringPrint: false property bool monitoringPrint: UM.Controller.activeStage.stageId == "MonitorStage"
property variant printDuration: PrintInformation.currentPrintTime property variant printDuration: PrintInformation.currentPrintTime
property variant printMaterialLengths: PrintInformation.materialLengths property variant printMaterialLengths: PrintInformation.materialLengths
@ -263,7 +263,7 @@ Rectangle
{ {
id: controlItem id: controlItem
anchors.bottom: footerSeparator.top anchors.bottom: footerSeparator.top
anchors.top: headerSeparator.bottom anchors.top: monitoringPrint ? base.top : headerSeparator.bottom
anchors.left: base.left anchors.left: base.left
anchors.right: base.right anchors.right: base.right
sourceComponent: sourceComponent:
@ -282,7 +282,7 @@ Rectangle
Loader Loader
{ {
anchors.bottom: footerSeparator.top anchors.bottom: footerSeparator.top
anchors.top: headerSeparator.bottom anchors.top: monitoringPrint ? base.top : headerSeparator.bottom
anchors.left: base.left anchors.left: base.left
anchors.right: base.right anchors.right: base.right
source: source:

View File

@ -403,8 +403,6 @@ Item
} }
} }
// //
// Infill // Infill
// //
@ -568,18 +566,20 @@ Item
model: infillModel model: infillModel
anchors.fill: parent anchors.fill: parent
property int activeIndex: { function activeIndex () {
for (var i = 0; i < infillModel.count; i++) { for (var i = 0; i < infillModel.count; i++) {
var density = parseInt(infillDensity.properties.value) var density = parseInt(infillDensity.properties.value)
var steps = parseInt(infillSteps.properties.value) var steps = parseInt(infillSteps.properties.value)
var infillModelItem = infillModel.get(i) var infillModelItem = infillModel.get(i)
if (density >= infillModelItem.percentageMin if (infillModelItem != "undefined"
&& density >= infillModelItem.percentageMin
&& density <= infillModelItem.percentageMax && density <= infillModelItem.percentageMax
&& steps >= infillModelItem.stepsMin && steps >= infillModelItem.stepsMin
&& steps <= infillModelItem.stepsMax){ && steps <= infillModelItem.stepsMax
return i ){
} return i
}
} }
return -1 return -1
} }
@ -587,7 +587,7 @@ Item
Rectangle Rectangle
{ {
anchors.fill: parent anchors.fill: parent
visible: infillIconList.activeIndex == index visible: infillIconList.activeIndex() == index
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("quality_slider_unavailable") border.color: UM.Theme.getColor("quality_slider_unavailable")

View File

@ -6,7 +6,7 @@ import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import UM 1.2 as UM import UM 1.4 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
import "Menus" import "Menus"
@ -16,27 +16,10 @@ Rectangle
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
height: UM.Theme.getSize("sidebar_header").height height: UM.Theme.getSize("sidebar_header").height
color: base.monitoringPrint ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color") color: UM.Controller.activeStage.stageId == "MonitorStage" ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color")
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property bool monitoringPrint: false
// outgoing signal
signal startMonitoringPrint()
signal stopMonitoringPrint()
// update monitoring status when event was triggered outside topbar
Component.onCompleted: {
startMonitoringPrint.connect(function () {
base.monitoringPrint = true
UM.Controller.disableModelRendering()
})
stopMonitoringPrint.connect(function () {
base.monitoringPrint = false
UM.Controller.enableModelRendering()
})
}
UM.I18nCatalog UM.I18nCatalog
{ {
@ -67,92 +50,30 @@ Rectangle
anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.rightMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width
Button // The topbar is dynamically filled with all available stages
Repeater
{ {
id: showSettings id: stagesMenu
height: UM.Theme.getSize("sidebar_header").height
text: catalog.i18nc("@title:tab", "Prepare")
checkable: true
checked: isChecked()
exclusiveGroup: sidebarHeaderBarGroup
style: UM.Theme.styles.topbar_header_tab
// We use a Qt.binding to re-bind the checkbox state after manually setting it model: UM.StageModel{}
// https://stackoverflow.com/questions/38798450/qt-5-7-qml-why-are-my-checkbox-property-bindings-disappearing
onClicked: {
base.stopMonitoringPrint()
checked = Qt.binding(isChecked)
}
function isChecked () { delegate: Button
return !base.monitoringPrint
}
property color overlayColor: "transparent"
property string overlayIconSource: ""
}
Button
{
id: showMonitor
width: UM.Theme.getSize("topbar_button").width
height: UM.Theme.getSize("sidebar_header").height
text: catalog.i18nc("@title:tab", "Monitor")
checkable: true
checked: isChecked()
exclusiveGroup: sidebarHeaderBarGroup
style: UM.Theme.styles.topbar_header_tab_no_overlay
// We use a Qt.binding to re-bind the checkbox state after manually setting it
// https://stackoverflow.com/questions/38798450/qt-5-7-qml-why-are-my-checkbox-property-bindings-disappearing
onClicked: {
base.startMonitoringPrint()
checked = Qt.binding(isChecked)
}
function isChecked () {
return base.monitoringPrint
}
property string iconSource:
{ {
if (!printerConnected) text: model.name
{ checkable: true
return UM.Theme.getIcon("tab_status_unknown"); checked: model.active
} exclusiveGroup: topbarMenuGroup
else if (!printerAcceptsCommands) style: (model.stage.iconSource != "") ? UM.Theme.styles.topbar_header_tab_no_overlay : UM.Theme.styles.topbar_header_tab
{ height: UM.Theme.getSize("sidebar_header").height
return UM.Theme.getIcon("tab_status_unknown"); onClicked: UM.Controller.setActiveStage(model.id)
} iconSource: model.stage.iconSource
if (Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance") property color overlayColor: "transparent"
{ property string overlayIconSource: ""
return UM.Theme.getIcon("tab_status_busy");
}
switch (Cura.MachineManager.printerOutputDevices[0].jobState)
{
case "printing":
case "pre_print":
case "pausing":
case "resuming":
return UM.Theme.getIcon("tab_status_busy");
case "wait_cleanup":
return UM.Theme.getIcon("tab_status_finished");
case "ready":
case "":
return UM.Theme.getIcon("tab_status_connected")
case "paused":
return UM.Theme.getIcon("tab_status_paused")
case "error":
return UM.Theme.getIcon("tab_status_stopped")
default:
return UM.Theme.getIcon("tab_status_unknown")
}
} }
} }
ExclusiveGroup { id: sidebarHeaderBarGroup } ExclusiveGroup { id: topbarMenuGroup }
} }
ToolButton ToolButton
@ -220,17 +141,16 @@ Rectangle
menu: PrinterMenu { } menu: PrinterMenu { }
} }
//View orientation Item // View orientation Item
Row Row
{ {
id: viewOrientationControl id: viewOrientationControl
height: 30 height: 30
spacing: 2 spacing: 2
visible: UM.Controller.activeStage.stageId != "MonitorStage"
visible: !base.monitoringPrint anchors
{
anchors {
verticalCenter: base.verticalCenter verticalCenter: base.verticalCenter
right: viewModeButton.right right: viewModeButton.right
rightMargin: UM.Theme.getSize("default_margin").width + viewModeButton.width rightMargin: UM.Theme.getSize("default_margin").width + viewModeButton.width
@ -308,7 +228,7 @@ Rectangle
} }
style: UM.Theme.styles.combobox style: UM.Theme.styles.combobox
visible: !base.monitoringPrint visible: UM.Controller.activeStage.stageId != "MonitorStage"
model: UM.ViewModel { } model: UM.ViewModel { }
textRole: "name" textRole: "name"