ConfigurationMenu.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. // Copyright (c) 2018 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.10
  4. import QtQuick.Controls 2.3
  5. import QtQuick.Controls.Styles 1.4
  6. import QtQuick.Layouts 1.3
  7. import UM 1.4 as UM
  8. import Cura 1.0 as Cura
  9. /**
  10. * Menu that allows you to select the configuration of the current printer, such
  11. * as the nozzle sizes and materials in each extruder.
  12. */
  13. Cura.ExpandablePopup
  14. {
  15. id: base
  16. property var extrudersModel: CuraApplication.getExtrudersModel()
  17. UM.I18nCatalog
  18. {
  19. id: catalog
  20. name: "cura"
  21. }
  22. enum ConfigurationMethod
  23. {
  24. Auto,
  25. Custom
  26. }
  27. contentPadding: UM.Theme.getSize("default_lining").width
  28. enabled: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates : false; //Only let it drop down if there is any configuration that you could change.
  29. headerItem: Item
  30. {
  31. // Horizontal list that shows the extruders and their materials
  32. RowLayout
  33. {
  34. anchors.top: parent.top
  35. anchors.bottom: parent.bottom
  36. anchors.left: parent.left
  37. width: parent.width - UM.Theme.getSize("standard_arrow").width
  38. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
  39. Repeater
  40. {
  41. model: extrudersModel
  42. delegate: Item
  43. {
  44. id: extruderItem
  45. Layout.preferredWidth: Math.round(parent.width / extrudersModel.count)
  46. Layout.maximumWidth: Math.round(parent.width / extrudersModel.count)
  47. Layout.fillHeight: true
  48. property var extruderStack: Cura.MachineManager.activeMachine.extruders[model.index]
  49. property bool valueWarning: !Cura.ExtruderManager.getExtruderHasQualityForMaterial(extruderStack)
  50. property bool valueError: Cura.ContainerManager.getContainerMetaDataEntry(extruderStack.material.id, "compatible", "") != "True"
  51. // Extruder icon. Shows extruder index and has the same color as the active material.
  52. Cura.ExtruderIcon
  53. {
  54. id: extruderIcon
  55. materialColor: model.color
  56. extruderEnabled: model.enabled
  57. anchors.verticalCenter: parent.verticalCenter
  58. }
  59. MouseArea // Connection status tooltip hover area
  60. {
  61. id: tooltipHoverArea
  62. anchors.fill: parent
  63. hoverEnabled: tooltip.text != ""
  64. acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks
  65. onEntered:
  66. {
  67. base.mouseArea.entered() // we want both this and the outer area to be entered
  68. tooltip.show()
  69. }
  70. onExited: { tooltip.hide() }
  71. }
  72. Cura.ToolTip
  73. {
  74. id: tooltip
  75. x: 0
  76. y: parent.height + UM.Theme.getSize("default_margin").height
  77. width: UM.Theme.getSize("tooltip").width
  78. targetPoint: Qt.point(Math.round(extruderIcon.width / 2), 0)
  79. text:
  80. {
  81. if (!model.enabled)
  82. {
  83. return ""
  84. }
  85. if (extruderItem.valueError)
  86. {
  87. return catalog.i18nc("@tooltip", "The configuration of this extruder is not allowed, and prohibits slicing.")
  88. }
  89. if (extruderItem.valueWarning)
  90. {
  91. return catalog.i18nc("@tooltip", "There are no profiles matching the configuration of this extruder.")
  92. }
  93. return ""
  94. }
  95. }
  96. // Warning icon that indicates if no qualities are available for the variant/material combination for this extruder
  97. UM.RecolorImage
  98. {
  99. id: badge
  100. anchors
  101. {
  102. top: parent.top
  103. topMargin: - Math.round(height * 1 / 6)
  104. left: parent.left
  105. leftMargin: extruderIcon.width - Math.round(width * 5 / 6)
  106. }
  107. width: UM.Theme.getSize("icon_indicator").width
  108. height: UM.Theme.getSize("icon_indicator").height
  109. visible: model.enabled && (extruderItem.valueError || extruderItem.valueWarning)
  110. source:
  111. {
  112. if (extruderItem.valueError)
  113. {
  114. return UM.Theme.getIcon("ErrorBadge", "low")
  115. }
  116. if (extruderItem.valueWarning)
  117. {
  118. return UM.Theme.getIcon("WarningBadge", "low")
  119. }
  120. return ""
  121. }
  122. color:
  123. {
  124. if (extruderItem.valueError)
  125. {
  126. return UM.Theme.getColor("error")
  127. }
  128. if (extruderItem.valueWarning)
  129. {
  130. return UM.Theme.getColor("warning")
  131. }
  132. return "transparent"
  133. }
  134. // Make a themable circle in the background so we can change it in other themes
  135. Rectangle
  136. {
  137. id: iconBackground
  138. anchors.centerIn: parent
  139. width: parent.width - 1.5 //1.5 pixels smaller, (at least sqrt(2), regardless of screen pixel scale) so that the circle doesn't show up behind the icon due to anti-aliasing.
  140. height: parent.height - 1.5
  141. radius: width / 2
  142. z: parent.z - 1
  143. color:
  144. {
  145. if (extruderItem.valueError)
  146. {
  147. return UM.Theme.getColor("error_badge_background")
  148. }
  149. if (extruderItem.valueWarning)
  150. {
  151. return UM.Theme.getColor("warning_badge_background")
  152. }
  153. return "transparent"
  154. }
  155. }
  156. }
  157. Column
  158. {
  159. opacity: model.enabled ? 1 : UM.Theme.getColor("extruder_disabled").a
  160. spacing: 0
  161. visible: width > 0
  162. anchors
  163. {
  164. left: extruderIcon.right
  165. leftMargin: UM.Theme.getSize("default_margin").width
  166. verticalCenter: parent.verticalCenter
  167. right: parent.right
  168. rightMargin: UM.Theme.getSize("default_margin").width
  169. }
  170. // Label for the brand of the material
  171. Label
  172. {
  173. id: materialBrandNameLabel
  174. text: model.material_brand + " " + model.material_name
  175. elide: Text.ElideRight
  176. font: UM.Theme.getFont("default")
  177. color: UM.Theme.getColor("text")
  178. renderType: Text.NativeRendering
  179. width: parent.width
  180. visible: !truncated
  181. }
  182. Label
  183. {
  184. id: materialNameLabel
  185. text: model.material_name
  186. elide: Text.ElideRight
  187. font: UM.Theme.getFont("default")
  188. color: UM.Theme.getColor("text")
  189. renderType: Text.NativeRendering
  190. width: parent.width
  191. visible: !materialBrandNameLabel.visible && !truncated
  192. }
  193. Label
  194. {
  195. id: materialTypeLabel
  196. text: model.material_type
  197. elide: Text.ElideRight
  198. font: UM.Theme.getFont("default")
  199. color: UM.Theme.getColor("text")
  200. renderType: Text.NativeRendering
  201. width: parent.width
  202. visible: !materialBrandNameLabel.visible && !materialNameLabel.visible
  203. }
  204. // Label that shows the name of the variant
  205. Label
  206. {
  207. id: variantLabel
  208. visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
  209. text: model.variant
  210. elide: Text.ElideRight
  211. font: UM.Theme.getFont("default_bold")
  212. color: UM.Theme.getColor("text")
  213. renderType: Text.NativeRendering
  214. Layout.preferredWidth: parent.width
  215. }
  216. }
  217. }
  218. }
  219. }
  220. // Placeholder text if there is a configuration to select but no materials (so we can't show the materials per extruder).
  221. Label
  222. {
  223. text: catalog.i18nc("@label", "Select configuration")
  224. elide: Text.ElideRight
  225. font: UM.Theme.getFont("medium")
  226. color: UM.Theme.getColor("text")
  227. renderType: Text.NativeRendering
  228. visible: Cura.MachineManager.activeMachine ? !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates) : false
  229. anchors
  230. {
  231. left: parent.left
  232. leftMargin: UM.Theme.getSize("default_margin").width
  233. verticalCenter: parent.verticalCenter
  234. }
  235. }
  236. }
  237. contentItem: Column
  238. {
  239. id: popupItem
  240. width: UM.Theme.getSize("configuration_selector").width
  241. height: implicitHeight // Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up.
  242. padding: UM.Theme.getSize("default_margin").height
  243. spacing: UM.Theme.getSize("default_margin").height
  244. property bool is_connected: false // If current machine is connected to a printer. Only evaluated upon making popup visible.
  245. property int configuration_method: ConfigurationMenu.ConfigurationMethod.Custom // Type of configuration being used. Only evaluated upon making popup visible.
  246. property int manual_selected_method: -1 // It stores the configuration method selected by the user. By default the selected method is
  247. onVisibleChanged:
  248. {
  249. is_connected = Cura.MachineManager.activeMachine.hasRemoteConnection && Cura.MachineManager.printerConnected && Cura.MachineManager.printerOutputDevices[0].uniqueConfigurations.length > 0 //Re-evaluate.
  250. // If the printer is not connected or does not have configurations, we switch always to the custom mode. If is connected instead, the auto mode
  251. // or the previous state is selected
  252. configuration_method = is_connected ? (manual_selected_method == -1 ? ConfigurationMenu.ConfigurationMethod.Auto : manual_selected_method) : ConfigurationMenu.ConfigurationMethod.Custom
  253. }
  254. Item
  255. {
  256. width: parent.width - 2 * parent.padding
  257. height:
  258. {
  259. var height = 0
  260. if (autoConfiguration.visible)
  261. {
  262. height += autoConfiguration.height
  263. }
  264. if (customConfiguration.visible)
  265. {
  266. height += customConfiguration.height
  267. }
  268. return height
  269. }
  270. AutoConfiguration
  271. {
  272. id: autoConfiguration
  273. visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto
  274. }
  275. CustomConfiguration
  276. {
  277. id: customConfiguration
  278. visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom
  279. }
  280. }
  281. Rectangle
  282. {
  283. id: separator
  284. visible: buttonBar.visible
  285. x: -parent.padding
  286. width: parent.width
  287. height: UM.Theme.getSize("default_lining").height
  288. color: UM.Theme.getColor("lining")
  289. }
  290. //Allow switching between custom and auto.
  291. Item
  292. {
  293. id: buttonBar
  294. visible: popupItem.is_connected //Switching only makes sense if the "auto" part is possible.
  295. width: parent.width - 2 * parent.padding
  296. height: childrenRect.height
  297. Cura.SecondaryButton
  298. {
  299. id: goToCustom
  300. visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Auto
  301. text: catalog.i18nc("@label", "Custom")
  302. anchors.right: parent.right
  303. iconSource: UM.Theme.getIcon("ChevronSingleRight")
  304. isIconOnRightSide: true
  305. onClicked:
  306. {
  307. popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Custom
  308. popupItem.manual_selected_method = popupItem.configuration_method
  309. }
  310. }
  311. Cura.SecondaryButton
  312. {
  313. id: goToAuto
  314. visible: popupItem.configuration_method == ConfigurationMenu.ConfigurationMethod.Custom
  315. text: catalog.i18nc("@label", "Configurations")
  316. iconSource: UM.Theme.getIcon("ChevronSingleLeft")
  317. onClicked:
  318. {
  319. popupItem.configuration_method = ConfigurationMenu.ConfigurationMethod.Auto
  320. popupItem.manual_selected_method = popupItem.configuration_method
  321. }
  322. }
  323. }
  324. }
  325. Connections
  326. {
  327. target: Cura.MachineManager
  328. function onGlobalContainerChanged() { popupItem.manual_selected_method = -1 } // When switching printers, reset the value of the manual selected method
  329. }
  330. }