PostProcessingPlugin.qml 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V.
  2. // The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Controls.Styles 1.1
  6. import QtQuick.Layouts 1.1
  7. import QtQuick.Dialogs 1.1
  8. import QtQuick.Window 2.2
  9. import UM 1.2 as UM
  10. import Cura 1.0 as Cura
  11. UM.Dialog
  12. {
  13. id: dialog
  14. title: catalog.i18nc("@title:window", "Post Processing Plugin")
  15. width: 700 * screenScaleFactor;
  16. height: 500 * screenScaleFactor;
  17. minimumWidth: 400 * screenScaleFactor;
  18. minimumHeight: 250 * screenScaleFactor;
  19. onVisibleChanged:
  20. {
  21. 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.
  22. {
  23. manager.writeScriptsToStack();
  24. }
  25. }
  26. Item
  27. {
  28. UM.I18nCatalog{id: catalog; name:"cura"}
  29. id: base
  30. property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width)
  31. property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
  32. property string activeScriptName
  33. SystemPalette{ id: palette }
  34. SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled }
  35. anchors.fill: parent
  36. ExclusiveGroup
  37. {
  38. id: selectedScriptGroup
  39. }
  40. Item
  41. {
  42. id: activeScripts
  43. anchors.left: parent.left
  44. width: base.columnWidth
  45. height: parent.height
  46. Label
  47. {
  48. id: activeScriptsHeader
  49. text: catalog.i18nc("@label", "Post Processing Scripts")
  50. anchors.top: parent.top
  51. anchors.topMargin: base.textMargin
  52. anchors.left: parent.left
  53. anchors.leftMargin: base.textMargin
  54. anchors.right: parent.right
  55. anchors.rightMargin: base.textMargin
  56. font: UM.Theme.getFont("large")
  57. }
  58. ListView
  59. {
  60. id: activeScriptsList
  61. anchors.top: activeScriptsHeader.bottom
  62. anchors.topMargin: base.textMargin
  63. anchors.left: parent.left
  64. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  65. anchors.right: parent.right
  66. anchors.rightMargin: base.textMargin
  67. height: childrenRect.height
  68. model: manager.scriptList
  69. delegate: Item
  70. {
  71. width: parent.width
  72. height: activeScriptButton.height
  73. Button
  74. {
  75. id: activeScriptButton
  76. text: manager.getScriptLabelByKey(modelData.toString())
  77. exclusiveGroup: selectedScriptGroup
  78. checkable: true
  79. checked: {
  80. if (manager.selectedScriptIndex == index)
  81. {
  82. base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
  83. return true
  84. }
  85. else
  86. {
  87. return false
  88. }
  89. }
  90. onClicked:
  91. {
  92. forceActiveFocus()
  93. manager.setSelectedScriptIndex(index)
  94. base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
  95. }
  96. width: parent.width
  97. height: UM.Theme.getSize("setting").height
  98. style: ButtonStyle
  99. {
  100. background: Rectangle
  101. {
  102. color: activeScriptButton.checked ? palette.highlight : "transparent"
  103. width: parent.width
  104. height: parent.height
  105. }
  106. label: Label
  107. {
  108. wrapMode: Text.Wrap
  109. text: control.text
  110. color: activeScriptButton.checked ? palette.highlightedText : palette.text
  111. }
  112. }
  113. }
  114. Button
  115. {
  116. id: removeButton
  117. text: "x"
  118. width: 20 * screenScaleFactor
  119. height: 20 * screenScaleFactor
  120. anchors.right:parent.right
  121. anchors.rightMargin: base.textMargin
  122. anchors.verticalCenter: parent.verticalCenter
  123. onClicked: manager.removeScriptByIndex(index)
  124. style: ButtonStyle
  125. {
  126. label: Item
  127. {
  128. UM.RecolorImage
  129. {
  130. anchors.verticalCenter: parent.verticalCenter
  131. anchors.horizontalCenter: parent.horizontalCenter
  132. width: Math.round(control.width / 2.7)
  133. height: Math.round(control.height / 2.7)
  134. sourceSize.width: width
  135. sourceSize.height: width
  136. color: palette.text
  137. source: UM.Theme.getIcon("cross1")
  138. }
  139. }
  140. }
  141. }
  142. Button
  143. {
  144. id: downButton
  145. text: ""
  146. anchors.right: removeButton.left
  147. anchors.verticalCenter: parent.verticalCenter
  148. enabled: index != manager.scriptList.length - 1
  149. width: 20 * screenScaleFactor
  150. height: 20 * screenScaleFactor
  151. onClicked:
  152. {
  153. if (manager.selectedScriptIndex == index)
  154. {
  155. manager.setSelectedScriptIndex(index + 1)
  156. }
  157. return manager.moveScript(index, index + 1)
  158. }
  159. style: ButtonStyle
  160. {
  161. label: Item
  162. {
  163. UM.RecolorImage
  164. {
  165. anchors.verticalCenter: parent.verticalCenter
  166. anchors.horizontalCenter: parent.horizontalCenter
  167. width: Math.round(control.width / 2.5)
  168. height: Math.round(control.height / 2.5)
  169. sourceSize.width: width
  170. sourceSize.height: width
  171. color: control.enabled ? palette.text : disabledPalette.text
  172. source: UM.Theme.getIcon("arrow_bottom")
  173. }
  174. }
  175. }
  176. }
  177. Button
  178. {
  179. id: upButton
  180. text: ""
  181. enabled: index != 0
  182. width: 20 * screenScaleFactor
  183. height: 20 * screenScaleFactor
  184. anchors.right: downButton.left
  185. anchors.verticalCenter: parent.verticalCenter
  186. onClicked:
  187. {
  188. if (manager.selectedScriptIndex == index)
  189. {
  190. manager.setSelectedScriptIndex(index - 1)
  191. }
  192. return manager.moveScript(index, index - 1)
  193. }
  194. style: ButtonStyle
  195. {
  196. label: Item
  197. {
  198. UM.RecolorImage
  199. {
  200. anchors.verticalCenter: parent.verticalCenter
  201. anchors.horizontalCenter: parent.horizontalCenter
  202. width: Math.round(control.width / 2.5)
  203. height: Math.round(control.height / 2.5)
  204. sourceSize.width: width
  205. sourceSize.height: width
  206. color: control.enabled ? palette.text : disabledPalette.text
  207. source: UM.Theme.getIcon("arrow_top")
  208. }
  209. }
  210. }
  211. }
  212. }
  213. }
  214. Button
  215. {
  216. id: addButton
  217. text: catalog.i18nc("@action", "Add a script")
  218. anchors.left: parent.left
  219. anchors.leftMargin: base.textMargin
  220. anchors.top: activeScriptsList.bottom
  221. anchors.topMargin: base.textMargin
  222. menu: scriptsMenu
  223. style: ButtonStyle
  224. {
  225. label: Label
  226. {
  227. text: control.text
  228. }
  229. }
  230. }
  231. Menu
  232. {
  233. id: scriptsMenu
  234. Instantiator
  235. {
  236. model: manager.loadedScriptList
  237. MenuItem
  238. {
  239. text: manager.getScriptLabelByKey(modelData.toString())
  240. onTriggered: manager.addScriptToList(modelData.toString())
  241. }
  242. onObjectAdded: scriptsMenu.insertItem(index, object);
  243. onObjectRemoved: scriptsMenu.removeItem(object);
  244. }
  245. }
  246. }
  247. Rectangle
  248. {
  249. color: UM.Theme.getColor("sidebar")
  250. anchors.left: activeScripts.right
  251. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  252. anchors.right: parent.right
  253. height: parent.height
  254. id: settingsPanel
  255. Label
  256. {
  257. id: scriptSpecsHeader
  258. text: manager.selectedScriptIndex == -1 ? catalog.i18nc("@label", "Settings") : base.activeScriptName
  259. anchors.top: parent.top
  260. anchors.topMargin: base.textMargin
  261. anchors.left: parent.left
  262. anchors.leftMargin: base.textMargin
  263. anchors.right: parent.right
  264. anchors.rightMargin: base.textMargin
  265. height: 20 * screenScaleFactor
  266. font: UM.Theme.getFont("large")
  267. color: UM.Theme.getColor("text")
  268. }
  269. ScrollView
  270. {
  271. id: scrollView
  272. anchors.top: scriptSpecsHeader.bottom
  273. anchors.topMargin: settingsPanel.textMargin
  274. anchors.left: parent.left
  275. anchors.right: parent.right
  276. anchors.bottom: parent.bottom
  277. visible: manager.selectedScriptDefinitionId != ""
  278. style: UM.Theme.styles.scrollview;
  279. ListView
  280. {
  281. id: listview
  282. spacing: UM.Theme.getSize("default_lining").height
  283. model: UM.SettingDefinitionsModel
  284. {
  285. id: definitionsModel;
  286. containerId: manager.selectedScriptDefinitionId
  287. showAll: true
  288. }
  289. delegate:Loader
  290. {
  291. id: settingLoader
  292. width: parent.width
  293. height:
  294. {
  295. if(provider.properties.enabled == "True")
  296. {
  297. if(model.type != undefined)
  298. {
  299. return UM.Theme.getSize("section").height;
  300. }
  301. else
  302. {
  303. return 0;
  304. }
  305. }
  306. else
  307. {
  308. return 0;
  309. }
  310. }
  311. Behavior on height { NumberAnimation { duration: 100 } }
  312. opacity: provider.properties.enabled == "True" ? 1 : 0
  313. Behavior on opacity { NumberAnimation { duration: 100 } }
  314. enabled: opacity > 0
  315. property var definition: model
  316. property var settingDefinitionsModel: definitionsModel
  317. property var propertyProvider: provider
  318. property var globalPropertyProvider: inheritStackProvider
  319. //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
  320. //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
  321. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
  322. asynchronous: model.type != "enum" && model.type != "extruder"
  323. onLoaded: {
  324. settingLoader.item.showRevertButton = false
  325. settingLoader.item.showInheritButton = false
  326. settingLoader.item.showLinkedSettingIcon = false
  327. settingLoader.item.doDepthIndentation = true
  328. settingLoader.item.doQualityUserSettingEmphasis = false
  329. }
  330. sourceComponent:
  331. {
  332. switch(model.type)
  333. {
  334. case "int":
  335. return settingTextField
  336. case "float":
  337. return settingTextField
  338. case "enum":
  339. return settingComboBox
  340. case "extruder":
  341. return settingExtruder
  342. case "bool":
  343. return settingCheckBox
  344. case "str":
  345. return settingTextField
  346. case "category":
  347. return settingCategory
  348. default:
  349. return settingUnknown
  350. }
  351. }
  352. UM.SettingPropertyProvider
  353. {
  354. id: provider
  355. containerStackId: manager.selectedScriptStackId
  356. key: model.key ? model.key : "None"
  357. watchedProperties: [ "value", "enabled", "state", "validationState" ]
  358. storeIndex: 0
  359. }
  360. // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
  361. // so we bypass that to make a dedicated provider).
  362. UM.SettingPropertyProvider
  363. {
  364. id: inheritStackProvider
  365. containerStackId: Cura.MachineManager.activeMachineId
  366. key: model.key ? model.key : "None"
  367. watchedProperties: [ "limit_to_extruder" ]
  368. }
  369. Connections
  370. {
  371. target: item
  372. onShowTooltip:
  373. {
  374. tooltip.text = text;
  375. var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0);
  376. tooltip.show(position);
  377. tooltip.target.x = position.x + 1
  378. }
  379. onHideTooltip:
  380. {
  381. tooltip.hide();
  382. }
  383. }
  384. }
  385. }
  386. }
  387. }
  388. Cura.SidebarTooltip
  389. {
  390. id: tooltip
  391. }
  392. Component
  393. {
  394. id: settingTextField;
  395. Cura.SettingTextField { }
  396. }
  397. Component
  398. {
  399. id: settingComboBox;
  400. Cura.SettingComboBox { }
  401. }
  402. Component
  403. {
  404. id: settingExtruder;
  405. Cura.SettingExtruder { }
  406. }
  407. Component
  408. {
  409. id: settingCheckBox;
  410. Cura.SettingCheckBox { }
  411. }
  412. Component
  413. {
  414. id: settingCategory;
  415. Cura.SettingCategory { }
  416. }
  417. Component
  418. {
  419. id: settingUnknown;
  420. Cura.SettingUnknown { }
  421. }
  422. }
  423. rightButtons: Button
  424. {
  425. text: catalog.i18nc("@action:button", "Close")
  426. iconName: "dialog-close"
  427. onClicked: dialog.accept()
  428. }
  429. Button {
  430. objectName: "postProcessingSaveAreaButton"
  431. visible: activeScriptsList.count > 0
  432. height: UM.Theme.getSize("save_button_save_to_button").height
  433. width: height
  434. tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts")
  435. onClicked: dialog.show()
  436. style: ButtonStyle {
  437. background: Rectangle {
  438. id: deviceSelectionIcon
  439. border.width: UM.Theme.getSize("default_lining").width
  440. border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") :
  441. control.pressed ? UM.Theme.getColor("action_button_active_border") :
  442. control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border")
  443. color: !control.enabled ? UM.Theme.getColor("action_button_disabled") :
  444. control.pressed ? UM.Theme.getColor("action_button_active") :
  445. control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
  446. Behavior on color { ColorAnimation { duration: 50; } }
  447. anchors.left: parent.left
  448. anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2);
  449. width: parent.height
  450. height: parent.height
  451. UM.RecolorImage {
  452. anchors.verticalCenter: parent.verticalCenter
  453. anchors.horizontalCenter: parent.horizontalCenter
  454. width: Math.round(parent.width / 2)
  455. height: Math.round(parent.height / 2)
  456. sourceSize.width: width
  457. sourceSize.height: height
  458. color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") :
  459. control.pressed ? UM.Theme.getColor("action_button_active_text") :
  460. control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text");
  461. source: "postprocessing.svg"
  462. }
  463. }
  464. label: Label{ }
  465. }
  466. }
  467. }