// Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.15 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 import UM 1.5 as UM import Cura 1.0 as Cura Rectangle { Cura.ExpandableComponent { id: cutPlaneBase dragPreferencesNamePrefix: "view/cutplane" contentHeaderTitle: catalog.i18nc("@label", "Cut plane") anchors { top: parent.top left: parent.horizontalCenter right: parent.right bottom: parent.bottom } headerItem: Item { UM.Label { id: cutPlaneLabel text: catalog.i18nc("@label", "Cut plane") height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text_medium") } UM.Label { text: cutPlaneOff.checked ? cutPlaneOff.text : (cutPlaneXAxis.checked ? cutPlaneXAxis.text : cutPlaneYAxis.text) anchors { left: cutPlaneLabel.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right } height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("medium") } } contentItem: Column { id: cutPlaneSettings width: UM.Theme.getSize("layerview_menu_size").width - 2 * UM.Theme.getSize("default_margin").width height: implicitHeight ColumnLayout { spacing: UM.Theme.getSize("default_margin").width RowLayout { spacing: UM.Theme.getSize("default_margin").width ButtonGroup { id: cutPlaneAxisButtons exclusive: true buttons: [cutPlaneOff, cutPlaneXAxis, cutPlaneYAxis] } Cura.RadioButton { id: cutPlaneOff text: catalog.i18nc("@label cut-plane off", "Off") checked: true onCheckedChanged: UM.SimulationView.setCutPlaneOff() } Cura.RadioButton { id: cutPlaneXAxis text: catalog.i18nc("@label cut-plane on x-axis", "X-Axis") onCheckedChanged: UM.SimulationView.setCutPlaneX() } Cura.RadioButton { id: cutPlaneYAxis text: catalog.i18nc("@label cut-plane on y-axis", "Y-Axis") onCheckedChanged: UM.SimulationView.setCutPlaneY() } UM.CheckBox { id: cutPlaneFlip enabled: ! cutPlaneOff.checked text: catalog.i18nc("@label cut-plane reversed", "Flipped") onClicked: UM.SimulationView.flipCutPlane() } } Slider { id: cutPlaneSlider Layout.alignment: Qt.AlignCenter Layout.preferredWidth: parent.width enabled: ! cutPlaneOff.checked from: (cutPlaneXAxis.checked ? UM.SimulationView.buildVolumeWidth : UM.SimulationView.buildVolumeDepth) / -2 value: 0 to: (cutPlaneXAxis.checked ? UM.SimulationView.buildVolumeWidth : UM.SimulationView.buildVolumeDepth) / 2 onPositionChanged: UM.SimulationView.setCutPlaneSlider(value) } } } } Cura.ExpandableComponent { id: colorSchemeBase dragPreferencesNamePrefix: "view/colorscheme" contentHeaderTitle: catalog.i18nc("@label", "Color scheme") anchors { top: parent.top left: parent.left right: parent.horizontalCenter bottom: parent.bottom } Connections { target: UM.Preferences function onPreferenceChanged(preference) { if (preference !== "view/only_show_top_layers" && preference !== "view/top_layer_count" && ! preference.match("layerview/")) { return; } layerTypeCombobox.currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex) viewSettings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|") viewSettings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves") viewSettings.show_helpers = UM.Preferences.getValue("layerview/show_helpers") viewSettings.show_skin = UM.Preferences.getValue("layerview/show_skin") viewSettings.show_infill = UM.Preferences.getValue("layerview/show_infill") viewSettings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers") viewSettings.top_layer_count = UM.Preferences.getValue("view/top_layer_count") } } headerItem: Item { UM.Label { id: colorSchemeLabel text: catalog.i18nc("@label", "Color scheme") height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text_medium") } UM.Label { text: layerTypeCombobox.currentText anchors { left: colorSchemeLabel.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right } height: parent.height elide: Text.ElideRight font: UM.Theme.getFont("medium") } } contentItem: Column { id: viewSettings property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|") property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves") property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers") property bool show_skin: UM.Preferences.getValue("layerview/show_skin") property bool show_infill: UM.Preferences.getValue("layerview/show_infill") property bool show_starts: UM.Preferences.getValue("layerview/show_starts") // If we are in compatibility mode, we only show the "line type" property bool show_legend: UM.SimulationView.compatibilityMode ? true : UM.Preferences.getValue("layerview/layer_view_type") == 1 property bool show_gradient: UM.SimulationView.compatibilityMode ? false : UM.Preferences.getValue("layerview/layer_view_type") == 2 || UM.Preferences.getValue("layerview/layer_view_type") == 3 property bool show_feedrate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 2 property bool show_thickness_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 3 property bool show_line_width_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 4 property bool show_flow_rate_gradient: show_gradient && UM.Preferences.getValue("layerview/layer_view_type") == 5 property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") width: UM.Theme.getSize("layerview_menu_size").width - 2 * UM.Theme.getSize("default_margin").width height: implicitHeight spacing: UM.Theme.getSize("layerview_row_spacing").height // matches SimulationView.py ListModel { id: layerViewTypes } Component.onCompleted: { layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Material Color"), type_id: 0 }) layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Line Type"), type_id: 1 }) layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Speed"), type_id: 2 }) layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Layer Thickness"), type_id: 3 // these ids match the switching in the shader }) layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Line Width"), type_id: 4 }) layerViewTypes.append({ text: catalog.i18nc("@label:listbox", "Flow"), type_id: 5 }) } Cura.ComboBox { id: layerTypeCombobox textRole: "text" valueRole: "type_id" width: parent.width implicitHeight: UM.Theme.getSize("setting_control").height model: layerViewTypes visible: !UM.SimulationView.compatibilityMode onActivated: (index) => {UM.Preferences.setValue("layerview/layer_view_type", index)} Component.onCompleted: { currentIndex = UM.SimulationView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); updateLegends(currentIndex); } function updateLegends(type_id) { // Update the visibility of the legends. viewSettings.show_legend = UM.SimulationView.compatibilityMode || (type_id == 1); viewSettings.show_gradient = !UM.SimulationView.compatibilityMode && (type_id == 2 || type_id == 3 || type_id == 4 || type_id == 5) ; viewSettings.show_feedrate_gradient = viewSettings.show_gradient && (type_id == 2); viewSettings.show_thickness_gradient = viewSettings.show_gradient && (type_id == 3); viewSettings.show_line_width_gradient = viewSettings.show_gradient && (type_id == 4); viewSettings.show_flow_rate_gradient = viewSettings.show_gradient && (type_id == 5); } } UM.Label { id: compatibilityModeLabel text: catalog.i18nc("@label", "Compatibility Mode") visible: UM.SimulationView.compatibilityMode height: UM.Theme.getSize("layerview_row").height width: parent.width } Item // Spacer { height: UM.Theme.getSize("narrow_margin").width width: width } Repeater { model: CuraApplication.getExtrudersModel() UM.CheckBox { id: extrudersModelCheckBox checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == "" height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height width: parent.width visible: !UM.SimulationView.compatibilityMode onClicked: { viewSettings.extruder_opacities[index] = checked ? 1.0 : 0.0 UM.Preferences.setValue("layerview/extruder_opacities", viewSettings.extruder_opacities.join("|")); } Rectangle { id: swatch anchors.verticalCenter: parent.verticalCenter anchors.right: extrudersModelCheckBox.right width: UM.Theme.getSize("layerview_legend_size").width height: UM.Theme.getSize("layerview_legend_size").height color: model.color border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") } UM.Label { text: model.name elide: Text.ElideRight color: UM.Theme.getColor("setting_control_text") anchors { verticalCenter: parent.verticalCenter left: extrudersModelCheckBox.left right: extrudersModelCheckBox.right leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) rightMargin: UM.Theme.getSize("default_margin").width * 2 } } } } Repeater { model: ListModel { id: typesLegendModel Component.onCompleted: { typesLegendModel.append({ label: catalog.i18nc("@label", "Travels"), initialValue: viewSettings.show_travel_moves, preference: "layerview/show_travel_moves", colorId: "layerview_move_combing" }); typesLegendModel.append({ label: catalog.i18nc("@label", "Helpers"), initialValue: viewSettings.show_helpers, preference: "layerview/show_helpers", colorId: "layerview_support" }); typesLegendModel.append({ label: catalog.i18nc("@label", "Shell"), initialValue: viewSettings.show_skin, preference: "layerview/show_skin", colorId: "layerview_inset_0" }); typesLegendModel.append({ label: catalog.i18nc("@label", "Infill"), initialValue: viewSettings.show_infill, preference: "layerview/show_infill", colorId: "layerview_infill" }); if (! UM.SimulationView.compatibilityMode) { typesLegendModel.append({ label: catalog.i18nc("@label", "Starts"), initialValue: viewSettings.show_starts, preference: "layerview/show_starts", colorId: "layerview_starts" }); } } } UM.CheckBox { id: legendModelCheckBox checked: model.initialValue onClicked: UM.Preferences.setValue(model.preference, checked) height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height width: parent.width Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.right: legendModelCheckBox.right width: UM.Theme.getSize("layerview_legend_size").width height: UM.Theme.getSize("layerview_legend_size").height color: UM.Theme.getColor(model.colorId) border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") visible: viewSettings.show_legend } UM.Label { text: label font: UM.Theme.getFont("default") elide: Text.ElideRight renderType: Text.NativeRendering color: UM.Theme.getColor("setting_control_text") anchors.verticalCenter: parent.verticalCenter anchors.left: legendModelCheckBox.left anchors.right: legendModelCheckBox.right anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width / 2) anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 } } } UM.CheckBox { checked: viewSettings.only_show_top_layers onClicked: UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0) text: catalog.i18nc("@label", "Only Show Top Layers") visible: UM.SimulationView.compatibilityMode width: parent.width } UM.CheckBox { checked: viewSettings.top_layer_count == 5 onClicked: UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1) text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") width: parent.width visible: UM.SimulationView.compatibilityMode } Repeater { model: ListModel { id: typesLegendModelNoCheck Component.onCompleted: { typesLegendModelNoCheck.append({ label: catalog.i18nc("@label", "Top / Bottom"), colorId: "layerview_skin", }); typesLegendModelNoCheck.append({ label: catalog.i18nc("@label", "Inner Wall"), colorId: "layerview_inset_x", }); } } UM.Label { text: label visible: viewSettings.show_legend id: typesLegendModelLabel height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height width: parent.width color: UM.Theme.getColor("setting_control_text") Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.right: typesLegendModelLabel.right width: UM.Theme.getSize("layerview_legend_size").width height: UM.Theme.getSize("layerview_legend_size").height color: UM.Theme.getColor(model.colorId) border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") } } } // Text for the minimum, maximum and units for the feedrates and layer thickness Item { id: gradientLegend visible: viewSettings.show_gradient width: parent.width height: UM.Theme.getSize("layerview_row").height UM.Label //Minimum value. { text: { if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { // Feedrate selected if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { return parseFloat(UM.SimulationView.minFeedrate).toFixed(2) } // Layer thickness selected if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { return parseFloat(UM.SimulationView.minThickness).toFixed(2) } // Line width selected if(UM.Preferences.getValue("layerview/layer_view_type") == 4) { return parseFloat(UM.SimulationView.minLineWidth).toFixed(2); } // Flow Rate selected if(UM.Preferences.getValue("layerview/layer_view_type") == 5) { return parseFloat(UM.SimulationView.minFlowRate).toFixed(2); } } return catalog.i18nc("@label","min") } anchors.left: parent.left } UM.Label //Unit in the middle. { text: { if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { // Feedrate selected if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { return "mm/s" } // Layer thickness selected if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { return "mm" } //Line width selected if(UM.Preferences.getValue("layerview/layer_view_type") == 4) { return "mm" } // Flow Rate selected if (UM.Preferences.getValue("layerview/layer_view_type") == 5) { return "mm³/s" } } return "" } anchors.horizontalCenter: parent.horizontalCenter color: UM.Theme.getColor("setting_control_text") } UM.Label //Maximum value. { text: { if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { // Feedrate selected if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { return parseFloat(UM.SimulationView.maxFeedrate).toFixed(2) } // Layer thickness selected if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { return parseFloat(UM.SimulationView.maxThickness).toFixed(2) } //Line width selected if(UM.Preferences.getValue("layerview/layer_view_type") == 4) { return parseFloat(UM.SimulationView.maxLineWidth).toFixed(2); } // Flow rate selected if(UM.Preferences.getValue("layerview/layer_view_type") == 5) { return parseFloat(UM.SimulationView.maxFlowRate).toFixed(2); } } return catalog.i18nc("@label","max") } anchors.right: parent.right color: UM.Theme.getColor("setting_control_text") } } // Gradient colors for feedrate Rectangle { id: feedrateGradient visible: ( viewSettings.show_feedrate_gradient || viewSettings.show_line_width_gradient ) anchors.left: parent.left anchors.right: parent.right height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.000 color: Qt.rgba(0, 0, 1, 1) } GradientStop { position: 0.25 color: Qt.rgba(0.25, 1, 0, 1) } GradientStop { position: 0.375 color: Qt.rgba(0.375, 0.5, 0, 1) } GradientStop { position: 1.0 color: Qt.rgba(1, 0.5, 0, 1) } } } // Gradient colors for layer thickness (similar to parula colormap) Rectangle { id: thicknessGradient visible: ( viewSettings.show_thickness_gradient ) anchors.left: parent.left anchors.right: parent.right height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.000 color: Qt.rgba(0, 0, 0.5, 1) } GradientStop { position: 0.25 color: Qt.rgba(0, 0.375, 0.75, 1) } GradientStop { position: 0.5 color: Qt.rgba(0, 0.75, 0.5, 1) } GradientStop { position: 0.75 color: Qt.rgba(1, 0.75, 0.25, 1) } GradientStop { position: 1.0 color: Qt.rgba(1, 1, 0, 1) } } } // Gradient colors for flow (similar to jet colormap) Rectangle { id: jetGradient visible: ( viewSettings.show_flow_rate_gradient ) anchors.left: parent.left anchors.right: parent.right height: Math.round(UM.Theme.getSize("layerview_row").height * 1.5) border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0 color: Qt.rgba(0, 0, 0.5, 1) } GradientStop { position: 0.125 color: Qt.rgba(0, 0.0, 1.0, 1) } GradientStop { position: 0.25 color: Qt.rgba(0, 0.5, 1.0, 1) } GradientStop { position: 0.375 color: Qt.rgba(0.0, 1.0, 1.0, 1) } GradientStop { position: 0.5 color: Qt.rgba(0.5, 1.0, 0.5, 1) } GradientStop { position: 0.625 color: Qt.rgba(1.0, 1.0, 0.0, 1) } GradientStop { position: 0.75 color: Qt.rgba(1.0, 0.5, 0, 1) } GradientStop { position: 0.875 color: Qt.rgba(1.0, 0.0, 0, 1) } GradientStop { position: 1.0 color: Qt.rgba(0.5, 0, 0, 1) } } } } } FontMetrics { id: fontMetrics font: UM.Theme.getFont("default") } }