ManualPrinterControl.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. // Copyright (c) 2019 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.2
  5. import QtQuick.Controls.Styles 2.2
  6. import QtQuick.Layouts 1.3
  7. import UM 1.3 as UM
  8. import Cura 1.0 as Cura
  9. import "."
  10. Item
  11. {
  12. property var printerModel: null
  13. property var activePrintJob: printerModel != null ? printerModel.activePrintJob : null
  14. property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
  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. Label
  52. {
  53. text: catalog.i18nc("@label", "Jog Position")
  54. color: UM.Theme.getColor("setting_control_text")
  55. font: UM.Theme.getFont("default")
  56. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  57. height: UM.Theme.getSize("setting_control").height
  58. verticalAlignment: Text.AlignVCenter
  59. }
  60. GridLayout
  61. {
  62. columns: 3
  63. rows: 4
  64. rowSpacing: UM.Theme.getSize("default_lining").width
  65. columnSpacing: UM.Theme.getSize("default_lining").height
  66. Label
  67. {
  68. text: catalog.i18nc("@label", "X/Y")
  69. color: UM.Theme.getColor("setting_control_text")
  70. font: UM.Theme.getFont("default")
  71. width: height
  72. height: UM.Theme.getSize("setting_control").height
  73. verticalAlignment: Text.AlignVCenter
  74. horizontalAlignment: Text.AlignHCenter
  75. Layout.row: 0
  76. Layout.column: 1
  77. Layout.preferredWidth: width
  78. Layout.preferredHeight: height
  79. }
  80. Button
  81. {
  82. Layout.row: 1
  83. Layout.column: 1
  84. Layout.preferredWidth: width
  85. Layout.preferredHeight: height
  86. iconSource: UM.Theme.getIcon("ChevronSingleUp");
  87. style: UM.Theme.styles.monitor_button_style
  88. width: height
  89. height: UM.Theme.getSize("setting_control").height
  90. onClicked:
  91. {
  92. printerModel.moveHead(0, distancesRow.currentDistance, 0)
  93. }
  94. }
  95. Button
  96. {
  97. Layout.row: 2
  98. Layout.column: 0
  99. Layout.preferredWidth: width
  100. Layout.preferredHeight: height
  101. iconSource: UM.Theme.getIcon("ChevronSingleLeft");
  102. style: UM.Theme.styles.monitor_button_style
  103. width: height
  104. height: UM.Theme.getSize("setting_control").height
  105. onClicked:
  106. {
  107. printerModel.moveHead(-distancesRow.currentDistance, 0, 0)
  108. }
  109. }
  110. Button
  111. {
  112. Layout.row: 2
  113. Layout.column: 2
  114. Layout.preferredWidth: width
  115. Layout.preferredHeight: height
  116. iconSource: UM.Theme.getIcon("ChevronSingleRight");
  117. style: UM.Theme.styles.monitor_button_style
  118. width: height
  119. height: UM.Theme.getSize("setting_control").height
  120. onClicked:
  121. {
  122. printerModel.moveHead(distancesRow.currentDistance, 0, 0)
  123. }
  124. }
  125. Button
  126. {
  127. Layout.row: 3
  128. Layout.column: 1
  129. Layout.preferredWidth: width
  130. Layout.preferredHeight: height
  131. iconSource: UM.Theme.getIcon("ChevronSingleDown");
  132. style: UM.Theme.styles.monitor_button_style
  133. width: height
  134. height: UM.Theme.getSize("setting_control").height
  135. onClicked:
  136. {
  137. printerModel.moveHead(0, -distancesRow.currentDistance, 0)
  138. }
  139. }
  140. Button
  141. {
  142. Layout.row: 2
  143. Layout.column: 1
  144. Layout.preferredWidth: width
  145. Layout.preferredHeight: height
  146. iconSource: UM.Theme.getIcon("House");
  147. style: UM.Theme.styles.monitor_button_style
  148. width: height
  149. height: UM.Theme.getSize("setting_control").height
  150. onClicked:
  151. {
  152. printerModel.homeHead()
  153. }
  154. }
  155. }
  156. Column
  157. {
  158. spacing: UM.Theme.getSize("default_lining").height
  159. Label
  160. {
  161. text: catalog.i18nc("@label", "Z")
  162. color: UM.Theme.getColor("setting_control_text")
  163. font: UM.Theme.getFont("default")
  164. width: UM.Theme.getSize("section").height
  165. height: UM.Theme.getSize("setting_control").height
  166. verticalAlignment: Text.AlignVCenter
  167. horizontalAlignment: Text.AlignHCenter
  168. }
  169. Button
  170. {
  171. iconSource: UM.Theme.getIcon("ChevronSingleUp");
  172. style: UM.Theme.styles.monitor_button_style
  173. width: height
  174. height: UM.Theme.getSize("setting_control").height
  175. onClicked:
  176. {
  177. printerModel.moveHead(0, 0, distancesRow.currentDistance)
  178. }
  179. }
  180. Button
  181. {
  182. iconSource: UM.Theme.getIcon("House");
  183. style: UM.Theme.styles.monitor_button_style
  184. width: height
  185. height: UM.Theme.getSize("setting_control").height
  186. onClicked:
  187. {
  188. printerModel.homeBed()
  189. }
  190. }
  191. Button
  192. {
  193. iconSource: UM.Theme.getIcon("ChevronSingleDown");
  194. style: UM.Theme.styles.monitor_button_style
  195. width: height
  196. height: UM.Theme.getSize("setting_control").height
  197. onClicked:
  198. {
  199. printerModel.moveHead(0, 0, -distancesRow.currentDistance)
  200. }
  201. }
  202. }
  203. }
  204. Row
  205. {
  206. id: distancesRow
  207. width: base.width - 2 * UM.Theme.getSize("default_margin").width
  208. height: childrenRect.height + UM.Theme.getSize("default_margin").width
  209. anchors.left: parent.left
  210. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  211. spacing: UM.Theme.getSize("default_margin").width
  212. property real currentDistance: 10
  213. Label
  214. {
  215. text: catalog.i18nc("@label", "Jog Distance")
  216. color: UM.Theme.getColor("setting_control_text")
  217. font: UM.Theme.getFont("default")
  218. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  219. height: UM.Theme.getSize("setting_control").height
  220. verticalAlignment: Text.AlignVCenter
  221. }
  222. Row
  223. {
  224. Repeater
  225. {
  226. model: distancesModel
  227. delegate: Button
  228. {
  229. height: UM.Theme.getSize("setting_control").height
  230. width: height + UM.Theme.getSize("default_margin").width
  231. text: model.label
  232. exclusiveGroup: distanceGroup
  233. checkable: true
  234. checked: distancesRow.currentDistance == model.value
  235. onClicked: distancesRow.currentDistance = model.value
  236. style: UM.Theme.styles.monitor_checkable_button_style
  237. }
  238. }
  239. }
  240. }
  241. Row
  242. {
  243. id: customCommandInputRow
  244. width: base.width - 2 * UM.Theme.getSize("default_margin").width
  245. height: childrenRect.height + UM.Theme.getSize("default_margin").width
  246. anchors.left: parent.left
  247. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  248. spacing: UM.Theme.getSize("default_margin").width
  249. Label
  250. {
  251. text: catalog.i18nc("@label", "Send G-code")
  252. color: UM.Theme.getColor("setting_control_text")
  253. font: UM.Theme.getFont("default")
  254. width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
  255. height: UM.Theme.getSize("setting_control").height
  256. verticalAlignment: Text.AlignVCenter
  257. }
  258. Row
  259. {
  260. // Input field for custom G-code commands.
  261. Rectangle
  262. {
  263. id: customCommandControl
  264. // state
  265. visible: printerModel != null ? printerModel.canSendRawGcode: true
  266. enabled: {
  267. if (printerModel == null) {
  268. return false // Can't send custom commands if not connected.
  269. }
  270. if (connectedPrinter == null || !connectedPrinter.acceptsCommands) {
  271. return false // Not allowed to do anything
  272. }
  273. if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline") {
  274. return false // Printer is in a state where it can't react to custom commands.
  275. }
  276. return true
  277. }
  278. // style
  279. color: !enabled ? UM.Theme.getColor("setting_control_disabled") : UM.Theme.getColor("setting_validation_ok")
  280. border.width: UM.Theme.getSize("default_lining").width
  281. 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")
  282. // size
  283. width: UM.Theme.getSize("setting_control").width
  284. height: UM.Theme.getSize("setting_control").height
  285. // highlight
  286. Rectangle
  287. {
  288. anchors.fill: parent
  289. anchors.margins: UM.Theme.getSize("default_lining").width
  290. color: UM.Theme.getColor("setting_control_highlight")
  291. opacity: customCommandControl.hovered ? 1.0 : 0
  292. }
  293. // cursor hover popup
  294. MouseArea
  295. {
  296. id: customCommandControlMouseArea
  297. hoverEnabled: true
  298. anchors.fill: parent
  299. cursorShape: Qt.IBeamCursor
  300. onHoveredChanged:
  301. {
  302. if (containsMouse)
  303. {
  304. base.showTooltip(
  305. base,
  306. { x: -tooltip.width, y: customCommandControlMouseArea.mapToItem(base, 0, 0).y },
  307. catalog.i18nc("@tooltip of G-code command input", "Send a custom G-code command to the connected printer. Press 'enter' to send the command.")
  308. )
  309. }
  310. else
  311. {
  312. base.hideTooltip()
  313. }
  314. }
  315. }
  316. TextInput
  317. {
  318. id: customCommandControlInput
  319. // style
  320. font: UM.Theme.getFont("default")
  321. color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
  322. selectByMouse: true
  323. clip: true
  324. enabled: parent.enabled
  325. renderType: Text.NativeRendering
  326. // anchors
  327. anchors.left: parent.left
  328. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  329. anchors.right: parent.right
  330. anchors.verticalCenter: parent.verticalCenter
  331. // send the command when pressing enter
  332. // we also clear the text field
  333. Keys.onReturnPressed:
  334. {
  335. printerModel.sendRawCommand(customCommandControlInput.text)
  336. customCommandControlInput.text = ""
  337. }
  338. }
  339. }
  340. }
  341. }
  342. ListModel
  343. {
  344. id: distancesModel
  345. ListElement { label: "0.1"; value: 0.1 }
  346. ListElement { label: "1"; value: 1 }
  347. ListElement { label: "10"; value: 10 }
  348. ListElement { label: "100"; value: 100 }
  349. }
  350. ExclusiveGroup { id: distanceGroup }
  351. }
  352. }