// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import UM 1.5 as UM import Cura 1.0 as Cura /** * Menu that allows you to select the configuration of the current printer, such * as the nozzle sizes and materials in each extruder. */ Cura.ExpandablePopup { id: base property var extrudersModel: CuraApplication.getExtrudersModel() property var activeMachine: Cura.MachineManager.activeMachine UM.I18nCatalog { id: catalog name: "cura" } enum ConfigurationMethod { Auto, Custom } contentPadding: UM.Theme.getSize("default_lining").width enabled: activeMachine ? activeMachine.hasMaterials || activeMachine.hasVariants || activeMachine.hasVariantBuildplates : false; //Only let it drop down if there is any configuration that you could change. headerItem: Item { id: headerBase // Horizontal list that shows the extruders and their materials RowLayout { anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: parent.left width: parent.width - UM.Theme.getSize("standard_arrow").width visible: activeMachine ? activeMachine.hasMaterials : false Repeater { model: extrudersModel delegate: Item { id: extruderItem Layout.preferredWidth: Math.floor(headerBase.width / extrudersModel.count) Layout.maximumWidth: Math.floor(headerBase.width / extrudersModel.count) Layout.preferredHeight: headerBase.height Layout.maximumHeight: headerBase.height Layout.fillHeight: true Layout.alignment: Qt.AlignCenter property var extruderStack: activeMachine ? activeMachine.extruderList[model.index]: null property bool valueWarning: !Cura.ExtruderManager.getExtruderHasQualityForMaterial(extruderStack) property bool valueError: activeMachine ? Cura.ContainerManager.getContainerMetaDataEntry(extruderStack.material.id, "compatible") != "True" : false // Extruder icon. Shows extruder index and has the same color as the active material. Cura.ExtruderIcon { id: extruderIcon materialColor: model.color extruderEnabled: model.enabled anchors.verticalCenter: parent.verticalCenter } MouseArea // Connection status tooltip hover area { id: tooltipHoverArea anchors.fill: parent hoverEnabled: tooltip.text != "" acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks onEntered: { base.mouseArea.entered() // we want both this and the outer area to be entered tooltip.show() } onExited: { tooltip.hide() } } UM.ToolTip { id: tooltip x: 0 y: parent.height + UM.Theme.getSize("default_margin").height width: UM.Theme.getSize("tooltip").width targetPoint: Qt.point(Math.round(extruderIcon.width / 2), 0) text: { if (!model.enabled) { return "" } if (extruderItem.valueError) { return catalog.i18nc("@tooltip", "The configuration of this extruder is not allowed, and prohibits slicing.") } if (extruderItem.valueWarning) { return catalog.i18nc("@tooltip", "There are no profiles matching the configuration of this extruder.") } return "" } } // Warning icon that indicates if no qualities are available for the variant/material combination for this extruder UM.ColorImage { id: badge anchors { top: parent.top topMargin: - Math.round(height * 1 / 6) left: parent.left leftMargin: extruderIcon.width - Math.round(width * 5 / 6) } width: UM.Theme.getSize("icon_indicator").width height: UM.Theme.getSize("icon_indicator").height visible: model.enabled && (extruderItem.valueError || extruderItem.valueWarning) source: { if (extruderItem.valueError) { return UM.Theme.getIcon("ErrorBadge", "low") } if (extruderItem.valueWarning) { return UM.Theme.getIcon("WarningBadge", "low") } return "" } color: { if (extruderItem.valueError) { return UM.Theme.getColor("error") } if (extruderItem.valueWarning) { return UM.Theme.getColor("warning") } return "transparent" } // Make a themable circle in the background so we can change it in other themes Rectangle { id: iconBackground anchors.centerIn: parent width: parent.width - 1.5 //1.5 pixels smaller, (at least sqrt(2), regardless of screen pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing. height: parent.height - 1.5 radius: width / 2 z: parent.z - 1 color: { if (extruderItem.valueError) { return UM.Theme.getColor("error_badge_background") } if (extruderItem.valueWarning) { return UM.Theme.getColor("warning_badge_background") } return "transparent" } } } Column { opacity: model.enabled ? 1 : UM.Theme.getColor("extruder_disabled").a spacing: 0 visible: width > 0 anchors { left: extruderIcon.right leftMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter right: parent.right rightMargin: UM.Theme.getSize("default_margin").width } // Label for the brand of the material UM.Label { id: materialBrandNameLabel text: model.material_brand + " " + model.material_name elide: Text.ElideRight wrapMode: Text.NoWrap width: parent.width visible: !truncated } UM.Label { id: materialNameLabel text: model.material_name elide: Text.ElideRight width: parent.width wrapMode: Text.NoWrap visible: !materialBrandNameLabel.visible && !truncated } UM.Label { id: materialTypeLabel text: model.material_type elide: Text.ElideRight width: parent.width wrapMode: Text.NoWrap visible: !materialBrandNameLabel.visible && !materialNameLabel.visible } // Label that shows the name of the variant UM.Label { id: variantLabel visible: activeMachine ? activeMachine.hasVariants : false text: model.variant elide: Text.ElideRight wrapMode: Text.NoWrap font: UM.Theme.getFont("default_bold") Layout.preferredWidth: parent.width } } } } } // Placeholder text if there is a configuration to select but no materials (so we can't show the materials per extruder). UM.Label { text: catalog.i18nc("@label", "Select configuration") elide: Text.ElideRight font: UM.Theme.getFont("medium") visible: activeMachine ? !activeMachine.hasMaterials && (activeMachine.hasVariants || activeMachine.hasVariantBuildplates) : false anchors { left: parent.left leftMargin: UM.Theme.getSize("default_margin").width verticalCenter: parent.verticalCenter } } } contentWidth: UM.Theme.getSize("configuration_selector").width contentItem: Column { id: popupItem padding: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height property bool is_connected: false // If current machine is connected to a printer. Only evaluated upon making popup visible. property int configuration_method: ConfigurationMenu.ConfigurationMethod.Custom // Type of configuration being used. Only evaluated upon making popup visible. property int manual_selected_method: -1 // It stores the configuration method selected by the user. By default the selected method is onVisibleChanged: { is_connected = activeMachine.hasRemoteConnection && Cura.MachineManager.printerConnected && Cura.MachineManager.printerOutputDevices[0].uniqueConfigurations.length > 0 //Re-evaluate. // If the printer is not connected or does not have configurations, we switch always to the custom mode. If is connected instead, the auto mode // or the previous state is selected configuration_method = is_connected ? (manual_selected_method == -1 ? ConfigurationMenu.ConfigurationMethod.Auto : manual_selected_method) : ConfigurationMenu.ConfigurationMethod.Custom } Item { width: parent.width - 2 * parent.padding height: { var height = 0 if (autoConfiguration.visible) { height += autoConfiguration.height } if (customConfiguration.visible) { height += customConfiguration.height } return height } AutoConfiguration { id: autoConfiguration visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto } CustomConfiguration { id: customConfiguration visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom } } Rectangle { id: separator visible: buttonBar.visible x: -parent.padding width: parent.width height: UM.Theme.getSize("default_lining").height color: UM.Theme.getColor("lining") } //Allow switching between custom and auto. Item { id: buttonBar visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible. width: parent.width - 2 * parent.padding height: childrenRect.height Cura.SecondaryButton { id: goToCustom visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto text: catalog.i18nc("@label", "Custom") anchors.right: parent.right iconSource: UM.Theme.getIcon("ChevronSingleRight") isIconOnRightSide: true onClicked: { popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom popupItem.manual_selected_method = popupItem.configuration_method } } Cura.SecondaryButton { id: goToAuto visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom text: catalog.i18nc("@label", "Configurations") iconSource: UM.Theme.getIcon("ChevronSingleLeft") onClicked: { popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto popupItem.manual_selected_method = popupItem.configuration_method } } } } Connections { target: Cura.MachineManager function onGlobalContainerChanged() { popupItem.manual_selected_method = -1 } // When switching printers, reset the value of the manual selected method } }