ConfigurationMenu.qml 15 KB

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