// Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V. // The PostProcessingPlugin is released under the terms of the AGPLv3 or higher. import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import UM 1.2 as UM import Cura 1.0 as Cura UM.Dialog { id: dialog title: catalog.i18nc("@title:window", "Post Processing Plugin") width: 700 * screenScaleFactor; height: 500 * screenScaleFactor; minimumWidth: 400 * screenScaleFactor; minimumHeight: 250 * screenScaleFactor; onVisibleChanged: { if(!visible) //Whenever the window is closed (either via the "Close" button or the X on the window frame), we want to update it in the stack. { manager.writeScriptsToStack(); } } Item { UM.I18nCatalog{id: catalog; name:"cura"} id: base property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width) property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2) property string activeScriptName SystemPalette{ id: palette } SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled } anchors.fill: parent ExclusiveGroup { id: selectedScriptGroup } Item { id: activeScripts anchors.left: parent.left width: base.columnWidth height: parent.height Label { id: activeScriptsHeader text: catalog.i18nc("@label", "Post Processing Scripts") anchors.top: parent.top anchors.topMargin: base.textMargin anchors.left: parent.left anchors.leftMargin: base.textMargin anchors.right: parent.right anchors.rightMargin: base.textMargin font: UM.Theme.getFont("large") } ListView { id: activeScriptsList anchors.top: activeScriptsHeader.bottom anchors.topMargin: base.textMargin anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right anchors.rightMargin: base.textMargin height: childrenRect.height model: manager.scriptList delegate: Item { width: parent.width height: activeScriptButton.height Button { id: activeScriptButton text: manager.getScriptLabelByKey(modelData.toString()) exclusiveGroup: selectedScriptGroup checkable: true checked: { if (manager.selectedScriptIndex == index) { base.activeScriptName = manager.getScriptLabelByKey(modelData.toString()) return true } else { return false } } onClicked: { forceActiveFocus() manager.setSelectedScriptIndex(index) base.activeScriptName = manager.getScriptLabelByKey(modelData.toString()) } width: parent.width height: UM.Theme.getSize("setting").height style: ButtonStyle { background: Rectangle { color: activeScriptButton.checked ? palette.highlight : "transparent" width: parent.width height: parent.height } label: Label { wrapMode: Text.Wrap text: control.text color: activeScriptButton.checked ? palette.highlightedText : palette.text } } } Button { id: removeButton text: "x" width: 20 * screenScaleFactor height: 20 * screenScaleFactor anchors.right:parent.right anchors.rightMargin: base.textMargin anchors.verticalCenter: parent.verticalCenter onClicked: manager.removeScriptByIndex(index) style: ButtonStyle { label: Item { UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.7) height: Math.round(control.height / 2.7) sourceSize.width: width sourceSize.height: width color: palette.text source: UM.Theme.getIcon("cross1") } } } } Button { id: downButton text: "" anchors.right: removeButton.left anchors.verticalCenter: parent.verticalCenter enabled: index != manager.scriptList.length - 1 width: 20 * screenScaleFactor height: 20 * screenScaleFactor onClicked: { if (manager.selectedScriptIndex == index) { manager.setSelectedScriptIndex(index + 1) } return manager.moveScript(index, index + 1) } style: ButtonStyle { label: Item { UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_bottom") } } } } Button { id: upButton text: "" enabled: index != 0 width: 20 * screenScaleFactor height: 20 * screenScaleFactor anchors.right: downButton.left anchors.verticalCenter: parent.verticalCenter onClicked: { if (manager.selectedScriptIndex == index) { manager.setSelectedScriptIndex(index - 1) } return manager.moveScript(index, index - 1) } style: ButtonStyle { label: Item { UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(control.width / 2.5) height: Math.round(control.height / 2.5) sourceSize.width: width sourceSize.height: width color: control.enabled ? palette.text : disabledPalette.text source: UM.Theme.getIcon("arrow_top") } } } } } } Button { id: addButton text: catalog.i18nc("@action", "Add a script") anchors.left: parent.left anchors.leftMargin: base.textMargin anchors.top: activeScriptsList.bottom anchors.topMargin: base.textMargin menu: scriptsMenu style: ButtonStyle { label: Label { text: control.text } } } Menu { id: scriptsMenu Instantiator { model: manager.loadedScriptList MenuItem { text: manager.getScriptLabelByKey(modelData.toString()) onTriggered: manager.addScriptToList(modelData.toString()) } onObjectAdded: scriptsMenu.insertItem(index, object); onObjectRemoved: scriptsMenu.removeItem(object); } } } Rectangle { color: UM.Theme.getColor("sidebar") anchors.left: activeScripts.right anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right height: parent.height id: settingsPanel Label { id: scriptSpecsHeader text: manager.selectedScriptIndex == -1 ? catalog.i18nc("@label", "Settings") : base.activeScriptName anchors.top: parent.top anchors.topMargin: base.textMargin anchors.left: parent.left anchors.leftMargin: base.textMargin anchors.right: parent.right anchors.rightMargin: base.textMargin height: 20 * screenScaleFactor font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") } ScrollView { id: scrollView anchors.top: scriptSpecsHeader.bottom anchors.topMargin: settingsPanel.textMargin anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom visible: manager.selectedScriptDefinitionId != "" style: UM.Theme.styles.scrollview; ListView { id: listview spacing: UM.Theme.getSize("default_lining").height model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: manager.selectedScriptDefinitionId showAll: true } delegate:Loader { id: settingLoader width: parent.width height: { if(provider.properties.enabled == "True") { if(model.type != undefined) { return UM.Theme.getSize("section").height; } else { return 0; } } else { return 0; } } Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } enabled: opacity > 0 property var definition: model property var settingDefinitionsModel: definitionsModel property var propertyProvider: provider property var globalPropertyProvider: inheritStackProvider //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 = true settingLoader.item.doQualityUserSettingEmphasis = false } sourceComponent: { switch(model.type) { case "int": return settingTextField case "float": return settingTextField case "enum": return settingComboBox case "extruder": return settingExtruder case "bool": return settingCheckBox case "str": return settingTextField case "category": return settingCategory default: return settingUnknown } } UM.SettingPropertyProvider { id: provider containerStackId: manager.selectedScriptStackId key: model.key ? model.key : "None" watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 } // 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: inheritStackProvider containerStackId: Cura.MachineManager.activeMachineId key: model.key ? model.key : "None" watchedProperties: [ "limit_to_extruder" ] } Connections { target: item onShowTooltip: { tooltip.text = text; var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0); tooltip.show(position); tooltip.target.x = position.x + 1 } onHideTooltip: { tooltip.hide(); } } } } } } Cura.SidebarTooltip { id: tooltip } Component { id: settingTextField; Cura.SettingTextField { } } Component { id: settingComboBox; Cura.SettingComboBox { } } Component { id: settingExtruder; Cura.SettingExtruder { } } Component { id: settingCheckBox; Cura.SettingCheckBox { } } Component { id: settingCategory; Cura.SettingCategory { } } Component { id: settingUnknown; Cura.SettingUnknown { } } } rightButtons: Button { text: catalog.i18nc("@action:button", "Close") iconName: "dialog-close" onClicked: dialog.accept() } Button { objectName: "postProcessingSaveAreaButton" visible: activeScriptsList.count > 0 height: UM.Theme.getSize("save_button_save_to_button").height width: height tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts") onClicked: dialog.show() style: ButtonStyle { background: Rectangle { id: deviceSelectionIcon border.width: UM.Theme.getSize("default_lining").width border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") : control.pressed ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") color: !control.enabled ? UM.Theme.getColor("action_button_disabled") : control.pressed ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") Behavior on color { ColorAnimation { duration: 50; } } anchors.left: parent.left anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2); width: parent.height height: parent.height UM.RecolorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: Math.round(parent.width / 2) height: Math.round(parent.height / 2) sourceSize.width: width sourceSize.height: height color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : control.pressed ? UM.Theme.getColor("action_button_active_text") : control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text"); source: "postprocessing.svg" } } label: Label{ } } } }