Cura/plugins/UM3NetworkPrinting/ClusterControlItem.qml
2018-09-05 10:09:44 +02:00

695 lines
34 KiB
QML

import QtQuick 2.3
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 lineColor: "#DCDCDC" // TODO: Should be linked to theme.
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"
}
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
}
text: catalog.i18nc("@label", "Printing")
elide: Text.ElideRight
}
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
}
style: UM.Theme.styles.scrollview
ListView
{
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
}
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
id: base
property var shadowRadius: 5
property var collapsed: true
layer.enabled: true
layer.effect: DropShadow
{
radius: base.shadowRadius
verticalOffset: 2
color: "#3F000000" // 25% shadow
}
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: base.collapsed = !base.collapsed
}
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 "UM3-icon.svg"
case "Ultimaker 3 Extended":
return "UM3x-icon.svg"
case "Ultimaker S5":
return "UMs5-icon.svg"
}
}
width: sourceSize.width
height: sourceSize.height
color: modelData.activePrintJob != undefined ? UM.Theme.getColor("primary") : UM.Theme.getColor("setting_control_disabled")
}
}
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")
}
if (modelData.activePrintJob != null)
{
return modelData.activePrintJob.name
}
return catalog.i18nc("@label", "Waiting")
}
anchors.top: machineNameLabel.bottom
width: parent.width
elide: Text.ElideRight
font: UM.Theme.getFont("default")
opacity: 0.6
}
}
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: UM.Theme.getColor("viewport_background")
height: 2
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: 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.
font.pixelSize: 25
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")
}
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: Controls2.Popup.CloseOnPressOutsideParent
x: parent.width - width
y: contextButton.height
width: 160
height: contentItem.height + 2 * padding
visible: false
transformOrigin: Controls2.Popup.Top
contentItem: Item
{
width: popup.width - 2 * popup.padding
height: childrenRect.height + 15
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
anchors.top: parent.top
anchors.topMargin: 10
hoverEnabled: true
background: Rectangle
{
opacity: pauseButton.down || pauseButton.hovered ? 1 : 0
color: UM.Theme.getColor("viewport_background")
}
}
Controls2.Button
{
id: abortButton
text: catalog.i18nc("@label", "Abort")
onClicked:
{
modelData.activePrintJob.setState("abort")
popup.close()
}
width: parent.width
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")
}
}
}
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
height: parent.height -10
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle
{
id: point
height: 13
width: 13
color: UM.Theme.getColor("setting_control")
transform: Rotation { angle: 45}
anchors.right: bloop.right
y: 1
}
Rectangle
{
id: bloop
color: UM.Theme.getColor("setting_control")
width: parent.width
anchors.top: parent.top
anchors.topMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
}
}
}
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 "paused-icon.svg"
case "wait_cleanup":
if(modelData.activePrintJob.timeElapsed < modelData.activePrintJob.timeTotal)
{
return "aborted-icon.svg"
}
return "approved-icon.svg"
case "wait_user_action":
return "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"
}
Rectangle
{
id: showCameraIcon
width: 35 * screenScaleFactor
height: width
radius: 0.5 * width
anchors.left: parent.left
anchors.bottom: printJobPreview.bottom
color: UM.Theme.getColor("setting_control_border_highlight")
Image
{
width: parent.width
height: width
anchors.right: parent.right
anchors.rightMargin: parent.rightMargin
source: "camera-icon.svg"
}
MouseArea
{
anchors.fill:parent
onClicked:
{
OutputDevice.setActiveCamera(modelData.camera)
}
}
}
}
}
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 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":
case "wait_user_action":
return catalog.i18nc("@label:status", "Aborted")
case "pausing":
case "paused":
return catalog.i18nc("@label:status", "Paused")
case "resuming":
return catalog.i18nc("@label:status", "Resuming")
case "queued":
return catalog.i18nc("@label:status", "Configuration change")
default:
OutputDevice.formatDuration(modelData.activePrintJob.timeTotal - modelData.activePrintJob.timeElapsed)
}
}
background: Rectangle
{
implicitWidth: 100
implicitHeight: visible ? 24 : 0
color: UM.Theme.getColor("viewport_background")
}
progress: Rectangle
{
color: UM.Theme.getColor("primary")
id: progressItem
function getTextOffset()
{
if(progressItem.width + progressLabel.width < 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")
}
}
}
}
}
}
}
}
}
}