CustomConfiguration.qml 14 KB

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