PostProcessingPlugin.qml 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  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. elide: Text.ElideRight
  58. }
  59. ListView
  60. {
  61. id: activeScriptsList
  62. anchors.top: activeScriptsHeader.bottom
  63. anchors.topMargin: base.textMargin
  64. anchors.left: parent.left
  65. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  66. anchors.right: parent.right
  67. anchors.rightMargin: base.textMargin
  68. height: childrenRect.height
  69. model: manager.scriptList
  70. delegate: Item
  71. {
  72. width: parent.width
  73. height: activeScriptButton.height
  74. Button
  75. {
  76. id: activeScriptButton
  77. text: manager.getScriptLabelByKey(modelData.toString())
  78. exclusiveGroup: selectedScriptGroup
  79. checkable: true
  80. checked: {
  81. if (manager.selectedScriptIndex == index)
  82. {
  83. base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
  84. return true
  85. }
  86. else
  87. {
  88. return false
  89. }
  90. }
  91. onClicked:
  92. {
  93. forceActiveFocus()
  94. manager.setSelectedScriptIndex(index)
  95. base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
  96. }
  97. width: parent.width
  98. height: UM.Theme.getSize("setting").height
  99. style: ButtonStyle
  100. {
  101. background: Rectangle
  102. {
  103. color: activeScriptButton.checked ? palette.highlight : "transparent"
  104. width: parent.width
  105. height: parent.height
  106. }
  107. label: Label
  108. {
  109. wrapMode: Text.Wrap
  110. text: control.text
  111. elide: Text.ElideRight
  112. color: activeScriptButton.checked ? palette.highlightedText : palette.text
  113. }
  114. }
  115. }
  116. Button
  117. {
  118. id: removeButton
  119. text: "x"
  120. width: 20 * screenScaleFactor
  121. height: 20 * screenScaleFactor
  122. anchors.right:parent.right
  123. anchors.rightMargin: base.textMargin
  124. anchors.verticalCenter: parent.verticalCenter
  125. onClicked: manager.removeScriptByIndex(index)
  126. style: ButtonStyle
  127. {
  128. label: Item
  129. {
  130. UM.RecolorImage
  131. {
  132. anchors.verticalCenter: parent.verticalCenter
  133. anchors.horizontalCenter: parent.horizontalCenter
  134. width: Math.round(control.width / 2.7)
  135. height: Math.round(control.height / 2.7)
  136. sourceSize.height: width
  137. color: palette.text
  138. source: UM.Theme.getIcon("cross1")
  139. }
  140. }
  141. }
  142. }
  143. Button
  144. {
  145. id: downButton
  146. text: ""
  147. anchors.right: removeButton.left
  148. anchors.verticalCenter: parent.verticalCenter
  149. enabled: index != manager.scriptList.length - 1
  150. width: 20 * screenScaleFactor
  151. height: 20 * screenScaleFactor
  152. onClicked:
  153. {
  154. if (manager.selectedScriptIndex == index)
  155. {
  156. manager.setSelectedScriptIndex(index + 1)
  157. }
  158. return manager.moveScript(index, index + 1)
  159. }
  160. style: ButtonStyle
  161. {
  162. label: Item
  163. {
  164. UM.RecolorImage
  165. {
  166. anchors.verticalCenter: parent.verticalCenter
  167. anchors.horizontalCenter: parent.horizontalCenter
  168. width: Math.round(control.width / 2.5)
  169. height: Math.round(control.height / 2.5)
  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.height: width
  205. color: control.enabled ? palette.text : disabledPalette.text
  206. source: UM.Theme.getIcon("arrow_top")
  207. }
  208. }
  209. }
  210. }
  211. }
  212. }
  213. Button
  214. {
  215. id: addButton
  216. text: catalog.i18nc("@action", "Add a script")
  217. anchors.left: parent.left
  218. anchors.leftMargin: base.textMargin
  219. anchors.top: activeScriptsList.bottom
  220. anchors.topMargin: base.textMargin
  221. menu: scriptsMenu
  222. style: ButtonStyle
  223. {
  224. label: Label
  225. {
  226. text: control.text
  227. }
  228. }
  229. }
  230. Menu
  231. {
  232. id: scriptsMenu
  233. Instantiator
  234. {
  235. model: manager.loadedScriptList
  236. MenuItem
  237. {
  238. text: manager.getScriptLabelByKey(modelData.toString())
  239. onTriggered: manager.addScriptToList(modelData.toString())
  240. }
  241. onObjectAdded: scriptsMenu.insertItem(index, object);
  242. onObjectRemoved: scriptsMenu.removeItem(object);
  243. }
  244. }
  245. }
  246. Rectangle
  247. {
  248. color: UM.Theme.getColor("main_background")
  249. anchors.left: activeScripts.right
  250. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  251. anchors.right: parent.right
  252. height: parent.height
  253. id: settingsPanel
  254. Label
  255. {
  256. id: scriptSpecsHeader
  257. text: manager.selectedScriptIndex == -1 ? catalog.i18nc("@label", "Settings") : base.activeScriptName
  258. anchors.top: parent.top
  259. anchors.topMargin: base.textMargin
  260. anchors.left: parent.left
  261. anchors.leftMargin: base.textMargin
  262. anchors.right: parent.right
  263. anchors.rightMargin: base.textMargin
  264. elide: Text.ElideRight
  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. containerStack: Cura.MachineManager.activeMachine
  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.height: height
  457. color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") :
  458. control.pressed ? UM.Theme.getColor("action_button_active_text") :
  459. control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text");
  460. source: "postprocessing.svg"
  461. }
  462. }
  463. label: Label{ }
  464. }
  465. }
  466. }