Sidebar.qml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Cura is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Controls.Styles 1.1
  6. import QtQuick.Layouts 1.1
  7. import UM 1.2 as UM
  8. import Cura 1.0 as Cura
  9. import "Menus"
  10. Rectangle
  11. {
  12. id: base;
  13. property int currentModeIndex;
  14. property bool monitoringPrint: false
  15. property bool hideSettings: PrintInformation.preSliced
  16. Connections
  17. {
  18. target: Printer
  19. onShowPrintMonitor:
  20. {
  21. base.monitoringPrint = show;
  22. showSettings.checked = !show;
  23. showMonitor.checked = show;
  24. }
  25. }
  26. // Is there an output device for this printer?
  27. property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
  28. property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
  29. color: UM.Theme.getColor("sidebar")
  30. UM.I18nCatalog { id: catalog; name:"cura"}
  31. Timer {
  32. id: tooltipDelayTimer
  33. interval: 500
  34. repeat: false
  35. property var item
  36. property string text
  37. onTriggered:
  38. {
  39. base.showTooltip(base, {x:1, y:item.y}, text);
  40. }
  41. }
  42. function showTooltip(item, position, text)
  43. {
  44. tooltip.text = text;
  45. position = item.mapToItem(base, position.x, position.y);
  46. tooltip.show(position);
  47. }
  48. function hideTooltip()
  49. {
  50. tooltip.hide();
  51. }
  52. function strPadLeft(string, pad, length) {
  53. return (new Array(length + 1).join(pad) + string).slice(-length);
  54. }
  55. function getPrettyTime(time)
  56. {
  57. var hours = Math.floor(time / 3600)
  58. time -= hours * 3600
  59. var minutes = Math.floor(time / 60);
  60. time -= minutes * 60
  61. var seconds = Math.floor(time);
  62. var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2);
  63. return finalTime;
  64. }
  65. MouseArea
  66. {
  67. anchors.fill: parent
  68. acceptedButtons: Qt.AllButtons;
  69. onWheel:
  70. {
  71. wheel.accepted = true;
  72. }
  73. }
  74. // Printer selection and mode selection buttons for changing between Setting & Monitor print mode
  75. Rectangle
  76. {
  77. id: sidebarHeaderBar
  78. anchors.left: parent.left
  79. anchors.right: parent.right
  80. height: childrenRect.height
  81. color: UM.Theme.getColor("sidebar_header_bar")
  82. Row
  83. {
  84. anchors.left: parent.left
  85. anchors.right: parent.right
  86. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  87. spacing: UM.Theme.getSize("default_margin").width
  88. ToolButton
  89. {
  90. id: machineSelection
  91. text: Cura.MachineManager.activeMachineName
  92. width: parent.width - (showSettings.width + showMonitor.width + 2 * UM.Theme.getSize("default_margin").width)
  93. height: UM.Theme.getSize("sidebar_header").height
  94. tooltip: Cura.MachineManager.activeMachineName
  95. anchors.verticalCenter: parent.verticalCenter
  96. style: ButtonStyle {
  97. background: Rectangle {
  98. color: {
  99. if(control.pressed) {
  100. return UM.Theme.getColor("sidebar_header_active");
  101. } else if(control.hovered) {
  102. return UM.Theme.getColor("sidebar_header_hover");
  103. } else {
  104. return UM.Theme.getColor("sidebar_header_bar");
  105. }
  106. }
  107. Behavior on color { ColorAnimation { duration: 50; } }
  108. Rectangle {
  109. id: underline;
  110. anchors.left: parent.left
  111. anchors.right: parent.right
  112. anchors.bottom: parent.bottom
  113. height: UM.Theme.getSize("sidebar_header_highlight").height
  114. color: UM.Theme.getColor("sidebar_header_highlight_hover")
  115. visible: control.hovered || control.pressed
  116. }
  117. UM.RecolorImage {
  118. id: downArrow
  119. anchors.verticalCenter: parent.verticalCenter
  120. anchors.right: parent.right
  121. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  122. width: UM.Theme.getSize("standard_arrow").width
  123. height: UM.Theme.getSize("standard_arrow").height
  124. sourceSize.width: width
  125. sourceSize.height: width
  126. color: UM.Theme.getColor("text_reversed")
  127. source: UM.Theme.getIcon("arrow_bottom")
  128. }
  129. Label {
  130. id: sidebarComboBoxLabel
  131. color: UM.Theme.getColor("text_reversed")
  132. text: control.text;
  133. elide: Text.ElideRight;
  134. anchors.left: parent.left;
  135. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  136. anchors.right: downArrow.left;
  137. anchors.rightMargin: control.rightMargin;
  138. anchors.verticalCenter: parent.verticalCenter;
  139. font: UM.Theme.getFont("large")
  140. }
  141. }
  142. label: Label{}
  143. }
  144. menu: PrinterMenu { }
  145. }
  146. Button
  147. {
  148. id: showSettings
  149. width: height
  150. height: UM.Theme.getSize("sidebar_header").height
  151. onClicked: monitoringPrint = false
  152. iconSource: UM.Theme.getIcon("tab_settings");
  153. property color overlayColor: "transparent"
  154. property string overlayIconSource: ""
  155. checkable: true
  156. checked: !monitoringPrint
  157. exclusiveGroup: sidebarHeaderBarGroup
  158. property string tooltipText: catalog.i18nc("@tooltip", "<b>Print Setup</b><br/><br/>Edit or review the settings for the active print job.")
  159. onHoveredChanged: {
  160. if (hovered)
  161. {
  162. tooltipDelayTimer.item = showSettings
  163. tooltipDelayTimer.text = tooltipText
  164. tooltipDelayTimer.start();
  165. }
  166. else
  167. {
  168. tooltipDelayTimer.stop();
  169. base.hideTooltip();
  170. }
  171. }
  172. style: UM.Theme.styles.sidebar_header_tab
  173. }
  174. Button
  175. {
  176. id: showMonitor
  177. width: height
  178. height: UM.Theme.getSize("sidebar_header").height
  179. onClicked: monitoringPrint = true
  180. iconSource: printerConnected ? UM.Theme.getIcon("tab_monitor_with_status") : UM.Theme.getIcon("tab_monitor")
  181. property color overlayColor:
  182. {
  183. if(!printerAcceptsCommands)
  184. {
  185. return UM.Theme.getColor("status_unknown");
  186. }
  187. if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
  188. {
  189. return UM.Theme.getColor("status_busy");
  190. }
  191. switch(Cura.MachineManager.printerOutputDevices[0].jobState)
  192. {
  193. case "printing":
  194. case "pre_print":
  195. case "wait_cleanup":
  196. case "pausing":
  197. case "resuming":
  198. return UM.Theme.getColor("status_busy");
  199. case "ready":
  200. case "":
  201. return UM.Theme.getColor("status_ready");
  202. case "paused":
  203. return UM.Theme.getColor("status_paused");
  204. case "error":
  205. return UM.Theme.getColor("status_stopped");
  206. case "offline":
  207. return UM.Theme.getColor("status_offline");
  208. default:
  209. return UM.Theme.getColor("text_reversed");
  210. }
  211. }
  212. property string overlayIconSource:
  213. {
  214. if(!printerConnected)
  215. {
  216. return "";
  217. }
  218. else if(!printerAcceptsCommands)
  219. {
  220. return UM.Theme.getIcon("tab_status_unknown");
  221. }
  222. if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
  223. {
  224. return UM.Theme.getIcon("tab_status_busy");
  225. }
  226. switch(Cura.MachineManager.printerOutputDevices[0].jobState)
  227. {
  228. case "printing":
  229. case "pre_print":
  230. case "wait_cleanup":
  231. case "pausing":
  232. case "resuming":
  233. return UM.Theme.getIcon("tab_status_busy");
  234. case "ready":
  235. case "":
  236. return UM.Theme.getIcon("tab_status_connected")
  237. case "paused":
  238. return UM.Theme.getIcon("tab_status_paused")
  239. case "error":
  240. return UM.Theme.getIcon("tab_status_stopped")
  241. case "offline":
  242. return UM.Theme.getIcon("tab_status_offline")
  243. default:
  244. return ""
  245. }
  246. }
  247. checkable: true
  248. checked: monitoringPrint
  249. exclusiveGroup: sidebarHeaderBarGroup
  250. property string tooltipText: catalog.i18nc("@tooltip", "<b>Print Monitor</b><br/><br/>Monitor the state of the connected printer and the print job in progress.")
  251. onHoveredChanged: {
  252. if (hovered)
  253. {
  254. tooltipDelayTimer.item = showMonitor
  255. tooltipDelayTimer.text = tooltipText
  256. tooltipDelayTimer.start();
  257. }
  258. else
  259. {
  260. tooltipDelayTimer.stop();
  261. base.hideTooltip();
  262. }
  263. }
  264. style: UM.Theme.styles.sidebar_header_tab
  265. }
  266. ExclusiveGroup { id: sidebarHeaderBarGroup }
  267. }
  268. }
  269. SidebarHeader {
  270. id: header
  271. width: parent.width
  272. anchors.top: sidebarHeaderBar.bottom
  273. onShowTooltip: base.showTooltip(item, location, text)
  274. onHideTooltip: base.hideTooltip()
  275. }
  276. Rectangle {
  277. id: headerSeparator
  278. width: parent.width
  279. visible: !monitoringPrint && !hideSettings
  280. height: visible ? UM.Theme.getSize("sidebar_lining").height : 0
  281. color: UM.Theme.getColor("sidebar_lining")
  282. anchors.top: header.bottom
  283. anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0
  284. }
  285. onCurrentModeIndexChanged:
  286. {
  287. UM.Preferences.setValue("cura/active_mode", currentModeIndex);
  288. if(modesListModel.count > base.currentModeIndex)
  289. {
  290. sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "replace": true });
  291. }
  292. }
  293. Label {
  294. id: settingsModeLabel
  295. text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox","Print Setup disabled\nG-code files cannot be modified");
  296. anchors.left: parent.left
  297. anchors.leftMargin: UM.Theme.getSize("default_margin").width;
  298. anchors.top: headerSeparator.bottom
  299. anchors.topMargin: UM.Theme.getSize("default_margin").height
  300. width: parent.width * 0.45 - 2 * UM.Theme.getSize("default_margin").width
  301. font: UM.Theme.getFont("large")
  302. color: UM.Theme.getColor("text")
  303. visible: !monitoringPrint
  304. elide: Text.ElideRight
  305. }
  306. Rectangle {
  307. id: settingsModeSelection
  308. width: parent.width * 0.55
  309. height: UM.Theme.getSize("sidebar_header_mode_toggle").height
  310. anchors.right: parent.right
  311. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  312. anchors.top: headerSeparator.bottom
  313. anchors.topMargin: UM.Theme.getSize("default_margin").height
  314. visible: !monitoringPrint && !hideSettings
  315. Component{
  316. id: wizardDelegate
  317. Button {
  318. height: settingsModeSelection.height
  319. anchors.left: parent.left
  320. anchors.leftMargin: model.index * (settingsModeSelection.width / 2)
  321. anchors.verticalCenter: parent.verticalCenter
  322. width: 0.5 * parent.width - (model.showFilterButton ? toggleFilterButton.width : 0)
  323. text: model.text
  324. exclusiveGroup: modeMenuGroup;
  325. checkable: true;
  326. checked: base.currentModeIndex == index
  327. onClicked: base.currentModeIndex = index
  328. onHoveredChanged: {
  329. if (hovered)
  330. {
  331. tooltipDelayTimer.item = settingsModeSelection
  332. tooltipDelayTimer.text = model.tooltipText
  333. tooltipDelayTimer.start();
  334. }
  335. else
  336. {
  337. tooltipDelayTimer.stop();
  338. base.hideTooltip();
  339. }
  340. }
  341. style: ButtonStyle {
  342. background: Rectangle {
  343. border.width: UM.Theme.getSize("default_lining").width
  344. border.color: control.checked ? UM.Theme.getColor("toggle_checked_border") :
  345. control.pressed ? UM.Theme.getColor("toggle_active_border") :
  346. control.hovered ? UM.Theme.getColor("toggle_hovered_border") : UM.Theme.getColor("toggle_unchecked_border")
  347. color: control.checked ? UM.Theme.getColor("toggle_checked") :
  348. control.pressed ? UM.Theme.getColor("toggle_active") :
  349. control.hovered ? UM.Theme.getColor("toggle_hovered") : UM.Theme.getColor("toggle_unchecked")
  350. Behavior on color { ColorAnimation { duration: 50; } }
  351. Label {
  352. anchors.centerIn: parent
  353. color: control.checked ? UM.Theme.getColor("toggle_checked_text") :
  354. control.pressed ? UM.Theme.getColor("toggle_active_text") :
  355. control.hovered ? UM.Theme.getColor("toggle_hovered_text") : UM.Theme.getColor("toggle_unchecked_text")
  356. font: UM.Theme.getFont("default")
  357. text: control.text;
  358. }
  359. }
  360. label: Item { }
  361. }
  362. }
  363. }
  364. ExclusiveGroup { id: modeMenuGroup; }
  365. ListView{
  366. id: modesList
  367. property var index: 0
  368. model: modesListModel
  369. delegate: wizardDelegate
  370. anchors.top: parent.top
  371. anchors.left: parent.left
  372. width: parent.width
  373. }
  374. }
  375. Button
  376. {
  377. id: toggleFilterButton
  378. anchors.right: parent.right
  379. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  380. anchors.top: headerSeparator.bottom
  381. anchors.topMargin: UM.Theme.getSize("default_margin").height
  382. height: settingsModeSelection.height
  383. width: visible ? height : 0
  384. visible: !monitoringPrint && !hideSettings && modesListModel.get(base.currentModeIndex) != undefined && modesListModel.get(base.currentModeIndex).showFilterButton
  385. opacity: visible ? 1 : 0
  386. onClicked: sidebarContents.currentItem.toggleFilterField()
  387. style: ButtonStyle
  388. {
  389. background: Rectangle
  390. {
  391. border.width: UM.Theme.getSize("default_lining").width
  392. border.color: UM.Theme.getColor("toggle_checked_border")
  393. color: visible ? UM.Theme.getColor("toggle_checked") : UM.Theme.getColor("toggle_hovered")
  394. Behavior on color { ColorAnimation { duration: 50; } }
  395. }
  396. label: UM.RecolorImage
  397. {
  398. anchors.verticalCenter: parent.verticalCenter
  399. anchors.right: parent.right
  400. anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
  401. source: UM.Theme.getIcon("search")
  402. color: UM.Theme.getColor("toggle_checked_text")
  403. }
  404. }
  405. }
  406. StackView
  407. {
  408. id: sidebarContents
  409. anchors.bottom: footerSeparator.top
  410. anchors.top: settingsModeSelection.bottom
  411. anchors.topMargin: UM.Theme.getSize("default_margin").height
  412. anchors.left: base.left
  413. anchors.right: base.right
  414. visible: !monitoringPrint && !hideSettings
  415. delegate: StackViewDelegate
  416. {
  417. function transitionFinished(properties)
  418. {
  419. properties.exitItem.opacity = 1
  420. }
  421. pushTransition: StackViewTransition
  422. {
  423. PropertyAnimation
  424. {
  425. target: enterItem
  426. property: "opacity"
  427. from: 0
  428. to: 1
  429. duration: 100
  430. }
  431. PropertyAnimation
  432. {
  433. target: exitItem
  434. property: "opacity"
  435. from: 1
  436. to: 0
  437. duration: 100
  438. }
  439. }
  440. }
  441. }
  442. Loader
  443. {
  444. anchors.bottom: footerSeparator.top
  445. anchors.top: headerSeparator.bottom
  446. anchors.left: base.left
  447. anchors.right: base.right
  448. source: monitoringPrint ? "PrintMonitor.qml": "SidebarContents.qml"
  449. }
  450. Rectangle
  451. {
  452. id: footerSeparator
  453. width: parent.width
  454. height: UM.Theme.getSize("sidebar_lining").height
  455. color: UM.Theme.getColor("sidebar_lining")
  456. anchors.bottom: saveButton.top
  457. anchors.bottomMargin: UM.Theme.getSize("default_margin").height
  458. }
  459. SaveButton
  460. {
  461. id: saveButton
  462. implicitWidth: base.width
  463. implicitHeight: totalHeight
  464. anchors.bottom: parent.bottom
  465. visible: !monitoringPrint
  466. }
  467. MonitorButton
  468. {
  469. id: monitorButton
  470. implicitWidth: base.width
  471. implicitHeight: totalHeight
  472. anchors.bottom: parent.bottom
  473. visible: monitoringPrint
  474. }
  475. SidebarTooltip
  476. {
  477. id: tooltip;
  478. }
  479. ListModel
  480. {
  481. id: modesListModel;
  482. }
  483. SidebarSimple
  484. {
  485. id: sidebarSimple;
  486. visible: false;
  487. onShowTooltip: base.showTooltip(item, location, text)
  488. onHideTooltip: base.hideTooltip()
  489. }
  490. SidebarAdvanced
  491. {
  492. id: sidebarAdvanced;
  493. visible: false;
  494. onShowTooltip: base.showTooltip(item, location, text)
  495. onHideTooltip: base.hideTooltip()
  496. }
  497. Component.onCompleted:
  498. {
  499. modesListModel.append({
  500. text: catalog.i18nc("@title:tab", "Recommended"),
  501. tooltipText: catalog.i18nc("@tooltip", "<b>Recommended Print Setup</b><br/><br/>Print with the recommended settings for the selected printer, material and quality."),
  502. item: sidebarSimple,
  503. showFilterButton: false
  504. })
  505. modesListModel.append({
  506. text: catalog.i18nc("@title:tab", "Custom"),
  507. tooltipText: catalog.i18nc("@tooltip", "<b>Custom Print Setup</b><br/><br/>Print with finegrained control over every last bit of the slicing process."),
  508. item: sidebarAdvanced,
  509. showFilterButton: true
  510. })
  511. sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "immediate": true });
  512. var index = parseInt(UM.Preferences.getValue("cura/active_mode"))
  513. if(index)
  514. {
  515. currentModeIndex = index;
  516. }
  517. }
  518. UM.SettingPropertyProvider
  519. {
  520. id: machineExtruderCount
  521. containerStackId: Cura.MachineManager.activeMachineId
  522. key: "machine_extruder_count"
  523. watchedProperties: [ "value" ]
  524. storeIndex: 0
  525. }
  526. UM.SettingPropertyProvider
  527. {
  528. id: machineHeatedBed
  529. containerStackId: Cura.MachineManager.activeMachineId
  530. key: "machine_heated_bed"
  531. watchedProperties: [ "value" ]
  532. storeIndex: 0
  533. }
  534. }