SidebarHeader.qml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.7
  4. import QtQuick.Controls 1.1
  5. import QtQuick.Controls.Styles 1.1
  6. import UM 1.2 as UM
  7. import Cura 1.0 as Cura
  8. import "Menus"
  9. Column
  10. {
  11. id: base;
  12. property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex;
  13. property bool currentExtruderVisible: extrudersList.visible;
  14. property bool printerConnected: Cura.MachineManager.printerConnected
  15. property bool hasManyPrinterTypes:
  16. {
  17. if (printerConnected)
  18. {
  19. if (Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount != null)
  20. {
  21. return Cura.MachineManager.printerOutputDevices[0].connectedPrintersTypeCount.length > 1;
  22. }
  23. }
  24. return false;
  25. }
  26. property bool buildplateCompatibilityError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
  27. property bool buildplateCompatibilityWarning: Cura.MachineManager.variantBuildplateUsable
  28. spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9)
  29. signal showTooltip(Item item, point location, string text)
  30. signal hideTooltip()
  31. Item
  32. {
  33. id: initialSeparator
  34. anchors
  35. {
  36. left: parent.left
  37. right: parent.right
  38. }
  39. visible: printerTypeSelectionRow.visible || buildplateRow.visible || extruderSelectionRow.visible
  40. height: UM.Theme.getSize("default_lining").height
  41. width: height
  42. }
  43. // Printer Type Row
  44. Item
  45. {
  46. id: printerTypeSelectionRow
  47. height: UM.Theme.getSize("sidebar_setup").height
  48. visible: printerConnected && hasManyPrinterTypes && !sidebar.hideSettings
  49. anchors
  50. {
  51. left: parent.left
  52. leftMargin: UM.Theme.getSize("sidebar_margin").width
  53. right: parent.right
  54. rightMargin: UM.Theme.getSize("sidebar_margin").width
  55. }
  56. Label
  57. {
  58. id: configurationLabel
  59. text: catalog.i18nc("@label", "Printer type");
  60. width: Math.round(parent.width * 0.4 - UM.Theme.getSize("default_margin").width)
  61. height: parent.height
  62. verticalAlignment: Text.AlignVCenter
  63. font: UM.Theme.getFont("default");
  64. color: UM.Theme.getColor("text");
  65. }
  66. ToolButton
  67. {
  68. id: printerTypeSelection
  69. text: Cura.MachineManager.activeMachineDefinitionName
  70. tooltip: Cura.MachineManager.activeMachineDefinitionName
  71. height: UM.Theme.getSize("setting_control").height
  72. width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width
  73. anchors.right: parent.right
  74. style: UM.Theme.styles.sidebar_header_button
  75. activeFocusOnPress: true;
  76. menu: PrinterTypeMenu { }
  77. }
  78. }
  79. Rectangle {
  80. id: headerSeparator
  81. width: parent.width
  82. visible: printerTypeSelectionRow.visible
  83. height: visible ? UM.Theme.getSize("sidebar_lining").height : 0
  84. color: UM.Theme.getColor("sidebar_lining")
  85. }
  86. // Extruder Row
  87. Item
  88. {
  89. id: extruderSelectionRow
  90. width: parent.width
  91. height: Math.round(UM.Theme.getSize("sidebar_tabs").height * 2 / 3)
  92. visible: machineExtruderCount.properties.value > 1
  93. anchors
  94. {
  95. left: parent.left
  96. leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
  97. right: parent.right
  98. rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
  99. topMargin: UM.Theme.getSize("sidebar_margin").height
  100. }
  101. ListView
  102. {
  103. id: extrudersList
  104. property var index: 0
  105. height: UM.Theme.getSize("sidebar_header_mode_tabs").height
  106. width: Math.round(parent.width)
  107. boundsBehavior: Flickable.StopAtBounds
  108. anchors
  109. {
  110. left: parent.left
  111. leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
  112. right: parent.right
  113. rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
  114. verticalCenter: parent.verticalCenter
  115. }
  116. ExclusiveGroup { id: extruderMenuGroup; }
  117. orientation: ListView.Horizontal
  118. model: Cura.ExtrudersModel { id: extrudersModel; }
  119. Connections
  120. {
  121. target: Cura.MachineManager
  122. onGlobalContainerChanged: forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
  123. }
  124. delegate: Button
  125. {
  126. height: ListView.view.height
  127. width: Math.round(ListView.view.width / extrudersModel.rowCount())
  128. text: model.name
  129. tooltip: model.name
  130. exclusiveGroup: extruderMenuGroup
  131. checked: base.currentExtruderIndex == index
  132. property bool extruder_enabled: true
  133. MouseArea
  134. {
  135. anchors.fill: parent
  136. acceptedButtons: Qt.LeftButton | Qt.RightButton
  137. onClicked: {
  138. switch (mouse.button) {
  139. case Qt.LeftButton:
  140. extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled
  141. if (extruder_enabled)
  142. {
  143. forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
  144. Cura.ExtruderManager.setActiveExtruderIndex(index);
  145. }
  146. break;
  147. case Qt.RightButton:
  148. extruder_enabled = Cura.MachineManager.getExtruder(model.index).isEnabled
  149. extruderMenu.popup();
  150. break;
  151. }
  152. }
  153. }
  154. Menu
  155. {
  156. id: extruderMenu
  157. MenuItem {
  158. text: catalog.i18nc("@action:inmenu", "Enable Extruder")
  159. onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
  160. visible: !extruder_enabled // using an intermediate variable prevents an empty popup that occured now and then
  161. }
  162. MenuItem {
  163. text: catalog.i18nc("@action:inmenu", "Disable Extruder")
  164. onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
  165. visible: extruder_enabled
  166. enabled: Cura.MachineManager.numberExtrudersEnabled > 1
  167. }
  168. }
  169. style: ButtonStyle
  170. {
  171. background: Item
  172. {
  173. function buttonBackgroundColor(index)
  174. {
  175. var extruder = Cura.MachineManager.getExtruder(index)
  176. if (extruder.isEnabled) {
  177. return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") :
  178. control.hovered ? UM.Theme.getColor("action_button_hovered") :
  179. UM.Theme.getColor("action_button")
  180. } else {
  181. return UM.Theme.getColor("action_button_disabled")
  182. }
  183. }
  184. function buttonBorderColor(index)
  185. {
  186. var extruder = Cura.MachineManager.getExtruder(index)
  187. if (extruder.isEnabled) {
  188. return (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") :
  189. control.hovered ? UM.Theme.getColor("action_button_hovered_border") :
  190. UM.Theme.getColor("action_button_border")
  191. } else {
  192. return UM.Theme.getColor("action_button_disabled_border")
  193. }
  194. }
  195. function buttonColor(index) {
  196. var extruder = Cura.MachineManager.getExtruder(index);
  197. if (extruder.isEnabled)
  198. {
  199. return (
  200. control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
  201. control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
  202. UM.Theme.getColor("action_button_text");
  203. } else {
  204. return UM.Theme.getColor("action_button_disabled_text");
  205. }
  206. }
  207. Rectangle
  208. {
  209. anchors.fill: parent
  210. border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
  211. border.color: buttonBorderColor(index)
  212. color: buttonBackgroundColor(index)
  213. Behavior on color { ColorAnimation { duration: 50; } }
  214. }
  215. Item
  216. {
  217. id: extruderButtonFace
  218. anchors.centerIn: parent
  219. width: {
  220. var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0;
  221. var iconWidth = extruderIconItem.width;
  222. return Math.round(extruderTextWidth + iconWidth + UM.Theme.getSize("default_margin").width / 2);
  223. }
  224. // Static text "Extruder"
  225. Label
  226. {
  227. id: extruderStaticText
  228. anchors.verticalCenter: parent.verticalCenter
  229. anchors.left: parent.left
  230. color: buttonColor(index)
  231. font: UM.Theme.getFont("large_nonbold")
  232. text: catalog.i18nc("@label", "Extruder")
  233. visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width)
  234. elide: Text.ElideRight
  235. }
  236. // Everything for the extruder icon
  237. Item
  238. {
  239. id: extruderIconItem
  240. anchors.verticalCenter: parent.verticalCenter
  241. anchors.right: parent.right
  242. property var sizeToUse:
  243. {
  244. var minimumWidth = control.width < UM.Theme.getSize("button").width ? control.width : UM.Theme.getSize("button").width;
  245. var minimumHeight = control.height < UM.Theme.getSize("button").height ? control.height : UM.Theme.getSize("button").height;
  246. var minimumSize = minimumWidth < minimumHeight ? minimumWidth : minimumHeight;
  247. minimumSize -= Math.round(UM.Theme.getSize("default_margin").width / 2);
  248. return minimumSize;
  249. }
  250. width: sizeToUse
  251. height: sizeToUse
  252. UM.RecolorImage {
  253. id: mainCircle
  254. anchors.fill: parent
  255. sourceSize.width: parent.width
  256. sourceSize.height: parent.width
  257. source: UM.Theme.getIcon("extruder_button")
  258. color: extruderNumberText.color
  259. }
  260. Label
  261. {
  262. id: extruderNumberText
  263. anchors.centerIn: parent
  264. text: index + 1;
  265. color: buttonColor(index)
  266. font: UM.Theme.getFont("default_bold")
  267. }
  268. // Material colour circle
  269. // Only draw the filling colour of the material inside the SVG border.
  270. Rectangle
  271. {
  272. id: materialColorCircle
  273. anchors
  274. {
  275. right: parent.right
  276. top: parent.top
  277. rightMargin: Math.round(parent.sizeToUse * 0.01)
  278. topMargin: Math.round(parent.sizeToUse * 0.05)
  279. }
  280. color: model.color
  281. width: Math.round(parent.width * 0.35)
  282. height: Math.round(parent.height * 0.35)
  283. radius: Math.round(width / 2)
  284. border.width: 1
  285. border.color: UM.Theme.getColor("extruder_button_material_border")
  286. opacity: !control.checked ? 0.6 : 1.0
  287. }
  288. }
  289. }
  290. }
  291. label: Item {}
  292. }
  293. }
  294. }
  295. }
  296. Item
  297. {
  298. id: variantRowSpacer
  299. height: Math.round(UM.Theme.getSize("sidebar_margin").height / 4)
  300. width: height
  301. visible: !extruderSelectionRow.visible && !initialSeparator.visible
  302. }
  303. // Material Row
  304. Item
  305. {
  306. id: materialRow
  307. height: UM.Theme.getSize("sidebar_setup").height
  308. visible: Cura.MachineManager.hasMaterials && !sidebar.hideSettings
  309. anchors
  310. {
  311. left: parent.left
  312. leftMargin: UM.Theme.getSize("sidebar_margin").width
  313. right: parent.right
  314. rightMargin: UM.Theme.getSize("sidebar_margin").width
  315. }
  316. Label
  317. {
  318. id: materialLabel
  319. text: catalog.i18nc("@label", "Material");
  320. width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
  321. height: parent.height
  322. verticalAlignment: Text.AlignVCenter
  323. font: UM.Theme.getFont("default");
  324. color: UM.Theme.getColor("text");
  325. }
  326. ToolButton
  327. {
  328. id: materialSelection
  329. property var activeExtruder: Cura.MachineManager.activeStack
  330. property var hasActiveExtruder: activeExtruder != null
  331. property var currentRootMaterialName: hasActiveExtruder ? activeExtruder.material.name : ""
  332. text: currentRootMaterialName
  333. tooltip: currentRootMaterialName
  334. visible: Cura.MachineManager.hasMaterials
  335. enabled: !extrudersList.visible || base.currentExtruderIndex > -1
  336. height: UM.Theme.getSize("setting_control").height
  337. width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width
  338. anchors.right: parent.right
  339. style: UM.Theme.styles.sidebar_header_button
  340. activeFocusOnPress: true;
  341. menu: MaterialMenu
  342. {
  343. extruderIndex: base.currentExtruderIndex
  344. }
  345. property var valueError: !isMaterialSupported()
  346. property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported
  347. function isMaterialSupported ()
  348. {
  349. if (!hasActiveExtruder)
  350. {
  351. return false;
  352. }
  353. return Cura.ContainerManager.getContainerMetaDataEntry(activeExtruder.material.id, "compatible", "") == "True"
  354. }
  355. }
  356. }
  357. //Variant row
  358. Item
  359. {
  360. id: variantRow
  361. height: UM.Theme.getSize("sidebar_setup").height
  362. visible: Cura.MachineManager.hasVariants && !sidebar.hideSettings
  363. anchors
  364. {
  365. left: parent.left
  366. leftMargin: UM.Theme.getSize("sidebar_margin").width
  367. right: parent.right
  368. rightMargin: UM.Theme.getSize("sidebar_margin").width
  369. }
  370. Label
  371. {
  372. id: variantLabel
  373. text: Cura.MachineManager.activeDefinitionVariantsName;
  374. width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
  375. height: parent.height
  376. verticalAlignment: Text.AlignVCenter
  377. font: UM.Theme.getFont("default");
  378. color: UM.Theme.getColor("text");
  379. }
  380. ToolButton
  381. {
  382. id: variantSelection
  383. text: Cura.MachineManager.activeVariantName
  384. tooltip: Cura.MachineManager.activeVariantName;
  385. visible: Cura.MachineManager.hasVariants
  386. height: UM.Theme.getSize("setting_control").height
  387. width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
  388. anchors.right: parent.right
  389. style: UM.Theme.styles.sidebar_header_button
  390. activeFocusOnPress: true;
  391. menu: NozzleMenu { extruderIndex: base.currentExtruderIndex }
  392. }
  393. }
  394. Rectangle
  395. {
  396. id: buildplateSeparator
  397. anchors.left: parent.left
  398. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  399. width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
  400. visible: buildplateRow.visible
  401. height: visible ? UM.Theme.getSize("sidebar_lining_thin").height : 0
  402. color: UM.Theme.getColor("sidebar_lining")
  403. }
  404. //Buildplate row
  405. Item
  406. {
  407. id: buildplateRow
  408. height: UM.Theme.getSize("sidebar_setup").height
  409. // TODO Only show in dev mode. Remove check when feature ready
  410. visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates && !sidebar.hideSettings : false
  411. anchors
  412. {
  413. left: parent.left
  414. leftMargin: UM.Theme.getSize("sidebar_margin").width
  415. right: parent.right
  416. rightMargin: UM.Theme.getSize("sidebar_margin").width
  417. }
  418. Label
  419. {
  420. id: bulidplateLabel
  421. text: catalog.i18nc("@label", "Build plate");
  422. width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
  423. height: parent.height
  424. verticalAlignment: Text.AlignVCenter
  425. font: UM.Theme.getFont("default");
  426. color: UM.Theme.getColor("text");
  427. }
  428. ToolButton
  429. {
  430. id: buildplateSelection
  431. text: Cura.MachineManager.activeVariantBuildplateName
  432. tooltip: Cura.MachineManager.activeVariantBuildplateName
  433. visible: Cura.MachineManager.hasVariantBuildplates
  434. height: UM.Theme.getSize("setting_control").height
  435. width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
  436. anchors.right: parent.right
  437. style: UM.Theme.styles.sidebar_header_button
  438. activeFocusOnPress: true;
  439. menu: BuildplateMenu {}
  440. property var valueError: !Cura.MachineManager.variantBuildplateCompatible && !Cura.MachineManager.variantBuildplateUsable
  441. property var valueWarning: Cura.MachineManager.variantBuildplateUsable
  442. }
  443. }
  444. // Material info row
  445. Item
  446. {
  447. id: materialInfoRow
  448. height: Math.round(UM.Theme.getSize("sidebar_setup").height / 2)
  449. visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariantBuildplates) && !sidebar.hideSettings
  450. anchors
  451. {
  452. left: parent.left
  453. leftMargin: UM.Theme.getSize("sidebar_margin").width
  454. right: parent.right
  455. rightMargin: UM.Theme.getSize("sidebar_margin").width
  456. }
  457. // TODO This was added to replace the buildplate selector. Remove this component when the feature is ready
  458. Label
  459. {
  460. id: materialCompatibilityLabel
  461. y: -Math.round(UM.Theme.getSize("sidebar_margin").height / 3)
  462. anchors.left: parent.left
  463. width: parent.width - materialCompatibilityLink.width
  464. text: catalog.i18nc("@label", "Use glue with this material combination")
  465. font: UM.Theme.getFont("very_small")
  466. color: UM.Theme.getColor("text")
  467. visible: CuraSDKVersion == "dev" ? false : buildplateCompatibilityError || buildplateCompatibilityWarning
  468. wrapMode: Text.WordWrap
  469. opacity: 0.5
  470. }
  471. Item
  472. {
  473. id: materialCompatibilityLink
  474. height: UM.Theme.getSize("sidebar_setup").height
  475. anchors.right: parent.right
  476. width: childrenRect.width + UM.Theme.getSize("default_margin").width
  477. UM.RecolorImage {
  478. id: warningImage
  479. anchors.right: materialInfoLabel.left
  480. anchors.rightMargin: UM.Theme.getSize("default_margin").width
  481. anchors.verticalCenter: parent.Bottom
  482. source: UM.Theme.getIcon("warning")
  483. width: UM.Theme.getSize("section_icon").width
  484. height: UM.Theme.getSize("section_icon").height
  485. sourceSize.width: width
  486. sourceSize.height: height
  487. color: UM.Theme.getColor("material_compatibility_warning")
  488. visible: !Cura.MachineManager.isCurrentSetupSupported || buildplateCompatibilityError || buildplateCompatibilityWarning
  489. }
  490. Label {
  491. id: materialInfoLabel
  492. wrapMode: Text.WordWrap
  493. text: "<a href='%1'>" + catalog.i18nc("@label", "Check compatibility") + "</a>"
  494. font: UM.Theme.getFont("default")
  495. color: UM.Theme.getColor("text")
  496. linkColor: UM.Theme.getColor("text_link")
  497. verticalAlignment: Text.AlignTop
  498. anchors.top: parent.top
  499. anchors.right: parent.right
  500. anchors.bottom: parent.bottom
  501. MouseArea {
  502. anchors.fill: parent
  503. hoverEnabled: true
  504. onClicked: {
  505. // open the material URL with web browser
  506. var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty"
  507. Qt.openUrlExternally(url);
  508. }
  509. onEntered: {
  510. var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com.");
  511. base.showTooltip(
  512. materialInfoRow,
  513. Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0),
  514. catalog.i18nc("@tooltip", content)
  515. );
  516. }
  517. onExited: base.hideTooltip();
  518. }
  519. }
  520. }
  521. }
  522. UM.SettingPropertyProvider
  523. {
  524. id: machineExtruderCount
  525. containerStack: Cura.MachineManager.activeMachine
  526. key: "machine_extruder_count"
  527. watchedProperties: [ "value" ]
  528. storeIndex: 0
  529. }
  530. UM.I18nCatalog { id: catalog; name:"cura" }
  531. }