SaveButton.qml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 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.1 as UM
  8. Item {
  9. id: base;
  10. UM.I18nCatalog { id: catalog; name:"cura"}
  11. property real progress: UM.Backend.progress;
  12. property int backendState: UM.Backend.state;
  13. property var backend: CuraApplication.getBackend();
  14. property bool activity: CuraApplication.platformActivity;
  15. property alias buttonRowWidth: saveRow.width
  16. property string fileBaseName
  17. property string statusText:
  18. {
  19. if(!activity)
  20. {
  21. return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model");
  22. }
  23. switch(base.backendState)
  24. {
  25. case 1:
  26. return catalog.i18nc("@label:PrintjobStatus", "Ready to slice");
  27. case 2:
  28. return catalog.i18nc("@label:PrintjobStatus", "Slicing...");
  29. case 3:
  30. return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription);
  31. case 4:
  32. return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice");
  33. case 5:
  34. return catalog.i18nc("@label:PrintjobStatus", "Slicing unavailable");
  35. default:
  36. return "";
  37. }
  38. }
  39. Label {
  40. id: statusLabel
  41. width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
  42. anchors.top: parent.top
  43. anchors.left: parent.left
  44. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  45. color: UM.Theme.getColor("text")
  46. font: UM.Theme.getFont("default_bold")
  47. text: statusText;
  48. }
  49. Rectangle {
  50. id: progressBar
  51. width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
  52. height: UM.Theme.getSize("progressbar").height
  53. anchors.top: statusLabel.bottom
  54. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height/4
  55. anchors.left: parent.left
  56. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  57. radius: UM.Theme.getSize("progressbar_radius").width
  58. color: UM.Theme.getColor("progressbar_background")
  59. Rectangle {
  60. width: Math.max(parent.width * base.progress)
  61. height: parent.height
  62. color: UM.Theme.getColor("progressbar_control")
  63. radius: UM.Theme.getSize("progressbar_radius").width
  64. visible: base.backendState == 2 ? true : false
  65. }
  66. }
  67. // Shortcut for "save as/print/..."
  68. Action {
  69. shortcut: "Ctrl+P"
  70. onTriggered:
  71. {
  72. // only work when the button is enabled
  73. if (saveToButton.enabled) {
  74. saveToButton.clicked();
  75. }
  76. }
  77. }
  78. Item {
  79. id: saveRow
  80. width: {
  81. // using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect
  82. var children_width = UM.Theme.getSize("default_margin").width;
  83. for (var index in children)
  84. {
  85. var child = children[index];
  86. if(child.visible)
  87. {
  88. children_width += child.width + child.anchors.rightMargin;
  89. }
  90. }
  91. return Math.min(children_width, base.width - UM.Theme.getSize("sidebar_margin").width);
  92. }
  93. height: saveToButton.height
  94. anchors.bottom: parent.bottom
  95. anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
  96. anchors.right: parent.right
  97. clip: true
  98. Row {
  99. id: additionalComponentsRow
  100. anchors.top: parent.top
  101. anchors.right: saveToButton.visible ? saveToButton.left : parent.right
  102. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  103. spacing: UM.Theme.getSize("default_margin").width
  104. }
  105. Connections {
  106. target: Printer
  107. onAdditionalComponentsChanged:
  108. {
  109. if(areaId == "saveButton") {
  110. for (var component in CuraApplication.additionalComponents["saveButton"]) {
  111. CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow
  112. }
  113. }
  114. }
  115. }
  116. Connections {
  117. target: UM.Preferences
  118. onPreferenceChanged:
  119. {
  120. var autoSlice = UM.Preferences.getValue("general/auto_slice");
  121. prepareButton.autoSlice = autoSlice;
  122. saveToButton.autoSlice = autoSlice;
  123. }
  124. }
  125. // Prepare button, only shows if auto_slice is off
  126. Button {
  127. id: prepareButton
  128. tooltip: UM.OutputDeviceManager.activeDeviceDescription;
  129. // 1 = not started, 2 = Processing
  130. enabled: (base.backendState == 1 || base.backendState == 2) && base.activity == true
  131. visible: {
  132. return !autoSlice && (base.backendState == 1 || base.backendState == 2) && base.activity == true;
  133. }
  134. property bool autoSlice
  135. height: UM.Theme.getSize("save_button_save_to_button").height
  136. anchors.top: parent.top
  137. anchors.right: parent.right
  138. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  139. // 1 = not started, 5 = disabled
  140. text: [1, 5].indexOf(UM.Backend.state) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel")
  141. onClicked:
  142. {
  143. if ([1, 5].indexOf(UM.Backend.state) != -1) {
  144. backend.forceSlice();
  145. } else {
  146. backend.stopSlicing();
  147. }
  148. }
  149. style: ButtonStyle {
  150. background: Rectangle
  151. {
  152. border.width: UM.Theme.getSize("default_lining").width
  153. border.color:
  154. {
  155. if(!control.enabled)
  156. return UM.Theme.getColor("action_button_disabled_border");
  157. else if(control.pressed)
  158. return UM.Theme.getColor("action_button_active_border");
  159. else if(control.hovered)
  160. return UM.Theme.getColor("action_button_hovered_border");
  161. else
  162. return UM.Theme.getColor("action_button_border");
  163. }
  164. color:
  165. {
  166. if(!control.enabled)
  167. return UM.Theme.getColor("action_button_disabled");
  168. else if(control.pressed)
  169. return UM.Theme.getColor("action_button_active");
  170. else if(control.hovered)
  171. return UM.Theme.getColor("action_button_hovered");
  172. else
  173. return UM.Theme.getColor("action_button");
  174. }
  175. Behavior on color { ColorAnimation { duration: 50; } }
  176. implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2)
  177. Label {
  178. id: actualLabel
  179. anchors.centerIn: parent
  180. color:
  181. {
  182. if(!control.enabled)
  183. return UM.Theme.getColor("action_button_disabled_text");
  184. else if(control.pressed)
  185. return UM.Theme.getColor("action_button_active_text");
  186. else if(control.hovered)
  187. return UM.Theme.getColor("action_button_hovered_text");
  188. else
  189. return UM.Theme.getColor("action_button_text");
  190. }
  191. font: UM.Theme.getFont("action_button")
  192. text: control.text;
  193. }
  194. }
  195. label: Item { }
  196. }
  197. }
  198. Button {
  199. id: saveToButton
  200. tooltip: UM.OutputDeviceManager.activeDeviceDescription;
  201. // 3 = done, 5 = disabled
  202. enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true
  203. visible: {
  204. return autoSlice || ((base.backendState == 3 || base.backendState == 5) && base.activity == true);
  205. }
  206. property bool autoSlice
  207. height: UM.Theme.getSize("save_button_save_to_button").height
  208. anchors.top: parent.top
  209. anchors.right: deviceSelectionMenu.visible ? deviceSelectionMenu.left : parent.right
  210. anchors.rightMargin: deviceSelectionMenu.visible ? -3 * UM.Theme.getSize("default_lining").width : UM.Theme.getSize("sidebar_margin").width
  211. text: UM.OutputDeviceManager.activeDeviceShortDescription
  212. onClicked:
  213. {
  214. UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, { "filter_by_machine": true, "preferred_mimetype":Printer.preferredOutputMimetype })
  215. }
  216. style: ButtonStyle {
  217. background: Rectangle
  218. {
  219. border.width: UM.Theme.getSize("default_lining").width
  220. border.color:
  221. {
  222. if(!control.enabled)
  223. return UM.Theme.getColor("action_button_disabled_border");
  224. else if(control.pressed)
  225. return UM.Theme.getColor("print_button_ready_pressed_border");
  226. else if(control.hovered)
  227. return UM.Theme.getColor("print_button_ready_hovered_border");
  228. else
  229. return UM.Theme.getColor("print_button_ready_border");
  230. }
  231. color:
  232. {
  233. if(!control.enabled)
  234. return UM.Theme.getColor("action_button_disabled");
  235. else if(control.pressed)
  236. return UM.Theme.getColor("print_button_ready_pressed");
  237. else if(control.hovered)
  238. return UM.Theme.getColor("print_button_ready_hovered");
  239. else
  240. return UM.Theme.getColor("print_button_ready");
  241. }
  242. Behavior on color { ColorAnimation { duration: 50; } }
  243. implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2)
  244. Label {
  245. id: actualLabel
  246. anchors.centerIn: parent
  247. color:
  248. {
  249. if(!control.enabled)
  250. return UM.Theme.getColor("action_button_disabled_text");
  251. else if(control.pressed)
  252. return UM.Theme.getColor("print_button_ready_text");
  253. else if(control.hovered)
  254. return UM.Theme.getColor("print_button_ready_text");
  255. else
  256. return UM.Theme.getColor("print_button_ready_text");
  257. }
  258. font: UM.Theme.getFont("action_button")
  259. text: control.text;
  260. }
  261. }
  262. label: Item { }
  263. }
  264. }
  265. Button {
  266. id: deviceSelectionMenu
  267. tooltip: catalog.i18nc("@info:tooltip","Select the active output device");
  268. anchors.top: parent.top
  269. anchors.right: parent.right
  270. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  271. width: UM.Theme.getSize("save_button_save_to_button").height
  272. height: UM.Theme.getSize("save_button_save_to_button").height
  273. // 3 = Done, 5 = Disabled
  274. enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true
  275. visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true
  276. style: ButtonStyle {
  277. background: Rectangle {
  278. id: deviceSelectionIcon
  279. border.width: UM.Theme.getSize("default_lining").width
  280. border.color:
  281. {
  282. if(!control.enabled)
  283. return UM.Theme.getColor("action_button_disabled_border");
  284. else if(control.pressed)
  285. return UM.Theme.getColor("print_button_ready_pressed_border");
  286. else if(control.hovered)
  287. return UM.Theme.getColor("print_button_ready_hovered_border");
  288. else
  289. return UM.Theme.getColor("print_button_ready_border");
  290. }
  291. color:
  292. {
  293. if(!control.enabled)
  294. return UM.Theme.getColor("action_button_disabled");
  295. else if(control.pressed)
  296. return UM.Theme.getColor("print_button_ready_pressed");
  297. else if(control.hovered)
  298. return UM.Theme.getColor("print_button_ready_hovered");
  299. else
  300. return UM.Theme.getColor("print_button_ready");
  301. }
  302. Behavior on color { ColorAnimation { duration: 50; } }
  303. anchors.left: parent.left
  304. anchors.leftMargin: UM.Theme.getSize("save_button_text_margin").width / 2;
  305. width: parent.height
  306. height: parent.height
  307. UM.RecolorImage {
  308. anchors.verticalCenter: parent.verticalCenter
  309. anchors.horizontalCenter: parent.horizontalCenter
  310. width: UM.Theme.getSize("standard_arrow").width
  311. height: UM.Theme.getSize("standard_arrow").height
  312. sourceSize.width: width
  313. sourceSize.height: height
  314. color:
  315. {
  316. if(!control.enabled)
  317. return UM.Theme.getColor("action_button_disabled_text");
  318. else if(control.pressed)
  319. return UM.Theme.getColor("print_button_ready_text");
  320. else if(control.hovered)
  321. return UM.Theme.getColor("print_button_ready_text");
  322. else
  323. return UM.Theme.getColor("print_button_ready_text");
  324. }
  325. source: UM.Theme.getIcon("arrow_bottom");
  326. }
  327. }
  328. label: Label{ }
  329. }
  330. menu: Menu {
  331. id: devicesMenu;
  332. Instantiator {
  333. model: devicesModel;
  334. MenuItem {
  335. text: model.description
  336. checkable: true;
  337. checked: model.id == UM.OutputDeviceManager.activeDevice;
  338. exclusiveGroup: devicesMenuGroup;
  339. onTriggered: {
  340. UM.OutputDeviceManager.setActiveDevice(model.id);
  341. }
  342. }
  343. onObjectAdded: devicesMenu.insertItem(index, object)
  344. onObjectRemoved: devicesMenu.removeItem(object)
  345. }
  346. ExclusiveGroup { id: devicesMenuGroup; }
  347. }
  348. }
  349. UM.OutputDevicesModel { id: devicesModel; }
  350. }
  351. }