SidebarSimple.qml 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  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 / 2 // closer to slider since it belongs to the same category
  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 * 1.5
  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: enableSupportLabel.top
  511. anchors.left: infillCellRight.left
  512. style: UM.Theme.styles.checkbox;
  513. enabled: base.settingsEnabled
  514. visible: supportEnabled.properties.enabled == "True"
  515. checked: supportEnabled.properties.value == "True";
  516. MouseArea
  517. {
  518. id: enableSupportMouseArea
  519. anchors.fill: parent
  520. hoverEnabled: true
  521. enabled: true
  522. onClicked:
  523. {
  524. // The value is a string "True" or "False"
  525. supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True");
  526. }
  527. onEntered:
  528. {
  529. base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0),
  530. catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."));
  531. }
  532. onExited:
  533. {
  534. base.hideTooltip();
  535. }
  536. }
  537. }
  538. Text
  539. {
  540. id: supportExtruderLabel
  541. visible: supportExtruderCombobox.visible
  542. anchors.left: parent.left
  543. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  544. anchors.verticalCenter: supportExtruderCombobox.verticalCenter
  545. text: catalog.i18nc("@label", "Support Extruder");
  546. font: UM.Theme.getFont("default");
  547. color: UM.Theme.getColor("text");
  548. }
  549. ComboBox
  550. {
  551. id: supportExtruderCombobox
  552. visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
  553. model: extruderModel
  554. property string color_override: "" // for manually setting values
  555. property string color: // is evaluated automatically, but the first time is before extruderModel being filled
  556. {
  557. var current_extruder = extruderModel.get(currentIndex);
  558. color_override = "";
  559. if (current_extruder === undefined) return ""
  560. return (current_extruder.color) ? current_extruder.color : "";
  561. }
  562. textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
  563. anchors.top: enableSupportCheckBox.bottom
  564. anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
  565. anchors.left: infillCellRight.left
  566. width: UM.Theme.getSize("sidebar").width * .55
  567. height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0
  568. Behavior on height { NumberAnimation { duration: 100 } }
  569. style: UM.Theme.styles.combobox_color
  570. enabled: base.settingsEnabled
  571. property alias _hovered: supportExtruderMouseArea.containsMouse
  572. currentIndex: supportExtruderNr.properties !== null ? parseFloat(supportExtruderNr.properties.value) : 0
  573. onActivated:
  574. {
  575. // Send the extruder nr as a string.
  576. supportExtruderNr.setPropertyValue("value", String(index));
  577. }
  578. MouseArea
  579. {
  580. id: supportExtruderMouseArea
  581. anchors.fill: parent
  582. hoverEnabled: true
  583. enabled: base.settingsEnabled
  584. acceptedButtons: Qt.NoButton
  585. onEntered:
  586. {
  587. base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0),
  588. 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."));
  589. }
  590. onExited:
  591. {
  592. base.hideTooltip();
  593. }
  594. }
  595. function updateCurrentColor()
  596. {
  597. var current_extruder = extruderModel.get(currentIndex);
  598. if (current_extruder !== undefined) {
  599. supportExtruderCombobox.color_override = current_extruder.color;
  600. }
  601. }
  602. }
  603. Text
  604. {
  605. id: adhesionHelperLabel
  606. visible: adhesionCheckBox.visible
  607. text: catalog.i18nc("@label", "Build Plate Adhesion")
  608. font: UM.Theme.getFont("default")
  609. color: UM.Theme.getColor("text")
  610. elide: Text.ElideRight
  611. anchors {
  612. left: parent.left
  613. leftMargin: UM.Theme.getSize("sidebar_margin").width
  614. right: infillCellLeft.right
  615. rightMargin: UM.Theme.getSize("sidebar_margin").width
  616. verticalCenter: adhesionCheckBox.verticalCenter
  617. }
  618. }
  619. CheckBox
  620. {
  621. id: adhesionCheckBox
  622. property alias _hovered: adhesionMouseArea.containsMouse
  623. anchors.top: enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom
  624. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  625. anchors.left: infillCellRight.left
  626. //: Setting enable printing build-plate adhesion helper checkbox
  627. style: UM.Theme.styles.checkbox;
  628. enabled: base.settingsEnabled
  629. visible: platformAdhesionType.properties.enabled == "True"
  630. checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
  631. MouseArea
  632. {
  633. id: adhesionMouseArea
  634. anchors.fill: parent
  635. hoverEnabled: true
  636. enabled: base.settingsEnabled
  637. onClicked:
  638. {
  639. var adhesionType = "skirt";
  640. if(!parent.checked)
  641. {
  642. // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft
  643. platformAdhesionType.removeFromContainer(0);
  644. adhesionType = platformAdhesionType.properties.value;
  645. if(adhesionType == "skirt" || adhesionType == "none")
  646. {
  647. // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim
  648. adhesionType = "brim";
  649. }
  650. }
  651. platformAdhesionType.setPropertyValue("value", adhesionType);
  652. }
  653. onEntered:
  654. {
  655. base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0),
  656. 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."));
  657. }
  658. onExited:
  659. {
  660. base.hideTooltip();
  661. }
  662. }
  663. }
  664. ListModel
  665. {
  666. id: extruderModel
  667. Component.onCompleted: populateExtruderModel()
  668. }
  669. //: Model used to populate the extrudelModel
  670. Cura.ExtrudersModel
  671. {
  672. id: extruders
  673. onModelChanged: populateExtruderModel()
  674. }
  675. Item
  676. {
  677. id: tipsCell
  678. anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
  679. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
  680. anchors.left: parent.left
  681. width: parent.width
  682. height: tipsText.contentHeight * tipsText.lineCount
  683. Text
  684. {
  685. id: tipsText
  686. anchors.left: parent.left
  687. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  688. anchors.right: parent.right
  689. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  690. anchors.top: parent.top
  691. wrapMode: Text.WordWrap
  692. 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")
  693. font: UM.Theme.getFont("default");
  694. color: UM.Theme.getColor("text");
  695. linkColor: UM.Theme.getColor("text_link")
  696. onLinkActivated: Qt.openUrlExternally(link)
  697. }
  698. }
  699. UM.SettingPropertyProvider
  700. {
  701. id: infillExtruderNumber
  702. containerStackId: Cura.MachineManager.activeStackId
  703. key: "infill_extruder_nr"
  704. watchedProperties: [ "value" ]
  705. storeIndex: 0
  706. }
  707. UM.SettingPropertyProvider
  708. {
  709. id: infillDensity
  710. containerStackId: Cura.MachineManager.activeStackId
  711. key: "infill_sparse_density"
  712. watchedProperties: [ "value" ]
  713. storeIndex: 0
  714. }
  715. UM.SettingPropertyProvider
  716. {
  717. id: infillSteps
  718. containerStackId: Cura.MachineManager.activeStackId
  719. key: "gradual_infill_steps"
  720. watchedProperties: ["value"]
  721. storeIndex: 0
  722. }
  723. UM.SettingPropertyProvider
  724. {
  725. id: platformAdhesionType
  726. containerStackId: Cura.MachineManager.activeMachineId
  727. key: "adhesion_type"
  728. watchedProperties: [ "value", "enabled" ]
  729. storeIndex: 0
  730. }
  731. UM.SettingPropertyProvider
  732. {
  733. id: supportEnabled
  734. containerStackId: Cura.MachineManager.activeMachineId
  735. key: "support_enable"
  736. watchedProperties: [ "value", "enabled", "description" ]
  737. storeIndex: 0
  738. }
  739. UM.SettingPropertyProvider
  740. {
  741. id: machineExtruderCount
  742. containerStackId: Cura.MachineManager.activeMachineId
  743. key: "machine_extruder_count"
  744. watchedProperties: [ "value" ]
  745. storeIndex: 0
  746. }
  747. UM.SettingPropertyProvider
  748. {
  749. id: supportExtruderNr
  750. containerStackId: Cura.MachineManager.activeMachineId
  751. key: "support_extruder_nr"
  752. watchedProperties: [ "value" ]
  753. storeIndex: 0
  754. }
  755. }
  756. }
  757. function populateExtruderModel()
  758. {
  759. extruderModel.clear();
  760. for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++)
  761. {
  762. extruderModel.append({
  763. text: extruders.getItem(extruderNumber).name,
  764. color: extruders.getItem(extruderNumber).color
  765. })
  766. }
  767. supportExtruderCombobox.updateCurrentColor();
  768. }
  769. }