ManualPrinterControl.qml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. // Copyright (c) 2022 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.1
  5. import QtQuick.Layouts 1.3
  6. import UM 1.5 as UM
  7. import Cura 1.0 as Cura
  8. import "."
  9. Item
  10. {
  11. property var printerModel: null
  12. property var activePrintJob: printerModel != null ? printerModel.activePrintJob : null
  13. property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
  14. property var _buttonSize: UM.Theme.getSize("setting_control").height + UM.Theme.getSize("thin_margin").height
  15. implicitWidth: parent.width
  16. implicitHeight: childrenRect.height
  17. Column
  18. {
  19. enabled:
  20. {
  21. if (printerModel == null)
  22. {
  23. return false; //Can't control the printer if not connected
  24. }
  25. if (!connectedDevice.acceptsCommands)
  26. {
  27. return false; //Not allowed to do anything.
  28. }
  29. if(activePrintJob == null)
  30. {
  31. return true
  32. }
  33. if (activePrintJob.state == "printing" || activePrintJob.state == "resuming" || activePrintJob.state == "pausing" || activePrintJob.state == "error" || activePrintJob.state == "offline")
  34. {
  35. return false; //Printer is in a state where it can't react to manual control
  36. }
  37. return true;
  38. }
  39. MonitorSection
  40. {
  41. label: catalog.i18nc("@label", "Printer control")
  42. width: base.width
  43. }
  44. Row
  45. {
  46. width: base.width - 2 * UM.Theme.getSize("default_margin").width
  47. height: childrenRect.height + UM.Theme.getSize("default_margin").width
  48. anchors.left: parent.left
  49. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  50. spacing: UM.Theme.getSize("default_margin").width
  51. UM.Label
  52. {
  53. text: catalog.i18nc("@label", "Jog Position")
  54. color: UM.Theme.getColor("setting_control_text")
  55. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  56. height: UM.Theme.getSize("setting_control").height
  57. }
  58. GridLayout
  59. {
  60. columns: 3
  61. rows: 4
  62. rowSpacing: UM.Theme.getSize("default_lining").width
  63. columnSpacing: UM.Theme.getSize("default_lining").height
  64. UM.Label
  65. {
  66. text: catalog.i18nc("@label", "X/Y")
  67. color: UM.Theme.getColor("setting_control_text")
  68. width: height
  69. height: UM.Theme.getSize("setting_control").height
  70. horizontalAlignment: Text.AlignHCenter
  71. Layout.row: 0
  72. Layout.column: 1
  73. Layout.preferredWidth: width
  74. Layout.preferredHeight: height
  75. }
  76. Cura.SecondaryButton
  77. {
  78. Layout.row: 1
  79. Layout.column: 1
  80. Layout.preferredWidth: _buttonSize
  81. Layout.preferredHeight: _buttonSize
  82. iconSource: UM.Theme.getIcon("ChevronSingleUp")
  83. leftPadding: (Layout.preferredWidth - iconSize) / 2
  84. onClicked: printerModel.moveHead(0, distancesRow.currentDistance, 0)
  85. }
  86. Cura.SecondaryButton
  87. {
  88. Layout.row: 2
  89. Layout.column: 0
  90. Layout.preferredWidth: _buttonSize
  91. Layout.preferredHeight: _buttonSize
  92. iconSource: UM.Theme.getIcon("ChevronSingleLeft")
  93. leftPadding: (Layout.preferredWidth - iconSize) / 2
  94. onClicked: printerModel.moveHead(-distancesRow.currentDistance, 0, 0)
  95. }
  96. Cura.SecondaryButton
  97. {
  98. Layout.row: 2
  99. Layout.column: 2
  100. Layout.preferredWidth: _buttonSize
  101. Layout.preferredHeight: _buttonSize
  102. iconSource: UM.Theme.getIcon("ChevronSingleRight")
  103. leftPadding: (Layout.preferredWidth - iconSize) / 2
  104. onClicked: printerModel.moveHead(distancesRow.currentDistance, 0, 0)
  105. }
  106. Cura.SecondaryButton
  107. {
  108. Layout.row: 3
  109. Layout.column: 1
  110. Layout.preferredWidth: _buttonSize
  111. Layout.preferredHeight: _buttonSize
  112. iconSource: UM.Theme.getIcon("ChevronSingleDown")
  113. leftPadding: (Layout.preferredWidth - iconSize) / 2
  114. onClicked: printerModel.moveHead(0, -distancesRow.currentDistance, 0)
  115. }
  116. Cura.SecondaryButton
  117. {
  118. Layout.row: 2
  119. Layout.column: 1
  120. Layout.preferredWidth: _buttonSize
  121. Layout.preferredHeight: _buttonSize
  122. iconSource: UM.Theme.getIcon("House")
  123. leftPadding: (Layout.preferredWidth - iconSize) / 2
  124. onClicked: printerModel.homeHead()
  125. }
  126. }
  127. Column
  128. {
  129. spacing: UM.Theme.getSize("default_lining").height
  130. UM.Label
  131. {
  132. text: catalog.i18nc("@label", "Z")
  133. color: UM.Theme.getColor("setting_control_text")
  134. width: UM.Theme.getSize("section").height
  135. height: UM.Theme.getSize("setting_control").height
  136. horizontalAlignment: Text.AlignHCenter
  137. }
  138. Cura.SecondaryButton
  139. {
  140. iconSource: UM.Theme.getIcon("ChevronSingleUp")
  141. width: height
  142. height: _buttonSize
  143. leftPadding: (width - iconSize) / 2
  144. onClicked: printerModel.moveHead(0, 0, distancesRow.currentDistance)
  145. }
  146. Cura.SecondaryButton
  147. {
  148. iconSource: UM.Theme.getIcon("House")
  149. width: height
  150. height: _buttonSize
  151. leftPadding: (width - iconSize) / 2
  152. onClicked: printerModel.homeBed()
  153. }
  154. Cura.SecondaryButton
  155. {
  156. iconSource: UM.Theme.getIcon("ChevronSingleDown")
  157. width: height
  158. height: _buttonSize
  159. leftPadding: (width - iconSize) / 2
  160. onClicked: printerModel.moveHead(0, 0, -distancesRow.currentDistance)
  161. }
  162. }
  163. }
  164. Row
  165. {
  166. id: distancesRow
  167. width: base.width - 2 * UM.Theme.getSize("default_margin").width
  168. height: childrenRect.height + UM.Theme.getSize("default_margin").width
  169. anchors.left: parent.left
  170. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  171. spacing: UM.Theme.getSize("default_margin").width
  172. property real currentDistance: 10
  173. UM.Label
  174. {
  175. text: catalog.i18nc("@label", "Jog Distance")
  176. color: UM.Theme.getColor("setting_control_text")
  177. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  178. height: UM.Theme.getSize("setting_control").height
  179. }
  180. Row
  181. {
  182. Repeater
  183. {
  184. model: distancesModel
  185. delegate: Cura.SecondaryButton
  186. {
  187. height: UM.Theme.getSize("setting_control").height
  188. text: model.label
  189. ButtonGroup.group: distanceGroup
  190. color: distancesRow.currentDistance == model.value ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("secondary_button")
  191. textColor: distancesRow.currentDistance == model.value ? UM.Theme.getColor("primary_button_text"): UM.Theme.getColor("secondary_button_text")
  192. hoverColor: distancesRow.currentDistance == model.value ? UM.Theme.getColor("primary_button_hover"): UM.Theme.getColor("secondary_button_hover")
  193. onClicked: distancesRow.currentDistance = model.value
  194. }
  195. }
  196. }
  197. }
  198. Row
  199. {
  200. id: customCommandInputRow
  201. width: base.width - 2 * UM.Theme.getSize("default_margin").width
  202. height: childrenRect.height + UM.Theme.getSize("default_margin").width
  203. anchors.left: parent.left
  204. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  205. spacing: UM.Theme.getSize("default_margin").width
  206. UM.Label
  207. {
  208. text: catalog.i18nc("@label", "Send G-code")
  209. color: UM.Theme.getColor("setting_control_text")
  210. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  211. height: UM.Theme.getSize("setting_control").height
  212. }
  213. Row
  214. {
  215. // Input field for custom G-code commands.
  216. Rectangle
  217. {
  218. id: customCommandControl
  219. // state
  220. visible: printerModel != null ? printerModel.canSendRawGcode: true
  221. enabled: {
  222. if (printerModel == null) {
  223. return false // Can't send custom commands if not connected.
  224. }
  225. if (connectedPrinter == null || !connectedPrinter.acceptsCommands) {
  226. return false // Not allowed to do anything
  227. }
  228. if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline") {
  229. return false // Printer is in a state where it can't react to custom commands.
  230. }
  231. return true
  232. }
  233. // style
  234. color: !enabled ? UM.Theme.getColor("setting_control_disabled") : UM.Theme.getColor("setting_validation_ok")
  235. border.width: UM.Theme.getSize("default_lining").width
  236. border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : customCommandControlMouseArea.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
  237. // size
  238. width: UM.Theme.getSize("setting_control").width
  239. height: UM.Theme.getSize("setting_control").height
  240. // highlight
  241. Rectangle
  242. {
  243. anchors.fill: parent
  244. anchors.margins: UM.Theme.getSize("default_lining").width
  245. color: UM.Theme.getColor("setting_control_highlight")
  246. opacity: customCommandControl.hovered ? 1.0 : 0
  247. }
  248. // cursor hover popup
  249. MouseArea
  250. {
  251. id: customCommandControlMouseArea
  252. hoverEnabled: true
  253. anchors.fill: parent
  254. cursorShape: Qt.IBeamCursor
  255. onHoveredChanged:
  256. {
  257. if (containsMouse)
  258. {
  259. base.showTooltip(
  260. base,
  261. { x: -tooltip.width, y: customCommandControlMouseArea.mapToItem(base, 0, 0).y },
  262. catalog.i18nc("@tooltip of G-code command input", "Send a custom G-code command to the connected printer. Press 'enter' to send the command.")
  263. )
  264. }
  265. else
  266. {
  267. base.hideTooltip()
  268. }
  269. }
  270. }
  271. TextInput
  272. {
  273. id: customCommandControlInput
  274. // style
  275. font: UM.Theme.getFont("default")
  276. color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
  277. selectByMouse: true
  278. clip: true
  279. enabled: parent.enabled
  280. renderType: Text.NativeRendering
  281. // anchors
  282. anchors.left: parent.left
  283. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  284. anchors.right: parent.right
  285. anchors.verticalCenter: parent.verticalCenter
  286. // send the command when pressing enter
  287. // we also clear the text field
  288. Keys.onReturnPressed:
  289. {
  290. printerModel.sendRawCommand(customCommandControlInput.text)
  291. customCommandControlInput.text = ""
  292. }
  293. }
  294. }
  295. }
  296. }
  297. ListModel
  298. {
  299. id: distancesModel
  300. ListElement { label: "0.1"; value: 0.1 }
  301. ListElement { label: "1"; value: 1 }
  302. ListElement { label: "10"; value: 10 }
  303. ListElement { label: "100"; value: 100 }
  304. }
  305. ButtonGroup { id: distanceGroup }
  306. }
  307. }