CustomConfiguration.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. anchors.horizontalCenter: parent.horizontalCenter
  86. anchors.verticalCenter: parent.verticalCenter
  87. width: Math.floor(tabBar.height / extrudersModel.count)
  88. height: tabBar.height
  89. Cura.ExtruderIcon
  90. {
  91. anchors.horizontalCenter: parent.horizontalCenter
  92. anchors.verticalCenter: parent.verticalCenter
  93. materialColor: model.color
  94. extruderEnabled: model.enabled
  95. }
  96. }
  97. onClicked:
  98. {
  99. Cura.ExtruderManager.setActiveExtruderIndex(tabBar.currentIndex)
  100. }
  101. }
  102. }
  103. //When active extruder changes for some other reason, switch tabs.
  104. //Don't directly link currentIndex to Cura.ExtruderManager.activeExtruderIndex!
  105. //This causes a segfault in Qt 5.11. Something with VisualItemModel removing index -1. We have to use setCurrentIndex instead.
  106. Connections
  107. {
  108. target: Cura.ExtruderManager
  109. function onActiveExtruderChanged()
  110. {
  111. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
  112. }
  113. }
  114. // Can't use 'item: ...activeExtruderIndex' directly apparently, see also the comment on the previous block.
  115. onVisibleChanged:
  116. {
  117. if (tabBar.visible)
  118. {
  119. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex);
  120. }
  121. }
  122. //When the model of the extruders is rebuilt, the list of extruders is briefly emptied and rebuilt.
  123. //This causes the currentIndex of the tab to be in an invalid position which resets it to 0.
  124. //Therefore we need to change it back to what it was: The active extruder index.
  125. Connections
  126. {
  127. target: repeater.model
  128. function onModelChanged()
  129. {
  130. tabBar.setCurrentIndex(Cura.ExtruderManager.activeExtruderIndex)
  131. }
  132. }
  133. }
  134. Rectangle
  135. {
  136. width: parent.width
  137. height: childrenRect.height
  138. anchors.top: tabBar.bottom
  139. radius: tabBar.visible ? UM.Theme.getSize("default_radius").width : 0
  140. border.width: tabBar.visible ? UM.Theme.getSize("default_lining").width : 0
  141. border.color: UM.Theme.getColor("lining")
  142. color: UM.Theme.getColor("main_background")
  143. //Remove rounding and lining at the top.
  144. Rectangle
  145. {
  146. width: parent.width
  147. height: parent.radius
  148. anchors.top: parent.top
  149. color: UM.Theme.getColor("lining")
  150. visible: tabBar.visible
  151. Rectangle
  152. {
  153. anchors
  154. {
  155. left: parent.left
  156. leftMargin: parent.parent.border.width
  157. right: parent.right
  158. rightMargin: parent.parent.border.width
  159. top: parent.top
  160. }
  161. height: parent.parent.radius
  162. color: parent.parent.color
  163. }
  164. }
  165. Column
  166. {
  167. id: selectors
  168. padding: UM.Theme.getSize("default_margin").width
  169. spacing: UM.Theme.getSize("default_margin").height
  170. property var model: extrudersModel.items[tabBar.currentIndex]
  171. readonly property real paddedWidth: parent.width - padding * 2
  172. property real textWidth: Math.round(paddedWidth * 0.3)
  173. property real controlWidth:
  174. {
  175. if(instructionLink == "")
  176. {
  177. return paddedWidth - textWidth
  178. }
  179. else
  180. {
  181. return paddedWidth - textWidth - UM.Theme.getSize("print_setup_big_item").height * 0.5 - UM.Theme.getSize("default_margin").width
  182. }
  183. }
  184. property string instructionLink: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "instruction_link"): ""
  185. Row
  186. {
  187. height: visible ? UM.Theme.getSize("setting_control").height : 0
  188. visible: extrudersModel.count > 1 // If there is only one extruder, there is no point to enable/disable that.
  189. UM.Label
  190. {
  191. text: catalog.i18nc("@label", "Enabled")
  192. height: parent.height
  193. width: selectors.textWidth
  194. }
  195. UM.CheckBox
  196. {
  197. id: enabledCheckbox
  198. enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder.
  199. height: parent.height
  200. Binding
  201. {
  202. target: enabledCheckbox
  203. property: "checked"
  204. value: Cura.MachineManager.activeStack.isEnabled
  205. when: Cura.MachineManager.activeStack != null
  206. }
  207. /* Use a MouseArea to process the click on this checkbox.
  208. This is necessary because actually clicking the checkbox
  209. causes the "checked" property to be overwritten. After
  210. it's been overwritten, the original link that made it
  211. depend on the active extruder stack is broken. */
  212. MouseArea
  213. {
  214. anchors.fill: parent
  215. onClicked:
  216. {
  217. if(!parent.enabled)
  218. {
  219. return
  220. }
  221. // Already update the visual indication
  222. parent.checked = !parent.checked
  223. // Update the settings on the background!
  224. Cura.MachineManager.setExtruderEnabled(Cura.ExtruderManager.activeExtruderIndex, parent.checked)
  225. }
  226. }
  227. }
  228. }
  229. Row
  230. {
  231. height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
  232. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
  233. UM.Label
  234. {
  235. text: catalog.i18nc("@label", "Material")
  236. height: parent.height
  237. width: selectors.textWidth
  238. }
  239. Cura.PrintSetupHeaderButton
  240. {
  241. id: materialSelection
  242. property bool valueError: Cura.MachineManager.activeStack !== null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible") !== "True" : true
  243. property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported
  244. text: Cura.MachineManager.activeStack !== null ? Cura.MachineManager.activeStack.material.name : ""
  245. tooltip: text
  246. enabled: enabledCheckbox.checked
  247. width: selectors.controlWidth
  248. height: parent.height
  249. anchors.verticalCenter: parent.verticalCenter
  250. focusPolicy: Qt.ClickFocus
  251. Cura.MaterialMenu
  252. {
  253. id: materialsMenu
  254. width: materialSelection.width
  255. extruderIndex: Cura.ExtruderManager.activeExtruderIndex
  256. updateModels: materialSelection.visible
  257. }
  258. onClicked: materialsMenu.popup(0, height - UM.Theme.getSize("default_lining").height)
  259. }
  260. Item
  261. {
  262. width: instructionButton.width + 2 * UM.Theme.getSize("narrow_margin").width
  263. height: instructionButton.visible ? materialSelection.height: 0
  264. Button
  265. {
  266. id: instructionButton
  267. hoverEnabled: true
  268. contentItem: Item {}
  269. height: UM.Theme.getSize("small_button").height
  270. width: UM.Theme.getSize("small_button").width
  271. anchors.centerIn: parent
  272. background: UM.ColorImage
  273. {
  274. source: UM.Theme.getIcon("Guide")
  275. color: instructionButton.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("icon")
  276. }
  277. visible: selectors.instructionLink != ""
  278. onClicked:Qt.openUrlExternally(selectors.instructionLink)
  279. }
  280. }
  281. }
  282. Row
  283. {
  284. height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
  285. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
  286. UM.Label
  287. {
  288. text: Cura.MachineManager.activeDefinitionVariantsName
  289. height: parent.height
  290. width: selectors.textWidth
  291. }
  292. Cura.PrintSetupHeaderButton
  293. {
  294. id: variantSelection
  295. text: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.variant.name : ""
  296. tooltip: text
  297. height: parent.height
  298. width: selectors.controlWidth
  299. anchors.verticalCenter: parent.verticalCenter
  300. focusPolicy: Qt.ClickFocus
  301. enabled: enabledCheckbox.checked
  302. Cura.NozzleMenu
  303. {
  304. id: nozzlesMenu
  305. extruderIndex: Cura.ExtruderManager.activeExtruderIndex
  306. width: variantSelection.width
  307. }
  308. onClicked: nozzlesMenu.popup(0, height - UM.Theme.getSize("default_lining").height)
  309. }
  310. }
  311. Row
  312. {
  313. id: warnings
  314. height: visible ? childrenRect.height : 0
  315. visible: buildplateCompatibilityError || buildplateCompatibilityWarning
  316. property bool buildplateCompatibilityError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
  317. property bool buildplateCompatibilityWarning: Cura.MachineManager.variantBuildplateUsable
  318. // This is a space holder aligning the warning messages.
  319. UM.Label
  320. {
  321. text: ""
  322. width: selectors.textWidth
  323. }
  324. Item
  325. {
  326. width: selectors.controlWidth
  327. height: childrenRect.height
  328. UM.ColorImage
  329. {
  330. id: warningImage
  331. anchors.left: parent.left
  332. source: UM.Theme.getIcon("Warning")
  333. width: UM.Theme.getSize("section_icon").width
  334. height: UM.Theme.getSize("section_icon").height
  335. color: UM.Theme.getColor("material_compatibility_warning")
  336. visible: !Cura.MachineManager.isCurrentSetupSupported || warnings.buildplateCompatibilityError || warnings.buildplateCompatibilityWarning
  337. }
  338. UM.Label
  339. {
  340. id: materialCompatibilityLabel
  341. anchors.left: warningImage.right
  342. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  343. width: selectors.controlWidth - warningImage.width - UM.Theme.getSize("default_margin").width
  344. text: catalog.i18nc("@label", "Use glue for better adhesion with this material combination.")
  345. visible: CuraSDKVersion == "dev" ? false : warnings.buildplateCompatibilityError || warnings.buildplateCompatibilityWarning
  346. wrapMode: Text.WordWrap
  347. }
  348. }
  349. }
  350. }
  351. }
  352. }