// Copyright (c) 2017 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import UM 1.2 as UM import Cura 1.0 as Cura import ".." Item { id: base width: childrenRect.width height: childrenRect.height property var all_categories_except_support: [ "machine_settings", "resolution", "shell", "infill", "material", "speed", "travel", "cooling", "platform_adhesion", "dual", "meshfix", "blackmagic", "experimental"] readonly property string normal_mesh_type: "" readonly property string support_mesh_type: "support_mesh" readonly property string cutting_mesh_type: "cutting_mesh" readonly property string infill_mesh_type: "infill_mesh" readonly property string anti_overhang_mesh_type: "anti_overhang_mesh" property var currentMeshType: UM.ActiveTool.properties.getValue("MeshType") // Update the view every time the currentMeshType changes onCurrentMeshTypeChanged: { // set checked state of mesh type buttons normalButton.checked = currentMeshType === normal_mesh_type supportMeshButton.checked = currentMeshType === support_mesh_type overhangMeshButton.checked = currentMeshType === infill_mesh_type || currentMeshType === cutting_mesh_type antiOverhangMeshButton.checked = currentMeshType === anti_overhang_mesh_type // update active type label for (var button in meshTypeButtons.children) { if (meshTypeButtons.children[button].checked) { meshTypeLabel.text = catalog.i18nc("@label","Mesh Type") + ": " + meshTypeButtons.children[button].text break } } } function setOverhangsMeshType() { if (infillOnlyCheckbox.checked) { setMeshType(infill_mesh_type) } else { setMeshType(cutting_mesh_type) } } function setMeshType(type) { UM.ActiveTool.setProperty("MeshType", type) } UM.I18nCatalog { id: catalog; name: "uranium"} Column { id: items anchors.top: parent.top; anchors.left: parent.left; spacing: UM.Theme.getSize("default_margin").height Row // Mesh type buttons { id: meshTypeButtons spacing: UM.Theme.getSize("default_margin").width Button { id: normalButton text: catalog.i18nc("@label", "Normal model") iconSource: UM.Theme.getIcon("pos_normal"); property bool needBorder: true checkable: true onClicked: setMeshType(normal_mesh_type); style: UM.Theme.styles.tool_button; z: 4 } Button { id: supportMeshButton text: catalog.i18nc("@label", "Print as support") iconSource: UM.Theme.getIcon("pos_print_as_support"); property bool needBorder: true checkable:true onClicked: setMeshType(support_mesh_type) style: UM.Theme.styles.tool_button; z: 3 } Button { id: overhangMeshButton text: catalog.i18nc("@label", "Modify settings for overlays") iconSource: UM.Theme.getIcon("pos_modify_overlaps"); property bool needBorder: true checkable:true onClicked: setMeshType(infill_mesh_type) style: UM.Theme.styles.tool_button; z: 2 } Button { id: antiOverhangMeshButton text: catalog.i18nc("@label", "Don't support overlaps") iconSource: UM.Theme.getIcon("pos_modify_dont_support_overlap"); property bool needBorder: true checkable: true onClicked: setMeshType(anti_overhang_mesh_type) style: UM.Theme.styles.tool_button; z: 1 } } Label { id: meshTypeLabel font: UM.Theme.getFont("default") color: UM.Theme.getColor("text") height: UM.Theme.getSize("setting").height verticalAlignment: Text.AlignVCenter } CheckBox { id: infillOnlyCheckbox text: catalog.i18nc("@action:checkbox","Infill only"); style: UM.Theme.styles.checkbox; visible: currentMeshType === infill_mesh_type || currentMeshType === cutting_mesh_type onClicked: setOverhangsMeshType() Binding { target: infillOnlyCheckbox property: "checked" value: currentMeshType === infill_mesh_type } } Column // Settings Dialog { // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar. // It kinda looks ugly otherwise (big panel, no content on it) id: currentSettings property int maximumHeight: 200 * screenScaleFactor height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight) visible: currentMeshType != "anti_overhang_mesh" ScrollView { height: parent.height width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width style: UM.Theme.styles.scrollview ListView { id: contents spacing: UM.Theme.getSize("default_lining").height model: UM.SettingDefinitionsModel { id: addedSettingsModel containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" expanded: [ "*" ] filter: { if (printSequencePropertyProvider.properties.value == "one_at_a_time") { return {"settable_per_meshgroup": true} } return {"settable_per_mesh": true} } exclude: { var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] if(currentMeshType == "support_mesh") { excluded_settings = excluded_settings.concat(base.all_categories_except_support) } return excluded_settings } visibilityHandler: Cura.PerObjectSettingVisibilityHandler { selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId") } // For some reason the model object is updated after removing him from the memory and // it happens only on Windows. For this reason, set the destroyed value manually. Component.onDestruction: { setDestroyed(true) } } delegate: Row { spacing: - UM.Theme.getSize("default_margin").width Loader { id: settingLoader width: UM.Theme.getSize("setting").width height: UM.Theme.getSize("section").height property var definition: model property var settingDefinitionsModel: addedSettingsModel property var propertyProvider: provider property var globalPropertyProvider: inheritStackProvider property var externalResetHandler: false //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. asynchronous: model.type != "enum" && model.type != "extruder" onLoaded: { settingLoader.item.showRevertButton = false settingLoader.item.showInheritButton = false settingLoader.item.showLinkedSettingIcon = false settingLoader.item.doDepthIndentation = false settingLoader.item.doQualityUserSettingEmphasis = false } sourceComponent: { switch(model.type) { case "int": return settingTextField case "[int]": return settingTextField case "float": return settingTextField case "enum": return settingComboBox case "extruder": return settingExtruder case "optional_extruder": return settingOptionalExtruder case "bool": return settingCheckBox case "str": return settingTextField case "category": return settingCategory default: return settingUnknown } } } Button { width: Math.round(UM.Theme.getSize("setting").height / 2) height: UM.Theme.getSize("setting").height onClicked: addedSettingsModel.setVisible(model.key, false) style: ButtonStyle { background: Item { UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter width: parent.width height: width sourceSize.height: width color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") source: UM.Theme.getIcon("minus") } } } } // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events // so we bypass that to make a dedicated provider). UM.SettingPropertyProvider { id: provider containerStackId: UM.ActiveTool.properties.getValue("ContainerID") key: model.key watchedProperties: [ "value", "enabled", "validationState" ] storeIndex: 0 removeUnusedValue: false } UM.SettingPropertyProvider { id: inheritStackProvider containerStackId: UM.ActiveTool.properties.getValue("ContainerID") key: model.key watchedProperties: [ "limit_to_extruder" ] } Connections { target: inheritStackProvider onPropertiesChanged: { provider.forcePropertiesChanged() } } Connections { target: UM.ActiveTool onPropertiesChanged: { // the values cannot be bound with UM.ActiveTool.properties.getValue() calls, // so here we connect to the signal and update the those values. if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined") { const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId") if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId) { addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId } } if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined") { const containerId = UM.ActiveTool.properties.getValue("ContainerID") if (provider.containerStackId != containerId) { provider.containerStackId = containerId } if (inheritStackProvider.containerStackId != containerId) { inheritStackProvider.containerStackId = containerId } } } } } } } } Cura.SecondaryButton { id: customiseSettingsButton; height: UM.Theme.getSize("setting_control").height; visible: currentSettings.visible text: catalog.i18nc("@action:button", "Select settings"); onClicked: { settingPickDialog.visible = true; if (currentMeshType == "support_mesh") { settingPickDialog.additional_excluded_settings = base.all_categories_except_support; } else { settingPickDialog.additional_excluded_settings = [] } } } } UM.Dialog { id: settingPickDialog title: catalog.i18nc("@title:window", "Select Settings to Customize for this model") width: screenScaleFactor * 360 property var additional_excluded_settings onVisibilityChanged: { // force updating the model to sync it with addedSettingsModel if(visible) { // Set skip setting, it will prevent from resetting selected mesh_type contents.model.visibilityHandler.addSkipResetSetting(currentMeshType) listview.model.forceUpdate() updateFilter() } } function updateFilter() { var new_filter = {} new_filter["settable_per_mesh"] = true // Don't filter on "settable_per_meshgroup" any more when `printSequencePropertyProvider.properties.value` // is set to "one_at_a_time", because the current backend architecture isn't ready for that. if(filterInput.text != "") { new_filter["i18n_label"] = "*" + filterInput.text } listview.model.filter = new_filter } TextField { id: filterInput anchors { top: parent.top left: parent.left right: toggleShowAll.left rightMargin: UM.Theme.getSize("default_margin").width } placeholderText: catalog.i18nc("@label:textbox", "Filter...") onTextChanged: settingPickDialog.updateFilter() } CheckBox { id: toggleShowAll anchors { top: parent.top right: parent.right } text: catalog.i18nc("@label:checkbox", "Show all") checked: listview.model.showAll onClicked: { listview.model.showAll = checked } } ScrollView { id: scrollView anchors { top: filterInput.bottom left: parent.left right: parent.right bottom: parent.bottom } ListView { id:listview model: UM.SettingDefinitionsModel { id: definitionsModel containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" visibilityHandler: UM.SettingPreferenceVisibilityHandler {} expanded: [ "*" ] exclude: { var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ] excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings) return excluded_settings } } delegate:Loader { id: loader width: parent.width height: model.type != undefined ? UM.Theme.getSize("section").height : 0 property var definition: model property var settingDefinitionsModel: definitionsModel asynchronous: true source: { switch(model.type) { case "category": return "PerObjectCategory.qml" default: return "PerObjectItem.qml" } } } Component.onCompleted: settingPickDialog.updateFilter() } } rightButtons: [ Button { text: catalog.i18nc("@action:button", "Close") onClicked: settingPickDialog.visible = false } ] } UM.SettingPropertyProvider { id: machineExtruderCount containerStack: Cura.MachineManager.activeMachine key: "machine_extruder_count" watchedProperties: [ "value" ] storeIndex: 0 } UM.SettingPropertyProvider { id: printSequencePropertyProvider containerStack: Cura.MachineManager.activeMachine key: "print_sequence" watchedProperties: [ "value" ] storeIndex: 0 } SystemPalette { id: palette } Component { id: settingTextField Cura.SettingTextField { } } Component { id: settingComboBox Cura.SettingComboBox { } } Component { id: settingExtruder Cura.SettingExtruder { } } Component { id: settingOptionalExtruder Cura.SettingOptionalExtruder { } } Component { id: settingCheckBox Cura.SettingCheckBox { } } Component { id: settingCategory Cura.SettingCategory { } } Component { id: settingUnknown Cura.SettingUnknown { } } }