SidebarSimple.qml 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  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. Item
  10. {
  11. id: base;
  12. signal showTooltip(Item item, point location, string text);
  13. signal hideTooltip();
  14. property Action configureSettings;
  15. property variant minimumPrintTime: PrintInformation.minimumPrintTime;
  16. property variant maximumPrintTime: PrintInformation.maximumPrintTime;
  17. property bool settingsEnabled: ExtruderManager.activeExtruderStackId || machineExtruderCount.properties.value == 1
  18. Component.onCompleted: PrintInformation.enabled = true
  19. Component.onDestruction: PrintInformation.enabled = false
  20. UM.I18nCatalog { id: catalog; name: "cura" }
  21. ScrollView
  22. {
  23. visible: Cura.MachineManager.activeMachineName != "" // If no printers added then the view is invisible
  24. anchors.fill: parent
  25. style: UM.Theme.styles.scrollview
  26. flickableItem.flickableDirection: Flickable.VerticalFlick
  27. Rectangle
  28. {
  29. width: childrenRect.width
  30. height: childrenRect.height
  31. color: UM.Theme.getColor("sidebar")
  32. //
  33. // Quality profile
  34. //
  35. Item
  36. {
  37. id: qualityRow
  38. height: UM.Theme.getSize("sidebar_margin").height
  39. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  40. anchors.left: parent.left
  41. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  42. anchors.right: parent.right
  43. Timer
  44. {
  45. id: qualitySliderChangeTimer
  46. interval: 50
  47. running: false
  48. repeat: false
  49. onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualitySlider.value).id)
  50. }
  51. Component.onCompleted: qualityModel.update()
  52. Connections
  53. {
  54. target: Cura.MachineManager
  55. onActiveQualityChanged: qualityModel.update()
  56. }
  57. ListModel
  58. {
  59. id: qualityModel
  60. property var totalTicks: 0
  61. property var availableTotalTicks: 0
  62. property var activeQualityId: 0
  63. property var qualitySliderStepWidth: 0
  64. property var qualitySliderAvailableMin : 0
  65. property var qualitySliderAvailableMax : 0
  66. property var qualitySliderMarginRight : 0
  67. function update () {
  68. reset()
  69. var availableMin = -1
  70. var availableMax = -1
  71. for (var i = 0; i <= Cura.ProfilesModel.rowCount(); i++) {
  72. var qualityItem = Cura.ProfilesModel.getItem(i)
  73. // Add each quality item to the UI quality model
  74. qualityModel.append(qualityItem)
  75. // Set selected value
  76. if (Cura.MachineManager.activeQualityId == qualityItem.id) {
  77. qualityModel.activeQualityId = i
  78. }
  79. // Set min available
  80. if (qualityItem.available && availableMin == -1) {
  81. availableMin = i
  82. }
  83. // Set max available
  84. if (qualityItem.available) {
  85. availableMax = i
  86. }
  87. }
  88. // Set total available ticks for active slider part
  89. if (availableMin != -1) {
  90. qualityModel.availableTotalTicks = availableMax - availableMin
  91. }
  92. // Calculate slider values
  93. calculateSliderStepWidth(qualityModel.totalTicks)
  94. calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks)
  95. qualityModel.qualitySliderAvailableMin = availableMin
  96. qualityModel.qualitySliderAvailableMax = availableMax
  97. }
  98. function calculateSliderStepWidth (totalTicks) {
  99. qualityModel.qualitySliderStepWidth = totalTicks != 0 ? (base.width * 0.55) / (totalTicks) : 0
  100. }
  101. function calculateSliderMargins (availableMin, availableMax, totalTicks) {
  102. if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) {
  103. qualityModel.qualitySliderMarginRight = base.width * 0.55
  104. } else if (availableMin == availableMax) {
  105. qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth
  106. } else {
  107. qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth
  108. }
  109. }
  110. function reset () {
  111. qualityModel.clear()
  112. qualityModel.availableTotalTicks = -1
  113. // check, the ticks count cannot be less than zero
  114. if(Cura.ProfilesModel.rowCount() != 0)
  115. qualityModel.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0
  116. else
  117. qualityModel.totalTicks = 0
  118. }
  119. }
  120. Text
  121. {
  122. id: qualityRowTitle
  123. text: catalog.i18nc("@label", "Layer Height")
  124. font: UM.Theme.getFont("default")
  125. color: UM.Theme.getColor("text")
  126. }
  127. // Show titles for the each quality slider ticks
  128. Item
  129. {
  130. y: -5;
  131. anchors.left: speedSlider.left
  132. Repeater
  133. {
  134. model: qualityModel
  135. Text
  136. {
  137. anchors.verticalCenter: parent.verticalCenter
  138. anchors.top: parent.top
  139. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
  140. color: (Cura.MachineManager.activeMachine != null && Cura.ProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  141. text:
  142. {
  143. var result = ""
  144. if(Cura.MachineManager.activeMachine != null){
  145. var result = Cura.ProfilesModel.getItem(index).layer_height_without_unit
  146. if(result == undefined)
  147. result = ""
  148. }
  149. return result
  150. }
  151. x: {
  152. // Make sure the text aligns correctly with each tick
  153. if (index == 0) {
  154. return (base.width * 0.55 / qualityModel.totalTicks) * index
  155. } else if (index == qualityModel.totalTicks) {
  156. return (base.width * 0.55 / qualityModel.totalTicks) * index - width
  157. } else {
  158. return (base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)
  159. }
  160. }
  161. }
  162. }
  163. }
  164. //Print speed slider
  165. Item
  166. {
  167. id: speedSlider
  168. width: base.width * 0.55
  169. height: UM.Theme.getSize("sidebar_margin").height
  170. anchors.right: parent.right
  171. anchors.top: parent.top
  172. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  173. // Draw Unavailable line
  174. Rectangle
  175. {
  176. id: groovechildrect
  177. width: base.width * 0.55
  178. height: 2 * screenScaleFactor
  179. color: UM.Theme.getColor("quality_slider_unavailable")
  180. anchors.verticalCenter: qualitySlider.verticalCenter
  181. x: 0
  182. }
  183. // Draw ticks
  184. Repeater
  185. {
  186. id: qualityRepeater
  187. model: qualityModel
  188. Rectangle
  189. {
  190. anchors.verticalCenter: parent.verticalCenter
  191. color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  192. width: 1 * screenScaleFactor
  193. height: 6 * screenScaleFactor
  194. y: 0
  195. x: qualityModel.qualitySliderStepWidth * index
  196. }
  197. }
  198. Slider
  199. {
  200. id: qualitySlider
  201. height: UM.Theme.getSize("sidebar_margin").height
  202. anchors.bottom: speedSlider.bottom
  203. enabled: qualityModel.availableTotalTicks > 0
  204. updateValueWhileDragging : false
  205. minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0
  206. maximumValue: qualityModel.qualitySliderAvailableMax >= 0 ? qualityModel.qualitySliderAvailableMax : 0
  207. stepSize: 1
  208. value: qualityModel.activeQualityId
  209. width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks
  210. anchors.right: parent.right
  211. anchors.rightMargin: qualityModel.qualitySliderMarginRight
  212. style: SliderStyle
  213. {
  214. //Draw Available line
  215. groove: Rectangle {
  216. implicitHeight: 2 * screenScaleFactor
  217. color: UM.Theme.getColor("quality_slider_available")
  218. radius: 1 * screenScaleFactor
  219. }
  220. handle: Item {
  221. Rectangle {
  222. id: qualityhandleButton
  223. anchors.centerIn: parent
  224. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  225. implicitWidth: 10 * screenScaleFactor
  226. implicitHeight: 10 * screenScaleFactor
  227. radius: 10 * screenScaleFactor
  228. }
  229. }
  230. }
  231. onValueChanged: {
  232. if(Cura.MachineManager.activeMachine != null)
  233. {
  234. //Prevent updating during view initializing. Trigger only if the value changed by user
  235. if(qualitySlider.value != qualityModel.activeQualityId)
  236. {
  237. //start updating with short delay
  238. qualitySliderChangeTimer.start();
  239. }
  240. }
  241. }
  242. }
  243. }
  244. Text
  245. {
  246. id: speedLabel
  247. anchors.top: speedSlider.bottom
  248. anchors.left: parent.left
  249. text: catalog.i18nc("@label", "Print Speed")
  250. font: UM.Theme.getFont("default")
  251. color: UM.Theme.getColor("text")
  252. }
  253. Text
  254. {
  255. anchors.bottom: speedLabel.bottom
  256. anchors.left: speedSlider.left
  257. text: catalog.i18nc("@label", "Slower")
  258. font: UM.Theme.getFont("default")
  259. color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  260. horizontalAlignment: Text.AlignLeft
  261. }
  262. Text
  263. {
  264. anchors.bottom: speedLabel.bottom
  265. anchors.right: speedSlider.right
  266. text: catalog.i18nc("@label", "Faster")
  267. font: UM.Theme.getFont("default")
  268. color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  269. horizontalAlignment: Text.AlignRight
  270. }
  271. }
  272. //
  273. // Infill
  274. //
  275. Item
  276. {
  277. id: infillCellLeft
  278. anchors.top: qualityRow.bottom
  279. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
  280. anchors.left: parent.left
  281. width: UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width
  282. Text
  283. {
  284. id: infillLabel
  285. text: catalog.i18nc("@label", "Infill")
  286. font: UM.Theme.getFont("default")
  287. color: UM.Theme.getColor("text")
  288. anchors.top: parent.top
  289. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 1.7
  290. anchors.left: parent.left
  291. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  292. }
  293. }
  294. Item
  295. {
  296. id: infillCellRight
  297. height: infillSlider.height + enableGradualInfillCheckBox.height + (UM.Theme.getSize("sidebar_margin").height * 2)
  298. width: UM.Theme.getSize("sidebar").width * .55
  299. anchors.left: infillCellLeft.right
  300. anchors.top: infillCellLeft.top
  301. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  302. Text {
  303. id: selectedInfillRateText
  304. //anchors.top: parent.top
  305. anchors.left: infillSlider.left
  306. anchors.leftMargin: (infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor
  307. anchors.right: parent.right
  308. text: infillSlider.value + "%"
  309. horizontalAlignment: Text.AlignLeft
  310. color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  311. }
  312. Slider
  313. {
  314. id: infillSlider
  315. anchors.top: selectedInfillRateText.bottom
  316. anchors.left: parent.left
  317. anchors.right: infillIcon.left
  318. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  319. height: UM.Theme.getSize("sidebar_margin").height
  320. width: infillCellRight.width - UM.Theme.getSize("sidebar_margin").width - style.handleWidth
  321. minimumValue: 0
  322. maximumValue: 100
  323. stepSize: 10
  324. tickmarksEnabled: true
  325. // disable slider when gradual support is enabled
  326. enabled: parseInt(infillSteps.properties.value) == 0
  327. // set initial value from stack
  328. value: parseInt(infillDensity.properties.value)
  329. onValueChanged: {
  330. infillDensity.setPropertyValue("value", infillSlider.value)
  331. }
  332. style: SliderStyle
  333. {
  334. groove: Rectangle {
  335. id: groove
  336. implicitWidth: 200 * screenScaleFactor
  337. implicitHeight: 2 * screenScaleFactor
  338. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  339. radius: 1
  340. }
  341. handle: Item {
  342. Rectangle {
  343. id: handleButton
  344. anchors.centerIn: parent
  345. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  346. implicitWidth: 10 * screenScaleFactor
  347. implicitHeight: 10 * screenScaleFactor
  348. radius: 10 * screenScaleFactor
  349. }
  350. }
  351. tickmarks: Repeater {
  352. id: repeater
  353. model: control.maximumValue / control.stepSize + 1
  354. Rectangle {
  355. anchors.verticalCenter: parent.verticalCenter
  356. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  357. width: 1 * screenScaleFactor
  358. height: 6 * screenScaleFactor
  359. y: 0
  360. x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))
  361. }
  362. }
  363. }
  364. }
  365. Rectangle
  366. {
  367. id: infillIcon
  368. width: (parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width)
  369. height: width
  370. anchors.right: parent.right
  371. anchors.top: parent.top
  372. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
  373. // we loop over all density icons and only show the one that has the current density and steps
  374. Repeater
  375. {
  376. id: infillIconList
  377. model: infillModel
  378. anchors.fill: parent
  379. property int activeIndex: {
  380. for (var i = 0; i < infillModel.count; i++) {
  381. var density = parseInt(infillDensity.properties.value)
  382. var steps = parseInt(infillSteps.properties.value)
  383. var infillModelItem = infillModel.get(i)
  384. if (density >= infillModelItem.percentageMin
  385. && density <= infillModelItem.percentageMax
  386. && steps >= infillModelItem.stepsMin
  387. && steps <= infillModelItem.stepsMax){
  388. return i
  389. }
  390. }
  391. return -1
  392. }
  393. Rectangle
  394. {
  395. anchors.fill: parent
  396. visible: infillIconList.activeIndex == index
  397. border.width: UM.Theme.getSize("default_lining").width
  398. border.color: UM.Theme.getColor("quality_slider_available")
  399. UM.RecolorImage {
  400. anchors.fill: parent
  401. anchors.margins: 2 * screenScaleFactor
  402. sourceSize.width: width
  403. sourceSize.height: width
  404. source: UM.Theme.getIcon(model.icon)
  405. color: UM.Theme.getColor("quality_slider_unavailable")
  406. }
  407. }
  408. }
  409. }
  410. // Gradual Support Infill Checkbox
  411. CheckBox {
  412. id: enableGradualInfillCheckBox
  413. property alias _hovered: enableGradualInfillMouseArea.containsMouse
  414. anchors.top: infillSlider.bottom
  415. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  416. anchors.left: infillCellRight.left
  417. style: UM.Theme.styles.checkbox
  418. enabled: base.settingsEnabled
  419. checked: parseInt(infillSteps.properties.value) > 0
  420. MouseArea {
  421. id: enableGradualInfillMouseArea
  422. anchors.fill: parent
  423. hoverEnabled: true
  424. enabled: true
  425. onClicked: {
  426. infillSteps.setPropertyValue("value", (parseInt(infillSteps.properties.value) == 0) ? 5 : 0)
  427. infillDensity.setPropertyValue("value", 90)
  428. }
  429. onEntered: {
  430. base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0),
  431. catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."))
  432. }
  433. onExited: {
  434. base.hideTooltip()
  435. }
  436. }
  437. Text {
  438. id: gradualInfillLabel
  439. anchors.left: enableGradualInfillCheckBox.right
  440. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2
  441. text: catalog.i18nc("@label", "Enable gradual")
  442. font: UM.Theme.getFont("default")
  443. color: UM.Theme.getColor("text")
  444. }
  445. }
  446. // Infill list model for mapping icon
  447. ListModel
  448. {
  449. id: infillModel
  450. Component.onCompleted:
  451. {
  452. infillModel.append({
  453. percentageMin: -1,
  454. percentageMax: 0,
  455. stepsMin: -1,
  456. stepsMax: 0,
  457. icon: "hollow"
  458. })
  459. infillModel.append({
  460. percentageMin: 0,
  461. percentageMax: 40,
  462. stepsMin: -1,
  463. stepsMax: 0,
  464. icon: "sparse"
  465. })
  466. infillModel.append({
  467. percentageMin: 40,
  468. percentageMax: 89,
  469. stepsMin: -1,
  470. stepsMax: 0,
  471. icon: "dense"
  472. })
  473. infillModel.append({
  474. percentageMin: 90,
  475. percentageMax: 9999999999,
  476. stepsMin: -1,
  477. stepsMax: 0,
  478. icon: "solid"
  479. })
  480. infillModel.append({
  481. percentageMin: 0,
  482. percentageMax: 9999999999,
  483. stepsMin: 1,
  484. stepsMax: 9999999999,
  485. icon: "gradual"
  486. })
  487. }
  488. }
  489. }
  490. //
  491. // Enable support
  492. //
  493. Text
  494. {
  495. id: enableSupportLabel
  496. visible: enableSupportCheckBox.visible
  497. anchors.top: infillCellRight.bottom
  498. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  499. anchors.left: parent.left
  500. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  501. anchors.verticalCenter: enableSupportCheckBox.verticalCenter
  502. text: catalog.i18nc("@label", "Generate Support");
  503. font: UM.Theme.getFont("default");
  504. color: UM.Theme.getColor("text");
  505. }
  506. CheckBox
  507. {
  508. id: enableSupportCheckBox
  509. property alias _hovered: enableSupportMouseArea.containsMouse
  510. anchors.top: infillCellRight.bottom
  511. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  512. anchors.left: infillCellRight.left
  513. style: UM.Theme.styles.checkbox;
  514. enabled: base.settingsEnabled
  515. visible: supportEnabled.properties.enabled == "True"
  516. checked: supportEnabled.properties.value == "True";
  517. MouseArea
  518. {
  519. id: enableSupportMouseArea
  520. anchors.fill: parent
  521. hoverEnabled: true
  522. enabled: true
  523. onClicked:
  524. {
  525. // The value is a string "True" or "False"
  526. supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True");
  527. }
  528. onEntered:
  529. {
  530. base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0),
  531. catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."));
  532. }
  533. onExited:
  534. {
  535. base.hideTooltip();
  536. }
  537. }
  538. }
  539. Text
  540. {
  541. id: supportExtruderLabel
  542. visible: supportExtruderCombobox.visible
  543. anchors.left: parent.left
  544. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  545. anchors.verticalCenter: supportExtruderCombobox.verticalCenter
  546. text: catalog.i18nc("@label", "Support Extruder");
  547. font: UM.Theme.getFont("default");
  548. color: UM.Theme.getColor("text");
  549. }
  550. ComboBox
  551. {
  552. id: supportExtruderCombobox
  553. visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
  554. model: extruderModel
  555. property string color_override: "" // for manually setting values
  556. property string color: // is evaluated automatically, but the first time is before extruderModel being filled
  557. {
  558. var current_extruder = extruderModel.get(currentIndex);
  559. color_override = "";
  560. if (current_extruder === undefined) return ""
  561. return (current_extruder.color) ? current_extruder.color : "";
  562. }
  563. textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
  564. anchors.top: enableSupportCheckBox.bottom
  565. anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
  566. anchors.left: infillCellRight.left
  567. width: UM.Theme.getSize("sidebar").width * .55
  568. height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0
  569. Behavior on height { NumberAnimation { duration: 100 } }
  570. style: UM.Theme.styles.combobox_color
  571. enabled: base.settingsEnabled
  572. property alias _hovered: supportExtruderMouseArea.containsMouse
  573. currentIndex: supportExtruderNr.properties !== null ? parseFloat(supportExtruderNr.properties.value) : 0
  574. onActivated:
  575. {
  576. // Send the extruder nr as a string.
  577. supportExtruderNr.setPropertyValue("value", String(index));
  578. }
  579. MouseArea
  580. {
  581. id: supportExtruderMouseArea
  582. anchors.fill: parent
  583. hoverEnabled: true
  584. enabled: base.settingsEnabled
  585. acceptedButtons: Qt.NoButton
  586. onEntered:
  587. {
  588. base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0),
  589. catalog.i18nc("@label", "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."));
  590. }
  591. onExited:
  592. {
  593. base.hideTooltip();
  594. }
  595. }
  596. function updateCurrentColor()
  597. {
  598. var current_extruder = extruderModel.get(currentIndex);
  599. if (current_extruder !== undefined) {
  600. supportExtruderCombobox.color_override = current_extruder.color;
  601. }
  602. }
  603. }
  604. Text
  605. {
  606. id: adhesionHelperLabel
  607. visible: adhesionCheckBox.visible
  608. anchors.left: parent.left
  609. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  610. anchors.right: infillCellLeft.right
  611. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  612. anchors.verticalCenter: adhesionCheckBox.verticalCenter
  613. text: catalog.i18nc("@label", "Build Plate Adhesion");
  614. font: UM.Theme.getFont("default");
  615. color: UM.Theme.getColor("text");
  616. elide: Text.ElideRight
  617. }
  618. CheckBox
  619. {
  620. id: adhesionCheckBox
  621. property alias _hovered: adhesionMouseArea.containsMouse
  622. anchors.top: enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom
  623. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  624. anchors.left: infillCellRight.left
  625. //: Setting enable printing build-plate adhesion helper checkbox
  626. style: UM.Theme.styles.checkbox;
  627. enabled: base.settingsEnabled
  628. visible: platformAdhesionType.properties.enabled == "True"
  629. checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
  630. MouseArea
  631. {
  632. id: adhesionMouseArea
  633. anchors.fill: parent
  634. hoverEnabled: true
  635. enabled: base.settingsEnabled
  636. onClicked:
  637. {
  638. var adhesionType = "skirt";
  639. if(!parent.checked)
  640. {
  641. // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft
  642. platformAdhesionType.removeFromContainer(0);
  643. adhesionType = platformAdhesionType.properties.value;
  644. if(adhesionType == "skirt" || adhesionType == "none")
  645. {
  646. // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim
  647. adhesionType = "brim";
  648. }
  649. }
  650. platformAdhesionType.setPropertyValue("value", adhesionType);
  651. }
  652. onEntered:
  653. {
  654. base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0),
  655. catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."));
  656. }
  657. onExited:
  658. {
  659. base.hideTooltip();
  660. }
  661. }
  662. }
  663. ListModel
  664. {
  665. id: extruderModel
  666. Component.onCompleted: populateExtruderModel()
  667. }
  668. //: Model used to populate the extrudelModel
  669. Cura.ExtrudersModel
  670. {
  671. id: extruders
  672. onModelChanged: populateExtruderModel()
  673. }
  674. Item
  675. {
  676. id: tipsCell
  677. anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
  678. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
  679. anchors.left: parent.left
  680. width: parent.width
  681. height: tipsText.contentHeight * tipsText.lineCount
  682. Text
  683. {
  684. id: tipsText
  685. anchors.left: parent.left
  686. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  687. anchors.right: parent.right
  688. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  689. anchors.top: parent.top
  690. wrapMode: Text.WordWrap
  691. text: catalog.i18nc("@label", "Need help improving your prints?<br>Read the <a href='%1'>Ultimaker Troubleshooting Guides</a>").arg("https://ultimaker.com/en/troubleshooting")
  692. font: UM.Theme.getFont("default");
  693. color: UM.Theme.getColor("text");
  694. linkColor: UM.Theme.getColor("text_link")
  695. onLinkActivated: Qt.openUrlExternally(link)
  696. }
  697. }
  698. UM.SettingPropertyProvider
  699. {
  700. id: infillExtruderNumber
  701. containerStackId: Cura.MachineManager.activeStackId
  702. key: "infill_extruder_nr"
  703. watchedProperties: [ "value" ]
  704. storeIndex: 0
  705. }
  706. UM.SettingPropertyProvider
  707. {
  708. id: infillDensity
  709. containerStackId: Cura.MachineManager.activeStackId
  710. key: "infill_sparse_density"
  711. watchedProperties: [ "value" ]
  712. storeIndex: 0
  713. }
  714. UM.SettingPropertyProvider
  715. {
  716. id: infillSteps
  717. containerStackId: Cura.MachineManager.activeStackId
  718. key: "gradual_infill_steps"
  719. watchedProperties: ["value"]
  720. storeIndex: 0
  721. }
  722. UM.SettingPropertyProvider
  723. {
  724. id: platformAdhesionType
  725. containerStackId: Cura.MachineManager.activeMachineId
  726. key: "adhesion_type"
  727. watchedProperties: [ "value", "enabled" ]
  728. storeIndex: 0
  729. }
  730. UM.SettingPropertyProvider
  731. {
  732. id: supportEnabled
  733. containerStackId: Cura.MachineManager.activeMachineId
  734. key: "support_enable"
  735. watchedProperties: [ "value", "enabled", "description" ]
  736. storeIndex: 0
  737. }
  738. UM.SettingPropertyProvider
  739. {
  740. id: machineExtruderCount
  741. containerStackId: Cura.MachineManager.activeMachineId
  742. key: "machine_extruder_count"
  743. watchedProperties: [ "value" ]
  744. storeIndex: 0
  745. }
  746. UM.SettingPropertyProvider
  747. {
  748. id: supportExtruderNr
  749. containerStackId: Cura.MachineManager.activeMachineId
  750. key: "support_extruder_nr"
  751. watchedProperties: [ "value" ]
  752. storeIndex: 0
  753. }
  754. }
  755. }
  756. function populateExtruderModel()
  757. {
  758. extruderModel.clear();
  759. for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++)
  760. {
  761. extruderModel.append({
  762. text: extruders.getItem(extruderNumber).name,
  763. color: extruders.getItem(extruderNumber).color
  764. })
  765. }
  766. supportExtruderCombobox.updateCurrentColor();
  767. }
  768. }