ExtruderBox.qml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. //Copyright (c) 2019 Ultimaker B.V.
  2. //Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 2.2
  5. import QtQuick.Controls.Styles 2.2
  6. import QtQuick.Layouts 1.1
  7. import UM 1.2 as UM
  8. import Cura 1.0 as Cura
  9. Item
  10. {
  11. property alias color: background.color
  12. property var extruderModel
  13. property var position: index
  14. property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
  15. implicitWidth: parent.width
  16. implicitHeight: UM.Theme.getSize("print_setup_extruder_box").height
  17. UM.SettingPropertyProvider
  18. {
  19. id: extruderTemperature
  20. containerStackId: Cura.ExtruderManager.extruderIds[position]
  21. key: "material_print_temperature"
  22. watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"]
  23. storeIndex: 0
  24. property var resolve: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine ? properties.resolve : "None"
  25. }
  26. Rectangle
  27. {
  28. id: background
  29. anchors.fill: parent
  30. Label //Extruder name.
  31. {
  32. text: Cura.MachineManager.activeMachine.extruderList[position].name !== "" ? Cura.MachineManager.activeMachine.extruderList[position].name : catalog.i18nc("@label", "Extruder")
  33. color: UM.Theme.getColor("text")
  34. font: UM.Theme.getFont("default")
  35. anchors.left: parent.left
  36. anchors.top: parent.top
  37. anchors.margins: UM.Theme.getSize("default_margin").width
  38. }
  39. Label //Target temperature.
  40. {
  41. id: extruderTargetTemperature
  42. text: Math.round(extruderModel.targetHotendTemperature) + "°C"
  43. font: UM.Theme.getFont("default_bold")
  44. color: UM.Theme.getColor("text_inactive")
  45. anchors.right: parent.right
  46. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  47. anchors.bottom: extruderCurrentTemperature.bottom
  48. MouseArea //For tooltip.
  49. {
  50. id: extruderTargetTemperatureTooltipArea
  51. hoverEnabled: true
  52. anchors.fill: parent
  53. onHoveredChanged:
  54. {
  55. if (containsMouse)
  56. {
  57. base.showTooltip(
  58. base,
  59. {x: 0, y: extruderTargetTemperature.mapToItem(base, 0, Math.floor(-parent.height / 4)).y},
  60. catalog.i18nc("@tooltip", "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off.")
  61. );
  62. }
  63. else
  64. {
  65. base.hideTooltip();
  66. }
  67. }
  68. }
  69. }
  70. Label //Temperature indication.
  71. {
  72. id: extruderCurrentTemperature
  73. text: Math.round(extruderModel.hotendTemperature) + "°C"
  74. color: UM.Theme.getColor("text")
  75. font: UM.Theme.getFont("large_bold")
  76. anchors.right: extruderTargetTemperature.left
  77. anchors.top: parent.top
  78. anchors.margins: UM.Theme.getSize("default_margin").width
  79. MouseArea //For tooltip.
  80. {
  81. id: extruderCurrentTemperatureTooltipArea
  82. hoverEnabled: true
  83. anchors.fill: parent
  84. onHoveredChanged:
  85. {
  86. if (containsMouse)
  87. {
  88. base.showTooltip(
  89. base,
  90. {x: 0, y: parent.mapToItem(base, 0, Math.floor(-parent.height / 4)).y},
  91. catalog.i18nc("@tooltip", "The current temperature of this hotend.")
  92. );
  93. }
  94. else
  95. {
  96. base.hideTooltip();
  97. }
  98. }
  99. }
  100. }
  101. Rectangle //Input field for pre-heat temperature.
  102. {
  103. id: preheatTemperatureControl
  104. color: !enabled ? UM.Theme.getColor("setting_control_disabled") : showError ? UM.Theme.getColor("setting_validation_error_background") : UM.Theme.getColor("setting_validation_ok")
  105. property var showError:
  106. {
  107. if(extruderTemperature.properties.maximum_value != "None" && extruderTemperature.properties.maximum_value < Math.floor(preheatTemperatureInput.text))
  108. {
  109. return true;
  110. } else
  111. {
  112. return false;
  113. }
  114. }
  115. enabled:
  116. {
  117. if (extruderModel == null)
  118. {
  119. return false; //Can't preheat if not connected.
  120. }
  121. if (!connectedPrinter.acceptsCommands)
  122. {
  123. return false; //Not allowed to do anything.
  124. }
  125. if (connectedPrinter.activePrinter && connectedPrinter.activePrinter.activePrintJob)
  126. {
  127. if((["printing", "pre_print", "resuming", "pausing", "paused", "error", "offline"]).indexOf(connectedPrinter.activePrinter.activePrintJob.state) != -1)
  128. {
  129. return false; //Printer is in a state where it can't react to pre-heating.
  130. }
  131. }
  132. return true;
  133. }
  134. border.width: UM.Theme.getSize("default_lining").width
  135. border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : preheatTemperatureInputMouseArea.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
  136. anchors.right: preheatButton.left
  137. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  138. anchors.bottom: parent.bottom
  139. anchors.bottomMargin: UM.Theme.getSize("default_margin").height
  140. width: UM.Theme.getSize("monitor_preheat_temperature_control").width
  141. height: UM.Theme.getSize("monitor_preheat_temperature_control").height
  142. visible: extruderModel != null ? enabled && extruderModel.canPreHeatHotends && !extruderModel.isPreheating : true
  143. Rectangle //Highlight of input field.
  144. {
  145. anchors.fill: parent
  146. anchors.margins: UM.Theme.getSize("default_lining").width
  147. color: UM.Theme.getColor("setting_control_highlight")
  148. opacity: preheatTemperatureControl.hovered ? 1.0 : 0
  149. }
  150. MouseArea //Change cursor on hovering.
  151. {
  152. id: preheatTemperatureInputMouseArea
  153. hoverEnabled: true
  154. anchors.fill: parent
  155. cursorShape: Qt.IBeamCursor
  156. onHoveredChanged:
  157. {
  158. if (containsMouse)
  159. {
  160. base.showTooltip(
  161. base,
  162. {x: 0, y: preheatTemperatureInputMouseArea.mapToItem(base, 0, -parent.height/2).y},
  163. catalog.i18nc("@tooltip of temperature input", "The temperature to pre-heat the hotend to.")
  164. );
  165. }
  166. else
  167. {
  168. base.hideTooltip();
  169. }
  170. }
  171. }
  172. Label
  173. {
  174. id: unit
  175. anchors.right: parent.right
  176. anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
  177. anchors.verticalCenter: parent.verticalCenter
  178. text: "°C";
  179. color: UM.Theme.getColor("setting_unit")
  180. font: UM.Theme.getFont("default")
  181. }
  182. TextInput
  183. {
  184. id: preheatTemperatureInput
  185. font: UM.Theme.getFont("default")
  186. color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
  187. selectByMouse: true
  188. maximumLength: 5
  189. enabled: parent.enabled
  190. validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex.
  191. anchors.left: parent.left
  192. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  193. anchors.right: unit.left
  194. anchors.verticalCenter: parent.verticalCenter
  195. renderType: Text.NativeRendering
  196. text:
  197. {
  198. if (!extruderTemperature.properties.value)
  199. {
  200. return "";
  201. }
  202. else
  203. {
  204. return extruderTemperature.properties.value;
  205. }
  206. }
  207. }
  208. }
  209. Button //The pre-heat button.
  210. {
  211. id: preheatButton
  212. height: UM.Theme.getSize("setting_control").height
  213. visible: extruderModel != null ? extruderModel.canPreHeatHotends: true
  214. enabled:
  215. {
  216. if (!preheatTemperatureControl.enabled)
  217. {
  218. return false; //Not connected, not authenticated or printer is busy.
  219. }
  220. if (extruderModel.isPreheating)
  221. {
  222. return true;
  223. }
  224. if (extruderTemperature.properties.minimum_value != "None" && Math.floor(preheatTemperatureInput.text) < Math.floor(extruderTemperature.properties.minimum_value))
  225. {
  226. return false; //Target temperature too low.
  227. }
  228. if (extruderTemperature.properties.maximum_value != "None" && Math.floor(preheatTemperatureInput.text) > Math.floor(extruderTemperature.properties.maximum_value))
  229. {
  230. return false; //Target temperature too high.
  231. }
  232. if (Math.floor(preheatTemperatureInput.text) == 0)
  233. {
  234. return false; //Setting the temperature to 0 is not allowed (since that cancels the pre-heating).
  235. }
  236. return true; //Preconditions are met.
  237. }
  238. anchors.right: parent.right
  239. anchors.bottom: parent.bottom
  240. anchors.margins: UM.Theme.getSize("default_margin").width
  241. style: ButtonStyle {
  242. background: Rectangle
  243. {
  244. border.width: UM.Theme.getSize("default_lining").width
  245. implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2)
  246. border.color:
  247. {
  248. if(!control.enabled)
  249. {
  250. return UM.Theme.getColor("action_button_disabled_border");
  251. }
  252. else if(control.pressed)
  253. {
  254. return UM.Theme.getColor("action_button_active_border");
  255. }
  256. else if(control.hovered)
  257. {
  258. return UM.Theme.getColor("action_button_hovered_border");
  259. }
  260. else
  261. {
  262. return UM.Theme.getColor("action_button_border");
  263. }
  264. }
  265. color:
  266. {
  267. if(!control.enabled)
  268. {
  269. return UM.Theme.getColor("action_button_disabled");
  270. }
  271. else if(control.pressed)
  272. {
  273. return UM.Theme.getColor("action_button_active");
  274. }
  275. else if(control.hovered)
  276. {
  277. return UM.Theme.getColor("action_button_hovered");
  278. }
  279. else
  280. {
  281. return UM.Theme.getColor("action_button");
  282. }
  283. }
  284. Behavior on color
  285. {
  286. ColorAnimation
  287. {
  288. duration: 50
  289. }
  290. }
  291. Label
  292. {
  293. id: actualLabel
  294. anchors.centerIn: parent
  295. color:
  296. {
  297. if(!control.enabled)
  298. {
  299. return UM.Theme.getColor("action_button_disabled_text");
  300. }
  301. else if(control.pressed)
  302. {
  303. return UM.Theme.getColor("action_button_active_text");
  304. }
  305. else if(control.hovered)
  306. {
  307. return UM.Theme.getColor("action_button_hovered_text");
  308. }
  309. else
  310. {
  311. return UM.Theme.getColor("action_button_text");
  312. }
  313. }
  314. font: UM.Theme.getFont("medium")
  315. text:
  316. {
  317. if(extruderModel == null)
  318. {
  319. return ""
  320. }
  321. if(extruderModel.isPreheating )
  322. {
  323. return catalog.i18nc("@button Cancel pre-heating", "Cancel")
  324. } else
  325. {
  326. return catalog.i18nc("@button", "Pre-heat")
  327. }
  328. }
  329. }
  330. }
  331. }
  332. onClicked:
  333. {
  334. if (!extruderModel.isPreheating)
  335. {
  336. extruderModel.preheatHotend(preheatTemperatureInput.text, 900);
  337. }
  338. else
  339. {
  340. extruderModel.cancelPreheatHotend();
  341. }
  342. }
  343. onHoveredChanged:
  344. {
  345. if (hovered)
  346. {
  347. base.showTooltip(
  348. base,
  349. {x: 0, y: preheatButton.mapToItem(base, 0, -parent.height).y},
  350. catalog.i18nc("@tooltip of pre-heat", "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print.")
  351. );
  352. }
  353. else
  354. {
  355. base.hideTooltip();
  356. }
  357. }
  358. }
  359. Rectangle //Material colour indication.
  360. {
  361. id: materialColor
  362. width: Math.floor(materialName.height * 0.75)
  363. height: Math.floor(materialName.height * 0.75)
  364. radius: width / 2
  365. color: extruderModel.activeMaterial ? extruderModel.activeMaterial.color: "#00000000"
  366. border.width: UM.Theme.getSize("default_lining").width
  367. border.color: UM.Theme.getColor("lining")
  368. visible: extruderModel.activeMaterial != null
  369. anchors.left: parent.left
  370. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  371. anchors.verticalCenter: materialName.verticalCenter
  372. MouseArea //For tooltip.
  373. {
  374. id: materialColorTooltipArea
  375. hoverEnabled: true
  376. anchors.fill: parent
  377. onHoveredChanged:
  378. {
  379. if (containsMouse)
  380. {
  381. base.showTooltip(
  382. base,
  383. {x: 0, y: parent.mapToItem(base, 0, -parent.height / 2).y},
  384. catalog.i18nc("@tooltip", "The colour of the material in this extruder.")
  385. );
  386. }
  387. else
  388. {
  389. base.hideTooltip();
  390. }
  391. }
  392. }
  393. }
  394. Label //Material name.
  395. {
  396. id: materialName
  397. text: extruderModel.activeMaterial != null ? extruderModel.activeMaterial.type : ""
  398. font: UM.Theme.getFont("default")
  399. color: UM.Theme.getColor("text")
  400. anchors.left: materialColor.right
  401. anchors.bottom: parent.bottom
  402. anchors.margins: UM.Theme.getSize("default_margin").width
  403. MouseArea //For tooltip.
  404. {
  405. id: materialNameTooltipArea
  406. hoverEnabled: true
  407. anchors.fill: parent
  408. onHoveredChanged:
  409. {
  410. if (containsMouse)
  411. {
  412. base.showTooltip(
  413. base,
  414. {x: 0, y: parent.mapToItem(base, 0, 0).y},
  415. catalog.i18nc("@tooltip", "The material in this extruder.")
  416. );
  417. }
  418. else
  419. {
  420. base.hideTooltip();
  421. }
  422. }
  423. }
  424. }
  425. Label //Variant name.
  426. {
  427. id: variantName
  428. text: extruderModel.hotendID
  429. font: UM.Theme.getFont("default")
  430. color: UM.Theme.getColor("text")
  431. anchors.right: parent.right
  432. anchors.bottom: parent.bottom
  433. anchors.margins: UM.Theme.getSize("default_margin").width
  434. MouseArea //For tooltip.
  435. {
  436. id: variantNameTooltipArea
  437. hoverEnabled: true
  438. anchors.fill: parent
  439. onHoveredChanged:
  440. {
  441. if (containsMouse)
  442. {
  443. base.showTooltip(
  444. base,
  445. {x: 0, y: parent.mapToItem(base, 0, -parent.height / 4).y},
  446. catalog.i18nc("@tooltip", "The nozzle inserted in this extruder.")
  447. );
  448. }
  449. else
  450. {
  451. base.hideTooltip();
  452. }
  453. }
  454. }
  455. }
  456. }
  457. }