Merge branch 'ui_rework_4_0' into cura4.0_header

Conflicts:
plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml
resources/qml/Menus/ViewMenu.qml
resources/themes/cura-dark/theme.json
resources/themes/cura-light/theme.json
This commit is contained in:
Diego Prado Gesto 2018-10-29 11:10:25 +01:00
commit 5de367bcc4
107 changed files with 15797 additions and 14749 deletions

View file

@ -1,46 +1,40 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.3
import QtQuick.Controls 2.0 as Controls2
import QtGraphicalEffects 1.0
import UM 1.3 as UM
import Cura 1.0 as Cura
Rectangle
{
property var iconSource: null
Rectangle {
property var iconSource: null;
color: clickArea.containsMouse ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary"); // "Cura Blue"
height: width;
radius: Math.round(0.5 * width);
width: 36 * screenScaleFactor;
width: 36 * screenScaleFactor
height: width
radius: 0.5 * width
color: clickArea.containsMouse ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary")
UM.RecolorImage
{
id: icon
width: parent.width / 2
height: width
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: UM.Theme.getColor("primary_text")
source: iconSource
UM.RecolorImage {
id: icon;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
color: UM.Theme.getColor("primary_text");
height: width;
source: iconSource;
width: Math.round(parent.width / 2);
}
MouseArea
{
id: clickArea
anchors.fill:parent
hoverEnabled: true
onClicked:
{
if (OutputDevice.activeCamera !== null)
{
MouseArea {
id: clickArea;
anchors.fill: parent;
hoverEnabled: true;
onClicked: {
if (OutputDevice.activeCamera !== null) {
OutputDevice.setActiveCamera(null)
}
else
{
OutputDevice.setActiveCamera(modelData.camera)
} else {
OutputDevice.setActiveCamera(modelData.camera);
}
}
}

View file

@ -1,803 +1,109 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Dialogs 1.1
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls 2.0 as Controls2
import UM 1.3 as UM
import Cura 1.0 as Cura
Component {
Rectangle {
id: base;
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");
visible: OutputDevice != null;
Component
{
Rectangle
{
id: base
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
property var shadowRadius: 5 * screenScaleFactor
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
visible: OutputDevice != null
anchors.fill: parent
color: "white"
UM.I18nCatalog
{
id: catalog
name: "cura"
UM.I18nCatalog {
id: catalog;
name: "cura";
}
Label
{
id: printingLabel
font: UM.Theme.getFont("large")
anchors
{
margins: 2 * UM.Theme.getSize("default_margin").width
leftMargin: 4 * UM.Theme.getSize("default_margin").width
top: parent.top
left: parent.left
right: parent.right
Label {
id: printingLabel;
anchors {
left: parent.left;
leftMargin: 4 * UM.Theme.getSize("default_margin").width;
margins: 2 * UM.Theme.getSize("default_margin").width;
right: parent.right;
top: parent.top;
}
text: catalog.i18nc("@label", "Printing")
elide: Text.ElideRight
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("large");
text: catalog.i18nc("@label", "Printing");
}
Label
{
id: managePrintersLabel
anchors.rightMargin: 4 * UM.Theme.getSize("default_margin").width
anchors.right: printerScrollView.right
anchors.bottom: printingLabel.bottom
text: catalog.i18nc("@label link to connect manager", "Manage printers")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("primary")
linkColor: UM.Theme.getColor("primary")
}
MouseArea
{
anchors.fill: managePrintersLabel
hoverEnabled: true
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel()
onEntered: managePrintersLabel.font.underline = true
onExited: managePrintersLabel.font.underline = false
}
ScrollView
{
id: printerScrollView
anchors
{
top: printingLabel.bottom
left: parent.left
right: parent.right
topMargin: UM.Theme.getSize("default_margin").height
bottom: parent.bottom
bottomMargin: UM.Theme.getSize("default_margin").height
Label {
id: managePrintersLabel;
anchors {
bottom: printingLabel.bottom;
right: printerScrollView.right;
rightMargin: 4 * UM.Theme.getSize("default_margin").width;
}
color: UM.Theme.getColor("primary"); // "Cura Blue"
font: UM.Theme.getFont("default");
linkColor: UM.Theme.getColor("primary"); // "Cura Blue"
text: catalog.i18nc("@label link to connect manager", "Manage printers");
}
style: UM.Theme.styles.scrollview
MouseArea {
anchors.fill: managePrintersLabel;
hoverEnabled: true;
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel();
onEntered: managePrintersLabel.font.underline = true;
onExited: managePrintersLabel.font.underline = false;
}
ListView
{
id: printer_list
property var current_index: -1
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.right
leftMargin: 2 * UM.Theme.getSize("default_margin").width
rightMargin: 2 * UM.Theme.getSize("default_margin").width
// Skeleton loading
Column {
id: skeletonLoader;
anchors {
left: parent.left;
leftMargin: UM.Theme.getSize("wide_margin").width;
right: parent.right;
rightMargin: UM.Theme.getSize("wide_margin").width;
top: printingLabel.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
}
spacing: UM.Theme.getSize("default_margin").height - 10;
visible: printerList.count === 0;
PrinterCard {
printer: null;
}
PrinterCard {
printer: null;
}
}
// Actual content
ScrollView {
id: printerScrollView;
anchors {
bottom: parent.bottom;
left: parent.left;
right: parent.right;
top: printingLabel.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
}
style: UM.Theme.styles.scrollview;
ListView {
id: printerList;
property var currentIndex: -1;
anchors {
fill: parent;
leftMargin: UM.Theme.getSize("wide_margin").width;
rightMargin: UM.Theme.getSize("wide_margin").width;
}
spacing: UM.Theme.getSize("default_margin").height -10
model: OutputDevice.printers
delegate: Item
{
width: parent.width
height: base.height + 2 * base.shadowRadius // To ensure that the shadow doesn't get cut off.
Rectangle
{
width: parent.width - 2 * shadowRadius
height: childrenRect.height + UM.Theme.getSize("default_margin").height
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color:
{
if(modelData.state == "disabled")
{
return UM.Theme.getColor("monitor_background_inactive")
}
else
{
return UM.Theme.getColor("monitor_background_active")
}
}
id: base
property var shadowRadius: 5 * screenScaleFactor
property var collapsed: true
layer.enabled: true
layer.effect: DropShadow
{
radius: 5 * screenScaleFactor
verticalOffset: 2
color: "#3F000000" // 25% shadow
}
Connections
{
target: printer_list
onCurrent_indexChanged: { base.collapsed = printer_list.current_index != model.index }
}
Item
{
id: printerInfo
height: machineIcon.height
anchors
{
top: parent.top
left: parent.left
right: parent.right
margins: UM.Theme.getSize("default_margin").width
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (base.collapsed) {
printer_list.current_index = model.index
}
else
{
printer_list.current_index = -1
}
}
}
Item
{
id: machineIcon
// Yeah, this is hardcoded now, but I can't think of a good way to fix this.
// The UI is going to get another update soon, so it's probably not worth the effort...
width: 58
height: 58
anchors.top: parent.top
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.left: parent.left
UM.RecolorImage
{
anchors.centerIn: parent
source:
{
switch(modelData.type)
{
case "Ultimaker 3":
return "../svg/UM3-icon.svg"
case "Ultimaker 3 Extended":
return "../svg/UM3x-icon.svg"
case "Ultimaker S5":
return "../svg/UMs5-icon.svg"
}
}
width: sourceSize.width
height: sourceSize.height
color:
{
if(modelData.state == "disabled")
{
return UM.Theme.getColor("monitor_text_inactive")
}
if(modelData.activePrintJob != undefined)
{
return UM.Theme.getColor("primary")
}
return UM.Theme.getColor("monitor_text_inactive")
}
}
}
Item
{
height: childrenRect.height
anchors
{
right: collapseIcon.left
rightMargin: UM.Theme.getSize("default_margin").width
left: machineIcon.right
leftMargin: UM.Theme.getSize("default_margin").width
verticalCenter: machineIcon.verticalCenter
}
Label
{
id: machineNameLabel
text: modelData.name
width: parent.width
elide: Text.ElideRight
font: UM.Theme.getFont("default_bold")
}
Label
{
id: activeJobLabel
text:
{
if (modelData.state == "disabled")
{
return catalog.i18nc("@label", "Not available")
} else if (modelData.state == "unreachable")
{
return catalog.i18nc("@label", "Unreachable")
}
if (modelData.activePrintJob != null)
{
return modelData.activePrintJob.name
}
return catalog.i18nc("@label", "Available")
}
anchors.top: machineNameLabel.bottom
width: parent.width
elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("monitor_text_inactive")
}
}
UM.RecolorImage
{
id: collapseIcon
width: 15
height: 15
sourceSize.width: width
sourceSize.height: height
source: base.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
color: "black"
}
}
Item
{
id: detailedInfo
property var printJob: modelData.activePrintJob
visible: height == childrenRect.height
anchors.top: printerInfo.bottom
width: parent.width
height: !base.collapsed ? childrenRect.height : 0
opacity: visible ? 1 : 0
Behavior on height { NumberAnimation { duration: 100 } }
Behavior on opacity { NumberAnimation { duration: 100 } }
Rectangle
{
id: topSpacer
color:
{
if(modelData.state == "disabled")
{
return UM.Theme.getColor("monitor_lining_inactive")
}
return UM.Theme.getColor("viewport_background")
}
// UM.Theme.getColor("viewport_background")
height: 1
anchors
{
left: parent.left
right: parent.right
margins: UM.Theme.getSize("default_margin").width
top: parent.top
topMargin: UM.Theme.getSize("default_margin").width
}
}
PrinterFamilyPill
{
id: printerFamilyPill
color:
{
if(modelData.state == "disabled")
{
return "transparent"
}
return UM.Theme.getColor("viewport_background")
}
anchors.top: topSpacer.bottom
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
text: modelData.type
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
padding: 3
}
Row
{
id: extrudersInfo
anchors.top: printerFamilyPill.bottom
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.leftMargin: 2 * UM.Theme.getSize("default_margin").width
anchors.right: parent.right
anchors.rightMargin: 2 * UM.Theme.getSize("default_margin").width
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
PrintCoreConfiguration
{
id: leftExtruderInfo
width: Math.round(parent.width / 2)
printCoreConfiguration: modelData.printerConfiguration.extruderConfigurations[0]
}
PrintCoreConfiguration
{
id: rightExtruderInfo
width: Math.round(parent.width / 2)
printCoreConfiguration: modelData.printerConfiguration.extruderConfigurations[1]
}
}
Rectangle
{
id: jobSpacer
color: UM.Theme.getColor("viewport_background")
height: 2
anchors
{
left: parent.left
right: parent.right
margins: UM.Theme.getSize("default_margin").width
top: extrudersInfo.bottom
topMargin: 2 * UM.Theme.getSize("default_margin").height
}
}
Item
{
id: jobInfo
property var showJobInfo: modelData.activePrintJob != null && modelData.activePrintJob.state != "queued"
anchors.top: jobSpacer.bottom
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: UM.Theme.getSize("default_margin").width
anchors.leftMargin: 2 * UM.Theme.getSize("default_margin").width
height: showJobInfo ? childrenRect.height + 2 * UM.Theme.getSize("default_margin").height: 0
visible: showJobInfo
Label
{
id: printJobName
text: modelData.activePrintJob != null ? modelData.activePrintJob.name : ""
font: UM.Theme.getFont("default_bold")
anchors.left: parent.left
anchors.right: contextButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
elide: Text.ElideRight
}
Label
{
id: ownerName
anchors.top: printJobName.bottom
text: modelData.activePrintJob != null ? modelData.activePrintJob.owner : ""
font: UM.Theme.getFont("default")
opacity: 0.6
width: parent.width
elide: Text.ElideRight
}
function switchPopupState()
{
popup.visible ? popup.close() : popup.open()
}
Controls2.Button
{
id: contextButton
text: "\u22EE" //Unicode; Three stacked points.
width: 35
height: width
anchors
{
right: parent.right
top: parent.top
}
hoverEnabled: true
background: Rectangle
{
opacity: contextButton.down || contextButton.hovered ? 1 : 0
width: contextButton.width
height: contextButton.height
radius: 0.5 * width
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: contextButton.text
color: UM.Theme.getColor("monitor_text_inactive")
font.pixelSize: 25
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
onClicked: parent.switchPopupState()
}
Controls2.Popup
{
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
id: popup
clip: true
closePolicy: Popup.CloseOnPressOutside
x: (parent.width - width) + 26 * screenScaleFactor
y: contextButton.height - 5 * screenScaleFactor // Because shadow
width: 182 * screenScaleFactor
height: contentItem.height + 2 * padding
visible: false
padding: 5 * screenScaleFactor // Because shadow
transformOrigin: Popup.Top
contentItem: Item
{
width: popup.width
height: childrenRect.height + 36 * screenScaleFactor
anchors.topMargin: 10 * screenScaleFactor
anchors.bottomMargin: 10 * screenScaleFactor
Controls2.Button
{
id: pauseButton
text: modelData.activePrintJob != null && modelData.activePrintJob.state == "paused" ? catalog.i18nc("@label", "Resume") : catalog.i18nc("@label", "Pause")
onClicked:
{
if(modelData.activePrintJob.state == "paused")
{
modelData.activePrintJob.setState("print")
}
else if(modelData.activePrintJob.state == "printing")
{
modelData.activePrintJob.setState("pause")
}
popup.close()
}
width: parent.width
enabled: modelData.activePrintJob != null && ["paused", "printing"].indexOf(modelData.activePrintJob.state) >= 0
visible: enabled
anchors.top: parent.top
anchors.topMargin: 18 * screenScaleFactor
height: visible ? 39 * screenScaleFactor : 0 * screenScaleFactor
hoverEnabled: true
background: Rectangle
{
opacity: pauseButton.down || pauseButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: pauseButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
Controls2.Button
{
id: abortButton
text: catalog.i18nc("@label", "Abort")
onClicked:
{
abortConfirmationDialog.visible = true;
popup.close();
}
width: parent.width
height: 39 * screenScaleFactor
anchors.top: pauseButton.bottom
hoverEnabled: true
enabled: modelData.activePrintJob != null && ["paused", "printing", "pre_print"].indexOf(modelData.activePrintJob.state) >= 0
background: Rectangle
{
opacity: abortButton.down || abortButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: abortButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
MessageDialog
{
id: abortConfirmationDialog
title: catalog.i18nc("@window:title", "Abort print")
icon: StandardIcon.Warning
text: catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to abort %1?").arg(modelData.activePrintJob.name)
standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false
onYes: modelData.activePrintJob.setState("abort")
}
}
background: Item
{
width: popup.width
height: popup.height
DropShadow
{
anchors.fill: pointedRectangle
radius: 5
color: "#3F000000" // 25% shadow
source: pointedRectangle
transparentBorder: true
verticalOffset: 2
}
Item
{
id: pointedRectangle
width: parent.width - 10 * screenScaleFactor // Because of the shadow
height: parent.height - 10 * screenScaleFactor // Because of the shadow
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle
{
id: point
height: 14 * screenScaleFactor
width: 14 * screenScaleFactor
color: UM.Theme.getColor("setting_control")
transform: Rotation { angle: 45}
anchors.right: bloop.right
anchors.rightMargin: 24
y: 1
}
Rectangle
{
id: bloop
color: UM.Theme.getColor("setting_control")
width: parent.width
anchors.top: parent.top
anchors.topMargin: 8 * screenScaleFactor // Because of the shadow + point
anchors.bottom: parent.bottom
anchors.bottomMargin: 8 * screenScaleFactor // Because of the shadow
}
}
}
exit: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
enter: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
onClosed: visible = false
onOpened: visible = true
}
Image
{
id: printJobPreview
source: modelData.activePrintJob != null ? modelData.activePrintJob.previewImageUrl : ""
anchors.top: ownerName.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width / 2
height: width
opacity:
{
if(modelData.activePrintJob == null)
{
return 1.0
}
switch(modelData.activePrintJob.state)
{
case "wait_cleanup":
case "wait_user_action":
case "paused":
return 0.5
default:
return 1.0
}
}
}
UM.RecolorImage
{
id: statusImage
anchors.centerIn: printJobPreview
source:
{
if(modelData.activePrintJob == null)
{
return ""
}
switch(modelData.activePrintJob.state)
{
case "paused":
return "../svg/paused-icon.svg"
case "wait_cleanup":
if(modelData.activePrintJob.timeElapsed < modelData.activePrintJob.timeTotal)
{
return "../svg/aborted-icon.svg"
}
return "../svg/approved-icon.svg"
case "wait_user_action":
return "../svg/aborted-icon.svg"
default:
return ""
}
}
visible: source != ""
width: 0.5 * printJobPreview.width
height: 0.5 * printJobPreview.height
sourceSize.width: width
sourceSize.height: height
color: "black"
}
CameraButton
{
id: showCameraButton
iconSource: "../svg/camera-icon.svg"
anchors
{
left: parent.left
bottom: printJobPreview.bottom
}
}
}
}
ProgressBar
{
property var progress:
{
if(modelData.activePrintJob == null)
{
return 0
}
var result = modelData.activePrintJob.timeElapsed / modelData.activePrintJob.timeTotal
if(result > 1.0)
{
result = 1.0
}
return result
}
id: jobProgressBar
width: parent.width
value: progress
anchors.top: detailedInfo.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
visible: modelData.activePrintJob != null && modelData.activePrintJob != undefined
style: ProgressBarStyle
{
property var remainingTime:
{
if(modelData.activePrintJob == null)
{
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". */
var activeJob = modelData.activePrintJob
return Math.max(activeJob.timeTotal - activeJob.timeElapsed, 0);
}
property var progressText:
{
if(modelData.activePrintJob == null)
{
return ""
}
switch(modelData.activePrintJob.state)
{
case "wait_cleanup":
if(modelData.activePrintJob.timeTotal > modelData.activePrintJob.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 )
}
}
background: Rectangle
{
implicitWidth: 100
implicitHeight: visible ? 24 : 0
color: UM.Theme.getColor("viewport_background")
}
progress: Rectangle
{
color:
{
var state = modelData.activePrintJob.state
var inactiveStates = [
"pausing",
"paused",
"resuming",
"wait_cleanup"
]
if(inactiveStates.indexOf(state) > -1 && remainingTime > 0)
{
return UM.Theme.getColor("monitor_text_inactive")
}
else
{
return UM.Theme.getColor("primary")
}
}
id: progressItem
function getTextOffset()
{
if(progressItem.width + progressLabel.width + 16 < control.width)
{
return progressItem.width + UM.Theme.getSize("default_margin").width
}
else
{
return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width
}
}
Label
{
id: progressLabel
anchors.left: parent.left
anchors.leftMargin: getTextOffset()
text: progressText
anchors.verticalCenter: parent.verticalCenter
color: progressItem.width + progressLabel.width < control.width ? "black" : "white"
width: contentWidth
font: UM.Theme.getFont("default")
}
}
}
}
}
delegate: PrinterCard {
printer: modelData;
}
model: OutputDevice.printers;
spacing: UM.Theme.getSize("default_margin").height - 10;
}
}
}

View file

@ -1,108 +1,132 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.3 as UM
import Cura 1.0 as Cura
Component
{
Rectangle
{
id: monitorFrame
width: maximumWidth
height: maximumHeight
color: UM.Theme.getColor("viewport_background")
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight")
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Label
{
id: manageQueueLabel
anchors.rightMargin: 3 * UM.Theme.getSize("default_margin").width
anchors.right: queuedPrintJobs.right
anchors.bottom: queuedLabel.bottom
text: catalog.i18nc("@label link to connect manager", "Manage queue")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("primary")
linkColor: UM.Theme.getColor("primary")
}
MouseArea
{
anchors.fill: manageQueueLabel
hoverEnabled: true
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
onEntered: manageQueueLabel.font.underline = true
onExited: manageQueueLabel.font.underline = false
}
Label
{
id: queuedLabel
anchors.left: queuedPrintJobs.left
anchors.top: parent.top
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
anchors.leftMargin: 3 * UM.Theme.getSize("default_margin").width + 5
text: catalog.i18nc("@label", "Queued")
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
}
ScrollView
{
id: queuedPrintJobs
anchors
{
top: queuedLabel.bottom
topMargin: UM.Theme.getSize("default_margin").height
horizontalCenter: parent.horizontalCenter
bottomMargin: 0
bottom: parent.bottom
Component {
Rectangle {
id: monitorFrame;
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight");
property var cornerRadius: UM.Theme.getSize("monitor_corner_radius").width;
color: UM.Theme.getColor("viewport_background");
height: maximumHeight;
onVisibleChanged: {
if (monitorFrame != null && !monitorFrame.visible) {
OutputDevice.setActiveCamera(null);
}
style: UM.Theme.styles.scrollview
width: Math.min(800 * screenScaleFactor, maximumWidth)
ListView
{
anchors.fill: parent
//anchors.margins: UM.Theme.getSize("default_margin").height
spacing: UM.Theme.getSize("default_margin").height - 10 // 2x the shadow radius
}
width: maximumWidth;
model: OutputDevice.queuedPrintJobs
UM.I18nCatalog {
id: catalog;
name: "cura";
}
delegate: PrintJobInfoBlock
{
printJob: modelData
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").height
anchors.leftMargin: UM.Theme.getSize("default_margin").height
height: 175 * screenScaleFactor
Label {
id: manageQueueLabel;
anchors {
bottom: queuedLabel.bottom;
right: queuedPrintJobs.right;
rightMargin: 3 * UM.Theme.getSize("default_margin").width;
}
color: UM.Theme.getColor("primary");
font: UM.Theme.getFont("default");
linkColor: UM.Theme.getColor("primary");
text: catalog.i18nc("@label link to connect manager", "Manage queue");
}
MouseArea {
anchors.fill: manageQueueLabel;
hoverEnabled: true;
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel();
onEntered: manageQueueLabel.font.underline = true;
onExited: manageQueueLabel.font.underline = false;
}
Label {
id: queuedLabel;
anchors {
left: queuedPrintJobs.left;
leftMargin: 3 * UM.Theme.getSize("default_margin").width + 5 * screenScaleFactor;
top: parent.top;
topMargin: 2 * UM.Theme.getSize("default_margin").height;
}
color: UM.Theme.getColor("text");
font: UM.Theme.getFont("large");
text: catalog.i18nc("@label", "Queued");
}
Column {
id: skeletonLoader;
anchors {
bottom: parent.bottom;
bottomMargin: UM.Theme.getSize("default_margin").height;
horizontalCenter: parent.horizontalCenter;
top: queuedLabel.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
}
visible: !queuedPrintJobs.visible;
width: Math.min(800 * screenScaleFactor, maximumWidth);
PrintJobInfoBlock {
anchors {
left: parent.left;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
}
printJob: null; // Use as skeleton
}
PrintJobInfoBlock {
anchors {
left: parent.left;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
}
printJob: null; // Use as skeleton
}
}
PrinterVideoStream
{
visible: OutputDevice.activeCamera != null
anchors.fill: parent
camera: OutputDevice.activeCamera
ScrollView {
id: queuedPrintJobs;
anchors {
top: queuedLabel.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
horizontalCenter: parent.horizontalCenter;
bottomMargin: UM.Theme.getSize("default_margin").height;
bottom: parent.bottom;
}
style: UM.Theme.styles.scrollview;
visible: OutputDevice.receivedPrintJobs;
width: Math.min(800 * screenScaleFactor, maximumWidth);
ListView {
id: printJobList;
anchors.fill: parent;
delegate: PrintJobInfoBlock {
anchors {
left: parent.left;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
}
printJob: modelData;
}
model: OutputDevice.queuedPrintJobs;
spacing: UM.Theme.getSize("default_margin").height - 2 * UM.Theme.getSize("monitor_shadow_radius").width;
}
}
onVisibleChanged:
{
if (monitorFrame != null && !monitorFrame.visible)
{
OutputDevice.setActiveCamera(null)
}
PrinterVideoStream {
anchors.fill: parent;
camera: OutputDevice.activeCamera;
visible: OutputDevice.activeCamera != null;
}
}
}

View file

@ -1,3 +1,6 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import UM 1.2 as UM
import Cura 1.0 as Cura

View file

@ -0,0 +1,12 @@
// 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
Rectangle {
color: UM.Theme.getColor("monitor_lining_light"); // TODO: Maybe theme separately? Maybe not.
height: UM.Theme.getSize("default_lining").height;
width: parent.width;
}

View file

@ -1,53 +1,51 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import UM 1.3 as UM
import Cura 1.0 as Cura
Component
{
Item
{
width: maximumWidth
height: maximumHeight
Image
{
id: cameraImage
width: Math.min(sourceSize.width === 0 ? 800 * screenScaleFactor : sourceSize.width, maximumWidth)
height: Math.floor((sourceSize.height === 0 ? 600 * screenScaleFactor : sourceSize.height) * width / sourceSize.width)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
z: 1
Component.onCompleted:
{
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null)
{
OutputDevice.activePrinter.camera.start()
Component {
Item {
height: maximumHeight;
width: maximumWidth;
Cura.CameraView {
id: cameraImage;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
Component.onCompleted: {
if (OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null) {
OutputDevice.activePrinter.camera.start();
}
}
onVisibleChanged:
{
if(visible)
{
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null)
{
OutputDevice.activePrinter.camera.start()
height: Math.floor((imageHeight === 0 ? 600 * screenScaleFactor : imageHeight) * width / imageWidth);
onVisibleChanged: {
if (visible) {
if (OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null) {
OutputDevice.activePrinter.camera.start();
}
} else
{
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null)
{
OutputDevice.activePrinter.camera.stop()
} else {
if (OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null) {
OutputDevice.activePrinter.camera.stop();
}
}
}
source:
width: Math.min(imageWidth === 0 ? 800 * screenScaleFactor : imageWidth, maximumWidth);
z: 1;
Connections
{
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null && OutputDevice.activePrinter.camera.latestImage)
target: OutputDevice.activePrinter.camera;
onNewImage:
{
return OutputDevice.activePrinter.camera.latestImage;
if (cameraImage.visible) {
cameraImage.image = OutputDevice.activePrinter.camera.latestImage;
cameraImage.update();
}
}
return "";
}
}
}

View file

@ -1,93 +1,121 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.2 as UM
Item {
id: extruderInfo;
property var printCoreConfiguration: null;
height: childrenRect.height;
width: Math.round(parent.width / 2);
Item
{
id: extruderInfo
property var printCoreConfiguration
// Extruder circle
Item {
id: extruderCircle;
height: UM.Theme.getSize("monitor_extruder_circle").height;
width: UM.Theme.getSize("monitor_extruder_circle").width;
width: Math.round(parent.width / 2)
height: childrenRect.height
// Loading skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill");
radius: Math.round(width / 2);
visible: !printCoreConfiguration;
}
Item
{
id: extruderCircle
width: 30
height: 30
anchors.verticalCenter: printAndMaterialLabel.verticalCenter
opacity:
{
if(printCoreConfiguration == null || printCoreConfiguration.activeMaterial == null || printCoreConfiguration.hotendID == null)
{
return 0.5
// Actual content
Rectangle {
anchors.fill: parent;
border.width: UM.Theme.getSize("monitor_thick_lining").width;
border.color: UM.Theme.getColor("monitor_lining_heavy");
color: "transparent";
opacity: {
if (printCoreConfiguration == null || printCoreConfiguration.activeMaterial == null || printCoreConfiguration.hotendID == null) {
return 0.5;
}
return 1;
}
return 1
}
radius: Math.round(width / 2);
visible: printCoreConfiguration;
Rectangle
{
anchors.fill: parent
radius: Math.round(width / 2)
border.width: 2
border.color: "black"
}
Label
{
anchors.centerIn: parent
font: UM.Theme.getFont("default_bold")
text: printCoreConfiguration.position + 1
Label {
anchors.centerIn: parent;
color: UM.Theme.getColor("text");
font: UM.Theme.getFont("default_bold");
text: printCoreConfiguration ? printCoreConfiguration.position + 1 : 0;
}
}
}
Item
{
id: printAndMaterialLabel
anchors
{
right: parent.right
left: extruderCircle.right
margins: UM.Theme.getSize("default_margin").width
// Print core and material labels
Item {
id: materialLabel
anchors {
left: extruderCircle.right;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
top: parent.top;
}
height: childrenRect.height
height: UM.Theme.getSize("monitor_text_line").height;
Label
{
id: materialLabel
text:
{
if(printCoreConfiguration != undefined && printCoreConfiguration.activeMaterial != undefined)
{
return printCoreConfiguration.activeMaterial.name
}
return ""
}
font: UM.Theme.getFont("default")
elide: Text.ElideRight
width: parent.width
// Loading skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill");
visible: !extruderInfo.printCoreConfiguration;
}
Label
{
id: printCoreLabel
text:
{
if(printCoreConfiguration != undefined && printCoreConfiguration.hotendID != undefined)
{
return printCoreConfiguration.hotendID
// Actual content
Label {
anchors.fill: parent;
elide: Text.ElideRight;
color: UM.Theme.getColor("text");
font: UM.Theme.getFont("default");
text: {
if (printCoreConfiguration && printCoreConfiguration.activeMaterial != undefined) {
return printCoreConfiguration.activeMaterial.name;
}
return ""
return "";
}
anchors.top: materialLabel.bottom
elide: Text.ElideRight
width: parent.width
opacity: 0.6
font: UM.Theme.getFont("default")
visible: extruderInfo.printCoreConfiguration;
}
}
Item {
id: printCoreLabel;
anchors {
left: extruderCircle.right;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
top: materialLabel.bottom;
topMargin: Math.floor(UM.Theme.getSize("default_margin").height/4);
}
height: UM.Theme.getSize("monitor_text_line").height;
// Loading skeleton
Rectangle {
color: UM.Theme.getColor("monitor_skeleton_fill");
height: parent.height;
visible: !extruderInfo.printCoreConfiguration;
width: Math.round(parent.width / 3);
}
// Actual content
Label {
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default");
opacity: 0.6;
text: {
if (printCoreConfiguration != undefined && printCoreConfiguration.hotendID != undefined) {
return printCoreConfiguration.hotendID;
}
return "";
}
visible: extruderInfo.printCoreConfiguration;
}
}
}

View 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.2
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.1
import QtGraphicalEffects 1.0
import UM 1.3 as UM
Item {
id: root;
property var printJob: null;
property var running: isRunning(printJob);
Button {
id: button;
background: Rectangle {
color: UM.Theme.getColor("viewport_background"); // TODO: Theme!
height: button.height;
opacity: button.down || button.hovered ? 1 : 0;
radius: Math.round(0.5 * width);
width: button.width;
}
contentItem: Label {
color: UM.Theme.getColor("monitor_context_menu_dots");
font.pixelSize: 25 * screenScaleFactor;
horizontalAlignment: Text.AlignHCenter;
text: button.text;
verticalAlignment: Text.AlignVCenter;
}
height: width;
hoverEnabled: true;
onClicked: parent.switchPopupState();
text: "\u22EE"; //Unicode; Three stacked points.
width: 35 * screenScaleFactor; // TODO: Theme!
}
Popup {
id: popup;
background: Item {
anchors.fill: parent;
DropShadow {
anchors.fill: pointedRectangle;
color: UM.Theme.getColor("monitor_shadow");
radius: UM.Theme.getSize("monitor_shadow_radius").width;
source: pointedRectangle;
transparentBorder: true;
verticalOffset: 2 * screenScaleFactor;
}
Item {
id: pointedRectangle;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
height: parent.height - 10 * screenScaleFactor; // Because of the shadow
width: parent.width - 10 * screenScaleFactor; // Because of the shadow
Rectangle {
id: point;
anchors {
right: bloop.right;
rightMargin: 24 * screenScaleFactor;
}
color: UM.Theme.getColor("monitor_context_menu_background");
height: 14 * screenScaleFactor;
transform: Rotation {
angle: 45;
}
width: 14 * screenScaleFactor;
y: 1 * screenScaleFactor;
}
Rectangle {
id: bloop;
anchors {
bottom: parent.bottom;
bottomMargin: 8 * screenScaleFactor; // Because of the shadow
top: parent.top;
topMargin: 8 * screenScaleFactor; // Because of the shadow + point
}
color: UM.Theme.getColor("monitor_context_menu_background");
width: parent.width;
}
}
}
clip: true;
closePolicy: Popup.CloseOnPressOutside;
contentItem: Column {
id: popupOptions;
anchors {
top: parent.top;
topMargin: UM.Theme.getSize("default_margin").height + 10 * screenScaleFactor; // Account for the point of the box
}
height: childrenRect.height + spacing * popupOptions.children.length + UM.Theme.getSize("default_margin").height;
spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2);
width: parent.width;
PrintJobContextMenuItem {
enabled: {
if (printJob && !running) {
if (OutputDevice && OutputDevice.queuedPrintJobs[0]) {
return OutputDevice.queuedPrintJobs[0].key != printJob.key;
}
}
return false;
}
onClicked: {
sendToTopConfirmationDialog.visible = true;
popup.close();
}
text: catalog.i18nc("@label", "Move to top");
}
PrintJobContextMenuItem {
enabled: printJob && !running;
onClicked: {
deleteConfirmationDialog.visible = true;
popup.close();
}
text: catalog.i18nc("@label", "Delete");
}
PrintJobContextMenuItem {
enabled: printJob && running;
onClicked: {
if (printJob.state == "paused") {
printJob.setState("print");
} else if(printJob.state == "printing") {
printJob.setState("pause");
}
popup.close();
}
text: printJob && printJob.state == "paused" ? catalog.i18nc("@label", "Resume") : catalog.i18nc("@label", "Pause");
}
PrintJobContextMenuItem {
enabled: printJob && running;
onClicked: {
abortConfirmationDialog.visible = true;
popup.close();
}
text: catalog.i18nc("@label", "Abort");
}
}
enter: Transition {
NumberAnimation {
duration: 75;
property: "visible";
}
}
exit: Transition {
NumberAnimation {
duration: 75;
property: "visible";
}
}
height: contentItem.height + 2 * padding;
onClosed: visible = false;
onOpened: visible = true;
padding: UM.Theme.getSize("monitor_shadow_radius").width;
transformOrigin: Popup.Top;
visible: false;
width: 182 * screenScaleFactor;
x: (button.width - width) + 26 * screenScaleFactor;
y: button.height + 5 * screenScaleFactor; // Because shadow
}
MessageDialog {
id: sendToTopConfirmationDialog;
Component.onCompleted: visible = false;
icon: StandardIcon.Warning;
onYes: OutputDevice.sendJobToTop(printJob.key);
standardButtons: StandardButton.Yes | StandardButton.No;
text: printJob && printJob.name ? catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to move %1 to the top of the queue?").arg(printJob.name) : "";
title: catalog.i18nc("@window:title", "Move print job to top");
}
MessageDialog {
id: deleteConfirmationDialog;
Component.onCompleted: visible = false;
icon: StandardIcon.Warning;
onYes: OutputDevice.deleteJobFromQueue(printJob.key);
standardButtons: StandardButton.Yes | StandardButton.No;
text: printJob && printJob.name ? catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to delete %1?").arg(printJob.name) : "";
title: catalog.i18nc("@window:title", "Delete print job");
}
MessageDialog {
id: abortConfirmationDialog;
Component.onCompleted: visible = false;
icon: StandardIcon.Warning;
onYes: printJob.setState("abort");
standardButtons: StandardButton.Yes | StandardButton.No;
text: printJob && printJob.name ? catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to abort %1?").arg(printJob.name) : "";
title: catalog.i18nc("@window:title", "Abort print");
}
// Utils
function switchPopupState() {
popup.visible ? popup.close() : popup.open();
}
function isRunning(job) {
if (!job) {
return false;
}
return ["paused", "printing", "pre_print"].indexOf(job.state) !== -1;
}
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import UM 1.3 as UM
Button {
background: Rectangle {
opacity: parent.down || parent.hovered ? 1 : 0;
color: UM.Theme.getColor("monitor_context_menu_highlight");
}
contentItem: Label {
color: UM.Theme.getColor("text");
text: parent.text
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
}
height: 39 * screenScaleFactor; // TODO: Theme!
hoverEnabled: true;
visible: enabled;
width: parent.width;
}

View file

@ -1,429 +1,476 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Dialogs 1.1
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import UM 1.3 as UM
Item {
id: root;
property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width;
property var shadowOffset: 2 * screenScaleFactor;
property var debug: false;
property var printJob: null;
width: parent.width; // Bubbles downward
height: childrenRect.height + shadowRadius * 2; // Bubbles upward
Item
{
id: base
property var printJob: null
property var shadowRadius: 5 * screenScaleFactor
function getPrettyTime(time)
{
return OutputDevice.formatDuration(time)
UM.I18nCatalog {
id: catalog;
name: "cura";
}
width: parent.width
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Rectangle
{
id: background
anchors
{
top: parent.top
topMargin: 3 * screenScaleFactor
left: parent.left
leftMargin: base.shadowRadius
rightMargin: base.shadowRadius
right: parent.right
bottom: parent.bottom
bottomMargin: base.shadowRadius
// The actual card (white block)
Rectangle {
// 5px margin, but shifted 2px vertically because of the shadow
anchors {
bottomMargin: root.shadowRadius + root.shadowOffset;
leftMargin: root.shadowRadius;
rightMargin: root.shadowRadius;
topMargin: root.shadowRadius - root.shadowOffset;
}
color: UM.Theme.getColor("monitor_card_background");
height: childrenRect.height;
layer.enabled: true
layer.effect: DropShadow
{
radius: base.shadowRadius
layer.effect: DropShadow {
radius: root.shadowRadius
verticalOffset: 2 * screenScaleFactor
color: "#3F000000" // 25% shadow
color: "#3F000000" // 25% shadow
}
width: parent.width - shadowRadius * 2;
Item
{
// Content on the left of the infobox
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.left
right: parent.horizontalCenter
margins: UM.Theme.getSize("wide_margin").width
rightMargin: UM.Theme.getSize("default_margin").width
}
Column {
height: childrenRect.height;
width: parent.width;
Label
{
id: printJobName
text: printJob.name
font: UM.Theme.getFont("default_bold")
width: parent.width
elide: Text.ElideRight
}
// Main content
Item {
id: mainContent;
height: 200 * screenScaleFactor; // TODO: Theme!
width: parent.width;
Label
{
id: ownerName
anchors.top: printJobName.bottom
text: printJob.owner
font: UM.Theme.getFont("default")
opacity: 0.6
width: parent.width
elide: Text.ElideRight
}
Image
{
id: printJobPreview
source: printJob.previewImageUrl
anchors.top: ownerName.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: totalTimeLabel.bottom
width: height
opacity: printJob.state == "error" ? 0.5 : 1.0
}
UM.RecolorImage
{
id: statusImage
anchors.centerIn: printJobPreview
source: printJob.state == "error" ? "../svg/aborted-icon.svg" : ""
visible: source != ""
width: 0.5 * printJobPreview.width
height: 0.5 * printJobPreview.height
sourceSize.width: width
sourceSize.height: height
color: "black"
}
Label
{
id: totalTimeLabel
anchors.bottom: parent.bottom
anchors.right: parent.right
font: UM.Theme.getFont("default")
text: printJob != null ? getPrettyTime(printJob.timeTotal) : ""
elide: Text.ElideRight
}
}
Item
{
// Content on the right side of the infobox.
anchors
{
top: parent.top
bottom: parent.bottom
left: parent.horizontalCenter
right: parent.right
margins: 2 * UM.Theme.getSize("default_margin").width
leftMargin: UM.Theme.getSize("default_margin").width
rightMargin: UM.Theme.getSize("default_margin").width / 2
}
Label
{
id: targetPrinterLabel
elide: Text.ElideRight
font: UM.Theme.getFont("default_bold")
text:
{
if(printJob.assignedPrinter == null)
{
if(printJob.state == "error")
{
return catalog.i18nc("@label", "Waiting for: Unavailable printer")
}
return catalog.i18nc("@label", "Waiting for: First available")
}
else
{
return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name
// Left content
Item {
anchors {
bottom: parent.bottom;
left: parent.left;
margins: UM.Theme.getSize("wide_margin").width;
right: parent.horizontalCenter;
top: parent.top;
}
}
Item {
id: printJobName;
width: parent.width;
height: UM.Theme.getSize("monitor_text_line").height;
anchors
{
left: parent.left
right: contextButton.left
rightMargin: UM.Theme.getSize("default_margin").width
}
}
function switchPopupState()
{
popup.visible ? popup.close() : popup.open()
}
Button
{
id: contextButton
text: "\u22EE" //Unicode; Three stacked points.
width: 35
height: width
anchors
{
right: parent.right
top: parent.top
}
hoverEnabled: true
background: Rectangle
{
opacity: contextButton.down || contextButton.hovered ? 1 : 0
width: contextButton.width
height: contextButton.height
radius: 0.5 * width
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: contextButton.text
color: UM.Theme.getColor("monitor_text_inactive")
font.pixelSize: 25
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
onClicked: parent.switchPopupState()
}
Popup
{
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
id: popup
clip: true
closePolicy: Popup.CloseOnPressOutside
x: (parent.width - width) + 26 * screenScaleFactor
y: contextButton.height - 5 * screenScaleFactor // Because shadow
width: 182 * screenScaleFactor
height: contentItem.height + 2 * padding
visible: false
padding: 5 * screenScaleFactor // Because shadow
transformOrigin: Popup.Top
contentItem: Item
{
width: popup.width
height: childrenRect.height + 36 * screenScaleFactor
anchors.topMargin: 10 * screenScaleFactor
anchors.bottomMargin: 10 * screenScaleFactor
Button
{
id: sendToTopButton
text: catalog.i18nc("@label", "Move to top")
onClicked:
{
sendToTopConfirmationDialog.visible = true;
popup.close();
Rectangle {
color: UM.Theme.getColor("monitor_skeleton_fill");
height: parent.height;
visible: !printJob;
width: Math.round(parent.width / 3);
}
width: parent.width
enabled: OutputDevice.queuedPrintJobs[0].key != printJob.key
visible: enabled
anchors.top: parent.top
anchors.topMargin: 18 * screenScaleFactor
height: visible ? 39 * screenScaleFactor : 0 * screenScaleFactor
hoverEnabled: true
background: Rectangle
{
opacity: sendToTopButton.down || sendToTopButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: sendToTopButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
Label {
anchors.fill: parent;
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default_bold");
text: printJob && printJob.name ? printJob.name : ""; // Supress QML warnings
visible: printJob;
}
}
MessageDialog
{
id: sendToTopConfirmationDialog
title: catalog.i18nc("@window:title", "Move print job to top")
icon: StandardIcon.Warning
text: catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to move %1 to the top of the queue?").arg(printJob.name)
standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false
onYes: OutputDevice.sendJobToTop(printJob.key)
}
Item {
id: printJobOwnerName;
anchors {
top: printJobName.bottom;
topMargin: Math.floor(UM.Theme.getSize("default_margin").height / 2);
}
height: UM.Theme.getSize("monitor_text_line").height;
width: parent.width;
Button
{
id: deleteButton
text: catalog.i18nc("@label", "Delete")
onClicked:
{
deleteConfirmationDialog.visible = true;
popup.close();
Rectangle {
color: UM.Theme.getColor("monitor_skeleton_fill");
height: parent.height;
visible: !printJob;
width: Math.round(parent.width / 2);
}
width: parent.width
height: 39 * screenScaleFactor
anchors.top: sendToTopButton.bottom
hoverEnabled: true
background: Rectangle
{
opacity: deleteButton.down || deleteButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
contentItem: Label
{
text: deleteButton.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
Label {
anchors.fill: parent;
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default");
text: printJob ? printJob.owner : ""; // Supress QML warnings
visible: printJob;
}
}
MessageDialog
{
id: deleteConfirmationDialog
title: catalog.i18nc("@window:title", "Delete print job")
icon: StandardIcon.Warning
text: catalog.i18nc("@label %1 is the name of a print job.", "Are you sure you want to delete %1?").arg(printJob.name)
standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false
onYes: OutputDevice.deleteJobFromQueue(printJob.key)
}
}
Item {
id: printJobPreview;
property var useUltibot: false;
anchors {
bottom: parent.bottom;
horizontalCenter: parent.horizontalCenter;
top: printJobOwnerName.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
}
width: height;
background: Item
{
width: popup.width
height: popup.height
DropShadow
{
anchors.fill: pointedRectangle
radius: 5
color: "#3F000000" // 25% shadow
source: pointedRectangle
transparentBorder: true
verticalOffset: 2
}
Item
{
id: pointedRectangle
width: parent.width - 10 * screenScaleFactor // Because of the shadow
height: parent.height - 10 * screenScaleFactor // Because of the shadow
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle
{
id: point
height: 14 * screenScaleFactor
width: 14 * screenScaleFactor
color: UM.Theme.getColor("setting_control")
transform: Rotation { angle: 45}
anchors.right: bloop.right
anchors.rightMargin: 24
y: 1
// Skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill");
radius: UM.Theme.getSize("default_margin").width;
visible: !printJob;
}
Rectangle
{
id: bloop
color: UM.Theme.getColor("setting_control")
width: parent.width
anchors.top: parent.top
anchors.topMargin: 8 * screenScaleFactor // Because of the shadow + point
anchors.bottom: parent.bottom
anchors.bottomMargin: 8 * screenScaleFactor // Because of the shadow
// Actual content
Image {
id: previewImage;
anchors.fill: parent;
opacity: printJob && printJob.state == "error" ? 0.5 : 1.0;
source: printJob ? printJob.previewImageUrl : "";
visible: printJob;
}
UM.RecolorImage {
id: ultiBotImage;
anchors.centerIn: printJobPreview;
color: UM.Theme.getColor("monitor_placeholder_image");
height: printJobPreview.height;
source: "../svg/ultibot.svg";
sourceSize {
height: height;
width: width;
}
/* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or
not in order to determine if we show the placeholder (ultibot) image instead. */
visible: printJob && previewImage.status == Image.Error;
width: printJobPreview.width;
}
UM.RecolorImage {
id: statusImage;
anchors.centerIn: printJobPreview;
color: UM.Theme.getColor("monitor_image_overlay");
height: 0.5 * printJobPreview.height;
source: printJob && printJob.state == "error" ? "../svg/aborted-icon.svg" : "";
sourceSize {
height: height;
width: width;
}
visible: source != "";
width: 0.5 * printJobPreview.width;
}
}
}
exit: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
}
enter: Transition
{
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation { property: "visible"; duration: 75; }
// Divider
Rectangle {
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
color: !printJob ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_lining_light");
height: parent.height - 2 * UM.Theme.getSize("default_margin").height;
width: UM.Theme.getSize("default_lining").width;
}
onClosed: visible = false
onOpened: visible = true
}
// Right content
Item {
anchors {
bottom: parent.bottom;
left: parent.horizontalCenter;
margins: UM.Theme.getSize("wide_margin").width;
right: parent.right;
top: parent.top;
}
Row
{
id: printerFamilyPills
spacing: 0.5 * UM.Theme.getSize("default_margin").width
anchors
{
left: parent.left
right: parent.right
bottom: extrudersInfo.top
bottomMargin: UM.Theme.getSize("default_margin").height
}
height: childrenRect.height
Repeater
{
model: printJob.compatibleMachineFamilies
Item {
id: targetPrinterLabel;
height: UM.Theme.getSize("monitor_text_line").height;
width: parent.width;
delegate: PrinterFamilyPill
{
text: modelData
color: UM.Theme.getColor("viewport_background")
padding: 3 * screenScaleFactor
Rectangle {
visible: !printJob;
color: UM.Theme.getColor("monitor_skeleton_fill");
anchors.fill: parent;
}
Label {
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default_bold");
text: {
if (printJob !== null) {
if (printJob.assignedPrinter == null) {
if (printJob.state == "error") {
return catalog.i18nc("@label", "Waiting for: Unavailable printer");
}
return catalog.i18nc("@label", "Waiting for: First available");
} else {
return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name;
}
}
return "";
}
visible: printJob;
}
}
PrinterInfoBlock {
anchors.bottom: parent.bottom;
printer: root.printJon && root.printJob.assignedPrinter;
printJob: root.printJob;
}
}
}
// PrintCore && Material config
Row
{
id: extrudersInfo
anchors.bottom: parent.bottom
anchors
{
left: parent.left
right: parent.right
}
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
PrintCoreConfiguration
{
id: leftExtruderInfo
width: Math.round(parent.width / 2) * screenScaleFactor
printCoreConfiguration: printJob.configuration.extruderConfigurations[0]
}
PrintCoreConfiguration
{
id: rightExtruderInfo
width: Math.round(parent.width / 2) * screenScaleFactor
printCoreConfiguration: printJob.configuration.extruderConfigurations[1]
PrintJobContextMenu {
id: contextButton;
anchors {
right: mainContent.right;
rightMargin: UM.Theme.getSize("default_margin").width * 3 + root.shadowRadius;
top: mainContent.top;
topMargin: UM.Theme.getSize("default_margin").height;
}
printJob: root.printJob;
visible: root.printJob;
}
}
}
Item {
id: configChangesBox;
height: childrenRect.height;
visible: printJob && printJob.configurationChanges.length !== 0;
width: parent.width;
Rectangle
{
color: UM.Theme.getColor("viewport_background")
width: 2 * screenScaleFactor
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: UM.Theme.getSize("default_margin").height
anchors.horizontalCenter: parent.horizontalCenter
// Config change toggle
Rectangle {
id: configChangeToggle;
color: {
if (configChangeToggleArea.containsMouse) {
return UM.Theme.getColor("viewport_background"); // TODO: Theme!
} else {
return "transparent";
}
}
width: parent.width;
height: UM.Theme.getSize("default_margin").height * 4; // TODO: Theme!
anchors {
left: parent.left;
right: parent.right;
top: parent.top;
}
Rectangle {
color: !printJob ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_lining_light");
height: UM.Theme.getSize("default_lining").height;
width: parent.width;
}
UM.RecolorImage {
anchors {
right: configChangeToggleLabel.left;
rightMargin: UM.Theme.getSize("default_margin").width;
verticalCenter: parent.verticalCenter;
}
color: UM.Theme.getColor("text");
height: 23 * screenScaleFactor; // TODO: Theme!
source: "../svg/warning-icon.svg";
sourceSize {
height: height;
width: width;
}
width: 23 * screenScaleFactor; // TODO: Theme!
}
Label {
id: configChangeToggleLabel;
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter;
}
color: UM.Theme.getColor("text");
text: catalog.i18nc("@label", "Configuration change");
}
UM.RecolorImage {
anchors {
left: configChangeToggleLabel.right;
leftMargin: UM.Theme.getSize("default_margin").width;
verticalCenter: parent.verticalCenter;
}
color: UM.Theme.getColor("text");
height: 15 * screenScaleFactor; // TODO: Theme!
source: {
if (configChangeDetails.visible) {
return UM.Theme.getIcon("arrow_top");
} else {
return UM.Theme.getIcon("arrow_bottom");
}
}
sourceSize {
width: width;
height: height;
}
width: 15 * screenScaleFactor; // TODO: Theme!
}
MouseArea {
id: configChangeToggleArea;
anchors.fill: parent;
hoverEnabled: true;
onClicked: {
configChangeDetails.visible = !configChangeDetails.visible;
}
}
}
// Config change details
Item {
id: configChangeDetails;
anchors.top: configChangeToggle.bottom;
Behavior on height { NumberAnimation { duration: 100 } }
// In case of really massive multi-line configuration changes
height: visible ? Math.max(UM.Theme.getSize("monitor_config_override_box").height, childrenRect.height) : 0;
visible: false;
width: parent.width;
Item {
anchors {
bottomMargin: UM.Theme.getSize("wide_margin").height;
fill: parent;
leftMargin: UM.Theme.getSize("wide_margin").height * 4;
rightMargin: UM.Theme.getSize("wide_margin").height * 4;
topMargin: UM.Theme.getSize("wide_margin").height;
}
clip: true;
Label {
anchors.fill: parent;
elide: Text.ElideRight;
color: UM.Theme.getColor("text");
font: UM.Theme.getFont("large_nonbold");
text: {
if (!printJob || printJob.configurationChanges.length === 0) {
return "";
}
var topLine;
if (materialsAreKnown(printJob)) {
topLine = catalog.i18nc("@label", "The assigned printer, %1, requires the following configuration change(s):").arg(printJob.assignedPrinter.name);
} else {
topLine = catalog.i18nc("@label", "The printer %1 is assigned, but the job contains an unknown material configuration.").arg(printJob.assignedPrinter.name);
}
var result = "<p>" + topLine +"</p>";
for (var i = 0; i < printJob.configurationChanges.length; i++) {
var change = printJob.configurationChanges[i];
var text;
switch (change.typeOfChange) {
case "material_change":
text = catalog.i18nc("@label", "Change material %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName);
break;
case "material_insert":
text = catalog.i18nc("@label", "Load %3 as material %1 (This cannot be overridden).").arg(change.index + 1).arg(change.targetName);
break;
case "print_core_change":
text = catalog.i18nc("@label", "Change print core %1 from %2 to %3.").arg(change.index + 1).arg(change.originName).arg(change.targetName);
break;
case "buildplate_change":
text = catalog.i18nc("@label", "Change build plate to %1 (This cannot be overridden).").arg(formatBuildPlateType(change.target_name));
break;
default:
text = "";
}
result += "<p><b>" + text + "</b></p>";
}
return result;
}
wrapMode: Text.WordWrap;
}
Button {
anchors {
bottom: parent.bottom;
left: parent.left;
}
onClicked: {
overrideConfirmationDialog.visible = true;
}
text: catalog.i18nc("@label", "Override");
visible: {
if (printJob && printJob.configurationChanges) {
var length = printJob.configurationChanges.length;
for (var i = 0; i < length; i++) {
var typeOfChange = printJob.configurationChanges[i].typeOfChange;
if (typeOfChange === "material_insert" || typeOfChange === "buildplate_change") {
return false;
}
}
}
return true;
}
}
}
}
MessageDialog {
id: overrideConfirmationDialog;
Component.onCompleted: visible = false;
icon: StandardIcon.Warning;
onYes: OutputDevice.forceSendJob(printJob.key);
standardButtons: StandardButton.Yes | StandardButton.No;
text: {
if (!printJob) {
return "";
}
var printJobName = formatPrintJobName(printJob.name);
var confirmText = catalog.i18nc("@label", "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?").arg(printJobName);
return confirmText;
}
title: catalog.i18nc("@window:title", "Override configuration configuration and start print");
}
}
}
}
}
// Utils
function formatPrintJobName(name) {
var extensions = [ ".gz", ".gcode", ".ufp" ];
for (var i = 0; i < extensions.length; i++) {
var extension = extensions[i];
if (name.slice(-extension.length) === extension) {
name = name.substring(0, name.length - extension.length);
}
}
return name;
}
function materialsAreKnown(job) {
var conf0 = job.configuration[0];
if (conf0 && !conf0.material.material) {
return false;
}
var conf1 = job.configuration[1];
if (conf1 && !conf1.material.material) {
return false;
}
return true;
}
function formatBuildPlateType(buildPlateType) {
var translationText = "";
switch (buildPlateType) {
case "glass":
translationText = catalog.i18nc("@label", "Glass");
break;
case "aluminum":
translationText = catalog.i18nc("@label", "Aluminum");
break;
default:
translationText = null;
}
return translationText;
}
}

View file

@ -0,0 +1,75 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Dialogs 1.1
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4 as LegacyControls
import UM 1.3 as UM
// Includes print job name, owner, and preview
Item {
property var job: null;
property var useUltibot: false;
height: 100 * screenScaleFactor;
width: height;
// Skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill");
radius: UM.Theme.getSize("default_margin").width;
visible: !job;
}
// Actual content
Image {
id: previewImage;
visible: job;
source: job ? job.previewImageUrl : "";
opacity: {
if (job == null) {
return 1.0;
}
var states = ["wait_cleanup", "wait_user_action", "error", "paused"];
if (states.indexOf(job.state) !== -1) {
return 0.5;
}
return 1.0;
}
anchors.fill: parent;
}
UM.RecolorImage {
id: ultibotImage;
anchors.centerIn: parent;
color: UM.Theme.getColor("monitor_placeholder_image"); // TODO: Theme!
height: parent.height;
source: "../svg/ultibot.svg";
sourceSize {
height: height;
width: width;
}
/* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or
not in order to determine if we show the placeholder (ultibot) image instead. */
visible: job && previewImage.status == Image.Error;
width: parent.width;
}
UM.RecolorImage {
id: statusImage;
anchors.centerIn: parent;
color: "black"; // TODO: Theme!
height: Math.round(0.5 * parent.height);
source: job && job.state == "error" ? "../svg/aborted-icon.svg" : "";
sourceSize {
height: height;
width: width;
}
visible: source != "";
width: Math.round(0.5 * parent.width);
}
}

View file

@ -0,0 +1,59 @@
// 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
Column {
property var job: null;
height: childrenRect.height;
spacing: Math.floor( UM.Theme.getSize("default_margin").height / 2); // TODO: Use explicit theme size
width: parent.width;
Item {
id: jobName;
height: UM.Theme.getSize("monitor_text_line").height;
width: parent.width;
// Skeleton loading
Rectangle {
color: UM.Theme.getColor("monitor_skeleton_fill");
height: parent.height;
visible: !job;
width: Math.round(parent.width / 3);
}
Label {
anchors.fill: parent;
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default_bold");
text: job && job.name ? job.name : "";
visible: job;
}
}
Item {
id: ownerName;
height: UM.Theme.getSize("monitor_text_line").height;
width: parent.width;
// Skeleton loading
Rectangle {
color: UM.Theme.getColor("monitor_skeleton_fill");
height: parent.height;
visible: !job;
width: Math.round(parent.width / 2);
}
Label {
anchors.fill: parent;
color: UM.Theme.getColor("text")
elide: Text.ElideRight;
font: UM.Theme.getFont("default");
text: job ? job.owner : "";
visible: job;
}
}
}

View file

@ -4,112 +4,100 @@
import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import UM 1.1 as UM
UM.Dialog
{
UM.Dialog {
id: base;
minimumWidth: 500 * screenScaleFactor
minimumHeight: 140 * screenScaleFactor
maximumWidth: minimumWidth
maximumHeight: minimumHeight
width: minimumWidth
height: minimumHeight
visible: true
modality: Qt.ApplicationModal
onVisibleChanged:
{
if(visible)
{
resetPrintersModel()
}
else
{
OutputDevice.cancelPrintSelection()
}
}
title: catalog.i18nc("@title:window", "Print over network")
property var printersModel: ListModel{}
function resetPrintersModel() {
printersModel.clear()
printersModel.append({ name: "Automatic", key: ""})
for (var index in OutputDevice.printers)
{
printersModel.append({name: OutputDevice.printers[index].name, key: OutputDevice.printers[index].key})
}
}
Column
{
id: printerSelection
anchors.fill: parent
anchors.top: parent.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.rightMargin: UM.Theme.getSize("default_margin").width
height: 50 * screenScaleFactor
Label
{
id: manualPrinterSelectionLabel
anchors
{
left: parent.left
topMargin: UM.Theme.getSize("default_margin").height
right: parent.right
}
text: catalog.i18nc("@label", "Printer selection")
wrapMode: Text.Wrap
height: 20 * screenScaleFactor
}
ComboBox
{
id: printerSelectionCombobox
model: base.printersModel
textRole: "name"
width: parent.width
height: 40 * screenScaleFactor
Behavior on height { NumberAnimation { duration: 100 } }
}
SystemPalette
{
id: palette
}
UM.I18nCatalog { id: catalog; name: "cura"; }
}
height: minimumHeight;
leftButtons: [
Button
{
text: catalog.i18nc("@action:button","Cancel")
enabled: true
Button {
enabled: true;
onClicked: {
base.visible = false;
printerSelectionCombobox.currentIndex = 0
OutputDevice.cancelPrintSelection()
printerSelectionCombobox.currentIndex = 0;
OutputDevice.cancelPrintSelection();
}
text: catalog.i18nc("@action:button","Cancel");
}
]
maximumHeight: minimumHeight;
maximumWidth: minimumWidth;
minimumHeight: 140 * screenScaleFactor;
minimumWidth: 500 * screenScaleFactor;
modality: Qt.ApplicationModal;
onVisibleChanged: {
if (visible) {
resetPrintersModel();
} else {
OutputDevice.cancelPrintSelection();
}
}
rightButtons: [
Button
{
text: catalog.i18nc("@action:button","Print")
enabled: true
Button {
enabled: true;
onClicked: {
base.visible = false;
OutputDevice.selectPrinter(printerSelectionCombobox.model.get(printerSelectionCombobox.currentIndex).key)
OutputDevice.selectPrinter(printerSelectionCombobox.model.get(printerSelectionCombobox.currentIndex).key);
// reset to defaults
printerSelectionCombobox.currentIndex = 0
printerSelectionCombobox.currentIndex = 0;
}
text: catalog.i18nc("@action:button","Print");
}
]
title: catalog.i18nc("@title:window", "Print over network");
visible: true;
width: minimumWidth;
Column {
id: printerSelection;
anchors {
fill: parent;
leftMargin: UM.Theme.getSize("default_margin").width;
rightMargin: UM.Theme.getSize("default_margin").width;
top: parent.top;
topMargin: UM.Theme.getSize("default_margin").height;
}
height: 50 * screenScaleFactor;
SystemPalette {
id: palette;
}
UM.I18nCatalog {
id: catalog;
name: "cura";
}
Label {
id: manualPrinterSelectionLabel;
anchors {
left: parent.left;
right: parent.right;
topMargin: UM.Theme.getSize("default_margin").height;
}
height: 20 * screenScaleFactor;
text: catalog.i18nc("@label", "Printer selection");
wrapMode: Text.Wrap;
}
ComboBox {
id: printerSelectionCombobox;
Behavior on height { NumberAnimation { duration: 100 } }
height: 40 * screenScaleFactor;
model: ListModel {
id: printersModel;
}
textRole: "name";
width: parent.width;
}
}
// Utils
function resetPrintersModel() {
printersModel.clear();
printersModel.append({ name: "Automatic", key: ""});
for (var index in OutputDevice.printers) {
printersModel.append({name: OutputDevice.printers[index].name, key: OutputDevice.printers[index].key});
}
}
}

View file

@ -0,0 +1,239 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Dialogs 1.1
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.3
import QtGraphicalEffects 1.0
import UM 1.3 as UM
Item {
id: root;
property var shadowRadius: UM.Theme.getSize("monitor_shadow_radius").width;
property var shadowOffset: UM.Theme.getSize("monitor_shadow_offset").width;
property var printer: null;
property var collapsed: true;
height: childrenRect.height + shadowRadius * 2; // Bubbles upward
width: parent.width; // Bubbles downward
// The actual card (white block)
Rectangle {
// 5px margin, but shifted 2px vertically because of the shadow
anchors {
bottomMargin: root.shadowRadius + root.shadowOffset;
leftMargin: root.shadowRadius;
rightMargin: root.shadowRadius;
topMargin: root.shadowRadius - root.shadowOffset;
}
color: {
if (!printer) {
return UM.Theme.getColor("monitor_card_background_inactive");
}
if (printer.state == "disabled") {
return UM.Theme.getColor("monitor_card_background_inactive");
} else {
return UM.Theme.getColor("monitor_card_background");
}
}
height: childrenRect.height;
layer.effect: DropShadow {
radius: root.shadowRadius;
verticalOffset: root.shadowOffset;
color: "#3F000000"; // 25% shadow
}
layer.enabled: true
width: parent.width - 2 * shadowRadius;
Column {
height: childrenRect.height;
width: parent.width;
// Main card
Item {
id: mainCard;
height: 60 * screenScaleFactor + 2 * UM.Theme.getSize("default_margin").width;
width: parent.width;
// Machine icon
Item {
id: machineIcon;
anchors {
leftMargin: UM.Theme.getSize("wide_margin").width;
top: parent.top;
left: parent.left;
margins: UM.Theme.getSize("default_margin").width;
}
height: parent.height - 2 * UM.Theme.getSize("default_margin").width;
width: height;
// Skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill_dark");
radius: UM.Theme.getSize("default_margin").width;
visible: !printer;
}
// Content
UM.RecolorImage {
anchors.centerIn: parent;
color: {
if (printer && printer.activePrintJob != undefined) {
return UM.Theme.getColor("monitor_printer_icon");
}
return UM.Theme.getColor("monitor_printer_icon_inactive");
}
height: sourceSize.height;
source: {
if (!printer) {
return "";
}
switch(printer.type) {
case "Ultimaker 3":
return "../svg/UM3-icon.svg";
case "Ultimaker 3 Extended":
return "../svg/UM3x-icon.svg";
case "Ultimaker S5":
return "../svg/UMs5-icon.svg";
}
}
visible: printer;
width: sourceSize.width;
}
}
// Printer info
Item {
id: printerInfo;
anchors {
left: machineIcon.right;
leftMargin: UM.Theme.getSize("default_margin").width;
right: collapseIcon.left;
verticalCenter: machineIcon.verticalCenter;
}
height: childrenRect.height;
// Machine name
Item {
id: machineNameLabel;
height: UM.Theme.getSize("monitor_text_line").height;
width: {
var percent = printer ? 0.75 : 0.3;
return Math.round(parent.width * percent);
}
// Skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill_dark");
visible: !printer;
}
// Actual content
Label {
anchors.fill: parent;
color: UM.Theme.getColor("text");
elide: Text.ElideRight;
font: UM.Theme.getFont("default_bold");
text: printer ? printer.name : "";
visible: printer;
width: parent.width;
}
}
// Job name
Item {
id: activeJobLabel;
anchors {
top: machineNameLabel.bottom;
topMargin: Math.round(UM.Theme.getSize("default_margin").height / 2);
}
height: UM.Theme.getSize("monitor_text_line").height;
width: Math.round(parent.width * 0.75);
// Skeleton
Rectangle {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_skeleton_fill_dark");
visible: !printer;
}
// Actual content
Label {
anchors.fill: parent;
color: UM.Theme.getColor("monitor_text_inactive");
elide: Text.ElideRight;
font: UM.Theme.getFont("default");
text: {
if (!printer) {
return "";
}
if (printer.state == "disabled") {
return catalog.i18nc("@label", "Not available");
} else if (printer.state == "unreachable") {
return catalog.i18nc("@label", "Unreachable");
}
if (printer.activePrintJob != null && printer.activePrintJob.name) {
return printer.activePrintJob.name;
}
return catalog.i18nc("@label", "Available");
}
visible: printer;
}
}
}
// Collapse icon
UM.RecolorImage {
id: collapseIcon;
anchors {
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
verticalCenter: parent.verticalCenter;
}
color: UM.Theme.getColor("text");
height: 15 * screenScaleFactor; // TODO: Theme!
source: root.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom");
sourceSize {
height: height;
width: width;
}
visible: printer;
width: 15 * screenScaleFactor; // TODO: Theme!
}
MouseArea {
anchors.fill: parent;
enabled: printer;
onClicked: {
if (model && root.collapsed) {
printerList.currentIndex = model.index;
} else {
printerList.currentIndex = -1;
}
}
}
Connections {
target: printerList;
onCurrentIndexChanged: {
root.collapsed = printerList.currentIndex != model.index;
}
}
}
// Detailed card
PrinterCardDetails {
collapsed: root.collapsed;
printer: root.printer;
visible: root.printer;
}
// Progress bar
PrinterCardProgressBar {
visible: printer && printer.activePrintJob != null;
}
}
}
}

View file

@ -0,0 +1,84 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Dialogs 1.1
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4 as LegacyControls
import UM 1.3 as UM
Item {
id: root;
property var printer: null;
property var printJob: printer ? printer.activePrintJob : null;
property var collapsed: true;
Behavior on height { NumberAnimation { duration: 100 } }
Behavior on opacity { NumberAnimation { duration: 100 } }
height: collapsed ? 0 : childrenRect.height;
opacity: collapsed ? 0 : 1;
width: parent.width;
Column {
id: contentColumn;
anchors {
left: parent.left;
leftMargin: UM.Theme.getSize("default_margin").width;
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
}
height: childrenRect.height + UM.Theme.getSize("wide_margin").height;
spacing: UM.Theme.getSize("default_margin").height;
width: parent.width;
HorizontalLine {}
PrinterInfoBlock {
printer: root.printer;
printJob: root.printer ? root.printer.activePrintJob : null;
}
HorizontalLine {
visible: root.printJob;
}
Row {
height: childrenRect.height;
visible: root.printJob;
width: parent.width;
PrintJobTitle {
job: root.printer ? root.printer.activePrintJob : null;
}
PrintJobContextMenu {
id: contextButton;
anchors {
right: parent.right;
rightMargin: UM.Theme.getSize("wide_margin").width;
}
printJob: root.printer ? root.printer.activePrintJob : null;
visible: printJob;
}
}
PrintJobPreview {
anchors.horizontalCenter: parent.horizontalCenter;
job: root.printer && root.printer.activePrintJob ? root.printer.activePrintJob : null;
visible: root.printJob;
}
}
CameraButton {
id: showCameraButton;
anchors {
bottom: contentColumn.bottom;
bottomMargin: Math.round(1.5 * UM.Theme.getSize("default_margin").height);
left: contentColumn.left;
leftMargin: Math.round(0.5 * UM.Theme.getSize("default_margin").width);
}
iconSource: "../svg/camera-icon.svg";
visible: root.printJob;
}
}

View file

@ -0,0 +1,108 @@
// 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
ProgressBar {
property var progress: {
if (!printer || printer.activePrintJob == null) {
return 0;
}
var result = printer.activePrintJob.timeElapsed / printer.activePrintJob.timeTotal;
if (result > 1.0) {
result = 1.0;
}
return result;
}
style: ProgressBarStyle {
property var remainingTime: {
if (!printer || printer.activePrintJob == null) {
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 (printer === null ) {
return "";
}
switch (printer.activePrintJob.state) {
case "wait_cleanup":
if (printer.activePrintJob.timeTotal > printer.activePrintJob.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 );
}
}
background: Rectangle {
color: UM.Theme.getColor("monitor_progress_background");
implicitHeight: visible ? 24 : 0;
implicitWidth: 100;
}
progress: Rectangle {
id: progressItem;
color: {
if (! printer || !printer.activePrintJob) {
return "black";
}
var state = printer.activePrintJob.state
var inactiveStates = [
"pausing",
"paused",
"resuming",
"wait_cleanup"
];
if (inactiveStates.indexOf(state) > -1 && remainingTime > 0) {
return UM.Theme.getColor("monitor_progress_fill_inactive");
} else {
return UM.Theme.getColor("monitor_progress_fill");
}
}
Label {
id: progressLabel;
anchors {
left: parent.left;
leftMargin: getTextOffset();
}
text: progressText;
anchors.verticalCenter: parent.verticalCenter;
color: progressItem.width + progressLabel.width < control.width ? UM.Theme.getColor("text") : UM.Theme.getColor("monitor_progress_fill_text");
width: contentWidth;
font: UM.Theme.getFont("default");
}
function getTextOffset() {
if (progressItem.width + progressLabel.width + 16 < control.width) {
return progressItem.width + UM.Theme.getSize("default_margin").width;
} else {
return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width;
}
}
}
}
value: progress;
width: parent.width;
}

View file

@ -1,28 +1,32 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import UM 1.2 as UM
Item
{
property alias color: background.color
property alias text: familyNameLabel.text
property var padding: 0
implicitHeight: familyNameLabel.contentHeight + 2 * padding // Apply the padding to top and bottom.
implicitWidth: familyNameLabel.contentWidth + implicitHeight // The extra height is added to ensure the radius doesn't cut something off.
Rectangle
{
id: background
height: parent.height
width: parent.width
color: parent.color
anchors.right: parent.right
anchors.horizontalCenter: parent.horizontalCenter
radius: 0.5 * height
Item {
property alias text: familyNameLabel.text;
property var padding: 3 * screenScaleFactor; // TODO: Theme!
implicitHeight: familyNameLabel.contentHeight + 2 * padding; // Apply the padding to top and bottom.
implicitWidth: Math.max(48 * screenScaleFactor, familyNameLabel.contentWidth + implicitHeight); // The extra height is added to ensure the radius doesn't cut something off.
Rectangle {
id: background;
anchors {
horizontalCenter: parent.horizontalCenter;
right: parent.right;
}
color: familyNameLabel.text.length < 1 ? UM.Theme.getColor("monitor_skeleton_fill") : UM.Theme.getColor("monitor_pill_background");
height: parent.height;
radius: 0.5 * height;
width: parent.width;
}
Label
{
id: familyNameLabel
anchors.centerIn: parent
text: ""
Label {
id: familyNameLabel;
anchors.centerIn: parent;
color: UM.Theme.getColor("text");
text: "";
}
}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
import QtQuick.Dialogs 1.1
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.3
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4 as LegacyControls
import UM 1.3 as UM
// Includes printer type pill and extuder configurations
Item {
id: root;
property var printer: null;
property var printJob: null;
width: parent.width;
height: childrenRect.height;
// Printer family pills
Row {
id: printerFamilyPills;
anchors {
left: parent.left;
right: parent.right;
}
height: childrenRect.height;
spacing: Math.round(0.5 * UM.Theme.getSize("default_margin").width);
width: parent.width;
Repeater {
id: compatiblePills;
delegate: PrinterFamilyPill {
text: modelData;
}
model: printJob ? printJob.compatibleMachineFamilies : [];
visible: printJob;
}
PrinterFamilyPill {
text: printer ? printer.type : "";
visible: !compatiblePills.visible && printer;
}
}
// Extruder info
Row {
id: extrudersInfo;
anchors {
left: parent.left;
right: parent.right;
rightMargin: UM.Theme.getSize("default_margin").width;
top: printerFamilyPills.bottom;
topMargin: UM.Theme.getSize("default_margin").height;
}
height: childrenRect.height;
spacing: UM.Theme.getSize("default_margin").width;
width: parent.width;
PrintCoreConfiguration {
width: Math.round(parent.width / 2) * screenScaleFactor;
printCoreConfiguration: getExtruderConfig(0);
}
PrintCoreConfiguration {
width: Math.round(parent.width / 2) * screenScaleFactor;
printCoreConfiguration: getExtruderConfig(1);
}
}
function getExtruderConfig( i ) {
if (root.printJob) {
// Use more-specific print job if possible
return root.printJob.configuration.extruderConfigurations[i];
}
if (root.printer) {
return root.printer.printerConfiguration.extruderConfigurations[i];
}
return null;
}
}

View file

@ -1,84 +1,75 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.3 as UM
import Cura 1.0 as Cura
Item {
property var camera: null;
Item
{
property var camera: null
Rectangle
{
anchors.fill:parent
color: UM.Theme.getColor("viewport_overlay")
opacity: 0.5
Rectangle {
anchors.fill:parent;
color: UM.Theme.getColor("viewport_overlay");
opacity: 0.5;
}
MouseArea
{
anchors.fill: parent
onClicked: OutputDevice.setActiveCamera(null)
z: 0
MouseArea {
anchors.fill: parent;
onClicked: OutputDevice.setActiveCamera(null);
z: 0;
}
CameraButton
{
id: closeCameraButton
iconSource: UM.Theme.getIcon("cross1")
anchors
{
top: cameraImage.top
topMargin: UM.Theme.getSize("default_margin").height
CameraButton {
id: closeCameraButton;
anchors {
right: cameraImage.right
rightMargin: UM.Theme.getSize("default_margin").width
top: cameraImage.top
topMargin: UM.Theme.getSize("default_margin").height
}
z: 999
iconSource: UM.Theme.getIcon("cross1");
z: 999;
}
Image
{
Cura.CameraView {
id: cameraImage
width: Math.min(sourceSize.width === 0 ? 800 * screenScaleFactor : sourceSize.width, maximumWidth)
height: Math.round((sourceSize.height === 0 ? 600 * screenScaleFactor : sourceSize.height) * width / sourceSize.width)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
z: 1
onVisibleChanged:
{
if(visible)
{
if(camera != null)
{
camera.start()
anchors.horizontalCenter: parent.horizontalCenter;
anchors.verticalCenter: parent.verticalCenter;
height: Math.round((imageHeight === 0 ? 600 * screenScaleFactor : imageHeight) * width / imageWidth);
onVisibleChanged: {
if (visible) {
if (camera != null) {
camera.start();
}
} else
{
if(camera != null)
{
camera.stop()
} else {
if (camera != null) {
camera.stop();
}
}
}
source:
Connections
{
if(camera != null && camera.latestImage != null)
{
return camera.latestImage;
target: camera
onNewImage: {
if (cameraImage.visible) {
cameraImage.image = camera.latestImage;
cameraImage.update();
}
}
return "";
}
width: Math.min(imageWidth === 0 ? 800 * screenScaleFactor : imageWidth, maximumWidth);
z: 1
}
MouseArea
{
anchors.fill: cameraImage
onClicked:
{
OutputDevice.setActiveCamera(null)
MouseArea {
anchors.fill: cameraImage;
onClicked: {
OutputDevice.setActiveCamera(null);
}
z: 1
z: 1;
}
}

View file

@ -1,125 +1,126 @@
import UM 1.2 as UM
import Cura 1.0 as Cura
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1
import UM 1.2 as UM
import Cura 1.0 as Cura
Item
{
id: base
Item {
id: base;
property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId;
property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null;
property bool printerConnected: Cura.MachineManager.printerConnected;
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands;
property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5); // AuthState.AuthenticationRequested or AuthenticationReceived.
property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId
property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null
property bool printerConnected: Cura.MachineManager.printerConnected
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5) // AuthState.AuthenticationRequested or AuthenticationReceived.
UM.I18nCatalog {
id: catalog;
name: "cura";
}
Row
{
objectName: "networkPrinterConnectButton"
visible: isUM3
spacing: UM.Theme.getSize("default_margin").width
Row {
objectName: "networkPrinterConnectButton";
spacing: UM.Theme.getSize("default_margin").width;
visible: isUM3;
Button
{
height: UM.Theme.getSize("save_button_save_to_button").height
tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer")
text: catalog.i18nc("@action:button", "Request Access")
style: UM.Theme.styles.sidebar_action_button
onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication()
visible: printerConnected && !printerAcceptsCommands && !authenticationRequested
Button {
height: UM.Theme.getSize("save_button_save_to_button").height;
onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication();
style: UM.Theme.styles.sidebar_action_button;
text: catalog.i18nc("@action:button", "Request Access");
tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer");
visible: printerConnected && !printerAcceptsCommands && !authenticationRequested;
}
Button
{
height: UM.Theme.getSize("save_button_save_to_button").height
tooltip: catalog.i18nc("@info:tooltip", "Connect to a printer")
text: catalog.i18nc("@action:button", "Connect")
style: UM.Theme.styles.sidebar_action_button
onClicked: connectActionDialog.show()
visible: !printerConnected
Button {
height: UM.Theme.getSize("save_button_save_to_button").height;
onClicked: connectActionDialog.show();
style: UM.Theme.styles.sidebar_action_button;
text: catalog.i18nc("@action:button", "Connect");
tooltip: catalog.i18nc("@info:tooltip", "Connect to a printer");
visible: !printerConnected;
}
}
UM.Dialog
{
id: connectActionDialog
Loader
{
anchors.fill: parent
source: "DiscoverUM3Action.qml"
UM.Dialog {
id: connectActionDialog;
rightButtons: Button {
iconName: "dialog-close";
onClicked: connectActionDialog.reject();
text: catalog.i18nc("@action:button", "Close");
}
rightButtons: Button
{
text: catalog.i18nc("@action:button", "Close")
iconName: "dialog-close"
onClicked: connectActionDialog.reject()
Loader {
anchors.fill: parent;
source: "DiscoverUM3Action.qml";
}
}
Column {
anchors.fill: parent;
objectName: "networkPrinterConnectionInfo";
spacing: UM.Theme.getSize("default_margin").width;
visible: isUM3;
Column
{
objectName: "networkPrinterConnectionInfo"
visible: isUM3
spacing: UM.Theme.getSize("default_margin").width
anchors.fill: parent
Button
{
tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer")
text: catalog.i18nc("@action:button", "Request Access")
onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication()
visible: printerConnected && !printerAcceptsCommands && !authenticationRequested
Button {
onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication();
text: catalog.i18nc("@action:button", "Request Access");
tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer");
visible: printerConnected && !printerAcceptsCommands && !authenticationRequested;
}
Row
{
visible: printerConnected
spacing: UM.Theme.getSize("default_margin").width
Row {
anchors {
left: parent.left;
right: parent.right;
}
height: childrenRect.height;
spacing: UM.Theme.getSize("default_margin").width;
visible: printerConnected;
anchors.left: parent.left
anchors.right: parent.right
height: childrenRect.height
Column {
Repeater {
model: Cura.ExtrudersModel {
simpleNames: true;
}
Column
{
Repeater
{
model: Cura.ExtrudersModel { simpleNames: true }
Label { text: model.name }
Label {
text: model.name;
}
}
}
Column
{
Repeater
{
id: nozzleColumn
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].hotendIds : null
Label { text: nozzleColumn.model[index] }
Column {
Repeater {
id: nozzleColumn;
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].hotendIds : null;
Label {
text: nozzleColumn.model[index];
}
}
}
Column
{
Repeater
{
id: materialColumn
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].materialNames : null
Label { text: materialColumn.model[index] }
Column {
Repeater {
id: materialColumn;
model: printerConnected ? Cura.MachineManager.printerOutputDevices[0].materialNames : null;
Label {
text: materialColumn.model[index];
}
}
}
}
Button
{
tooltip: catalog.i18nc("@info:tooltip", "Load the configuration of the printer into Cura")
text: catalog.i18nc("@action:button", "Activate Configuration")
visible: false // printerConnected && !isClusterPrinter()
onClicked: manager.loadConfigurationFromPrinter()
Button {
onClicked: manager.loadConfigurationFromPrinter();
text: catalog.i18nc("@action:button", "Activate Configuration");
tooltip: catalog.i18nc("@info:tooltip", "Load the configuration of the printer into Cura");
visible: false; // printerConnected && !isClusterPrinter()
}
}
UM.I18nCatalog{id: catalog; name: "cura"}
}