CustomConfiguration.qml 15 KB

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