CustomConfiguration.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. //Copyright (c) 2022 Ultimaker B.V.
  2. //Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.6
  4. import QtQuick.Controls 2.0
  5. import Cura 1.0 as Cura
  6. import UM 1.5 as UM
  7. // Simple button for displaying text and changes appearance for various states: enabled, valueError, valueWarning
  8. // - and hovered. Mainly used in CustomConfiguration.qml
  9. Item
  10. {
  11. UM.I18nCatalog
  12. {
  13. id: catalog
  14. name: "cura"
  15. }
  16. width: parent.width
  17. height: childrenRect.height
  18. UM.Label
  19. {
  20. id: header
  21. text: catalog.i18nc("@header", "Custom")
  22. font: UM.Theme.getFont("medium")
  23. color: UM.Theme.getColor("small_button_text")
  24. height: contentHeight
  25. anchors
  26. {
  27. top: parent.top
  28. left: parent.left
  29. right: parent.right
  30. }
  31. }
  32. // Printer type selector.
  33. Item
  34. {
  35. id: printerTypeSelectorRow
  36. visible:
  37. {
  38. return Cura.MachineManager.printerOutputDevices.length >= 1 //If connected...
  39. && Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null //...and we have configuration information...
  40. && Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1; //...and there is more than one type of printer in the configuration list.
  41. }
  42. height: visible ? childrenRect.height : 0
  43. anchors
  44. {
  45. left: parent.left
  46. right: parent.right
  47. top: header.bottom
  48. topMargin: visible ? UM.Theme.getSize("default_margin").height : 0
  49. }
  50. UM.Label
  51. {
  52. text: catalog.i18nc("@label", "Printer")
  53. width: Math.round(parent.width * 0.3) - UM.Theme.getSize("default_margin").width
  54. height: contentHeight
  55. anchors.verticalCenter: printerTypeSelector.verticalCenter
  56. anchors.left: parent.left
  57. }
  58. Button
  59. {
  60. id: printerTypeSelector
  61. text: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.definition.name: ""
  62. height: UM.Theme.getSize("print_setup_big_item").height
  63. width: Math.round(parent.width * 0.7) + UM.Theme.getSize("default_margin").width
  64. anchors.right: parent.right
  65. onClicked: menu.open()
  66. //style: UM.Theme.styles.print_setup_header_button
  67. Cura.PrinterTypeMenu { id: menu}
  68. }
  69. }
  70. UM.TabRow
  71. {
  72. id: tabBar
  73. anchors.top: printerTypeSelectorRow.bottom
  74. anchors.topMargin: UM.Theme.getSize("default_margin").height
  75. visible: extrudersModel.count > 1
  76. Repeater
  77. {
  78. id: repeater
  79. model: extrudersModel
  80. delegate: UM.TabRowButton
  81. {
  82. checked: model.index == 0
  83. contentItem: Item
  84. {
  85. Cura.ExtruderIcon
  86. {
  87. anchors.horizontalCenter: parent.horizontalCenter
  88. materialColor: model.color
  89. extruderEnabled: model.enabled
  90. width: parent.height
  91. height: parent.height
  92. }
  93. }
  94. onClicked:
  95. {
  96. Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex)
  97. }
  98. }
  99. }
  100. //When active extruder changes for some other reason, switch tabs.
  101. //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex!
  102. //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead.
  103. Connections
  104. {
  105. target: Cura.ExtruderManager
  106. function onActiveExtruderChanged()
  107. {
  108. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
  109. }
  110. }
  111. // Can't use 'item: ...activeExtruderIndex' directly apparently, see also the comment on the previous block.
  112. onVisibleChanged:
  113. {
  114. if (tabBar.visible)
  115. {
  116. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
  117. }
  118. }
  119. //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt.
  120. //This causes the currentIndex of the tab to be in an invalid position which resets it to 0.
  121. //Therefore we need to change it back to what it was: The active extruder index.
  122. Connections
  123. {
  124. target: repeater.model
  125. function onModelChanged()
  126. {
  127. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex)
  128. }
  129. }
  130. }
  131. Rectangle
  132. {
  133. width: parent.width
  134. height: childrenRect.height
  135. anchors.top: tabBar.bottom
  136. radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0
  137. border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0
  138. border.color: UM.Theme.getColor("lining")
  139. color: UM.Theme.getColor("main_background")
  140. //Remove rounding and lining at the top.
  141. Rectangle
  142. {
  143. width: parent.width
  144. height: parent.radius
  145. anchors.top: parent.top
  146. color: UM.Theme.getColor("lining")
  147. visible: tabBar.visible
  148. Rectangle
  149. {
  150. anchors
  151. {
  152. left: parent.left
  153. leftMargin: parent.parent.border.width
  154. right: parent.right
  155. rightMargin: parent.parent.border.width
  156. top: parent.top
  157. }
  158. height: parent.parent.radius
  159. color: parent.parent.color
  160. }
  161. }
  162. Column
  163. {
  164. id: selectors
  165. padding: UM.Theme.getSize("default_margin").width
  166. spacing: UM.Theme.getSize("default_margin").height
  167. property var model: extrudersModel.items[tabBar.currentIndex]
  168. readonly property real paddedWidth: parent.width - padding * 2
  169. property real textWidth: Math.round(paddedWidth * 0.3)
  170. property real controlWidth:
  171. {
  172. if(instructionLink == "")
  173. {
  174. return paddedWidth - textWidth
  175. }
  176. else
  177. {
  178. return paddedWidth - textWidth - UM.Theme.getSize("print_setup_big_item").height * 0.5 - UM.Theme.getSize("default_margin").width
  179. }
  180. }
  181. property string instructionLink: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "instruction_link"): ""
  182. Row
  183. {
  184. height: visible ? UM.Theme.getSize("setting_control").height : 0
  185. visible: extrudersModel.count > 1 // If there is only one extruder, there is no point to enable/disable that.
  186. UM.Label
  187. {
  188. text: catalog.i18nc("@label", "Enabled")
  189. height: parent.height
  190. width: selectors.textWidth
  191. }
  192. UM.CheckBox
  193. {
  194. id: enabledCheckbox
  195. enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder.
  196. height: parent.height
  197. Binding
  198. {
  199. target: enabledCheckbox
  200. property: "checked"
  201. value: Cura.MachineManager.activeStack.isEnabled
  202. when: Cura.MachineManager.activeStack != null
  203. }
  204. /* Use a MouseArea to process the click on this checkbox.
  205. This is necessary because actually clicking the checkbox
  206. causes the "checked" property to be overwritten. After
  207. it's been overwritten, the original link that made it
  208. depend on the active extruder stack is broken. */
  209. MouseArea
  210. {
  211. anchors.fill: parent
  212. onClicked:
  213. {
  214. if(!parent.enabled)
  215. {
  216. return
  217. }
  218. // Already update the visual indication
  219. parent.checked = !parent.checked
  220. // Update the settings on the background!
  221. Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, parent.checked)
  222. }
  223. }
  224. }
  225. }
  226. Row
  227. {
  228. height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
  229. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
  230. UM.Label
  231. {
  232. text: catalog.i18nc("@label", "Material")
  233. height: parent.height
  234. width: selectors.textWidth
  235. }
  236. Cura.PrintSetupHeaderButton
  237. {
  238. id: materialSelection
  239. property bool valueError: Cura.MachineManager.activeStack !== null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible") !== "True" : true
  240. property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported
  241. text: Cura.MachineManager.activeStack !== null ? Cura.MachineManager.activeStack.material.name : ""
  242. tooltip: text
  243. enabled: enabledCheckbox.checked
  244. width: selectors.controlWidth
  245. height: parent.height
  246. anchors.verticalCenter: parent.verticalCenter
  247. focusPolicy: Qt.ClickFocus
  248. Cura.MaterialMenu
  249. {
  250. id: materialsMenu
  251. width: materialSelection.width
  252. extruderIndex: Cura.ExtruderManager.activeExtruderIndex
  253. updateModels: materialSelection.visible
  254. }
  255. onClicked: materialsMenu.popup(0, height - UM.Theme.getSize("default_lining").height)
  256. }
  257. Item
  258. {
  259. width: instructionButton.width + 2 * UM.Theme.getSize("narrow_margin").width
  260. height: instructionButton.visible ? materialSelection.height: 0
  261. Button
  262. {
  263. id: instructionButton
  264. hoverEnabled: true
  265. contentItem: Item {}
  266. height: UM.Theme.getSize("small_button").height
  267. width: UM.Theme.getSize("small_button").width
  268. anchors.centerIn: parent
  269. background: UM.ColorImage
  270. {
  271. source: UM.Theme.getIcon("Guide")
  272. color: instructionButton.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("icon")
  273. }
  274. visible: selectors.instructionLink != ""
  275. onClicked:Qt.openUrlExternally(selectors.instructionLink)
  276. }
  277. }
  278. }
  279. Row
  280. {
  281. height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
  282. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
  283. UM.Label
  284. {
  285. text: Cura.MachineManager.activeDefinitionVariantsName
  286. height: parent.height
  287. width: selectors.textWidth
  288. }
  289. Cura.PrintSetupHeaderButton
  290. {
  291. id: variantSelection
  292. text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.variant.name : ""
  293. tooltip: text
  294. height: parent.height
  295. width: selectors.controlWidth
  296. anchors.verticalCenter: parent.verticalCenter
  297. focusPolicy: Qt.ClickFocus
  298. enabled: enabledCheckbox.checked
  299. Cura.NozzleMenu
  300. {
  301. id: nozzlesMenu
  302. extruderIndex: Cura.ExtruderManager.activeExtruderIndex
  303. width: variantSelection.width
  304. }
  305. onClicked: nozzlesMenu.popup(0, height - UM.Theme.getSize("default_lining").height)
  306. }
  307. }
  308. Row
  309. {
  310. id: warnings
  311. height: visible ? childrenRect.height : 0
  312. visible: buildplateCompatibilityError || buildplateCompatibilityWarning
  313. property bool buildplateCompatibilityError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
  314. property bool buildplateCompatibilityWarning: Cura.MachineManager.variantBuildplateUsable
  315. // This is a space holder aligning the warning messages.
  316. UM.Label
  317. {
  318. text: ""
  319. width: selectors.textWidth
  320. }
  321. Item
  322. {
  323. width: selectors.controlWidth
  324. height: childrenRect.height
  325. UM.ColorImage
  326. {
  327. id: warningImage
  328. anchors.left: parent.left
  329. source: UM.Theme.getIcon("Warning")
  330. width: UM.Theme.getSize("section_icon").width
  331. height: UM.Theme.getSize("section_icon").height
  332. color: UM.Theme.getColor("material_compatibility_warning")
  333. visible: !Cura.MachineManager.isCurrentSetupSupported || warnings.buildplateCompatibilityError || warnings.buildplateCompatibilityWarning
  334. }
  335. UM.Label
  336. {
  337. id: materialCompatibilityLabel
  338. anchors.left: warningImage.right
  339. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  340. width: selectors.controlWidth - warningImage.width - UM.Theme.getSize("default_margin").width
  341. text: catalog.i18nc("@label", "Use glue for better adhesion with this material combination.")
  342. visible: CuraSDKVersion == "dev" ? false : warnings.buildplateCompatibilityError || warnings.buildplateCompatibilityWarning
  343. wrapMode: Text.WordWrap
  344. }
  345. }
  346. }
  347. }
  348. }
  349. }