SidebarSimple.qml 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  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 (qualityModel.totalTicks == 0) {
  154. // If there is only one tick, align it centrally
  155. return ((base.width * 0.55) - width) / 2
  156. } else if (index == 0) {
  157. return (base.width * 0.55 / qualityModel.totalTicks) * index
  158. } else if (index == qualityModel.totalTicks) {
  159. return (base.width * 0.55 / qualityModel.totalTicks) * index - width
  160. } else {
  161. return (base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)
  162. }
  163. }
  164. }
  165. }
  166. }
  167. //Print speed slider
  168. Item
  169. {
  170. id: speedSlider
  171. width: base.width * 0.55
  172. height: UM.Theme.getSize("sidebar_margin").height
  173. anchors.right: parent.right
  174. anchors.top: parent.top
  175. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  176. // Draw Unavailable line
  177. Rectangle
  178. {
  179. id: groovechildrect
  180. width: base.width * 0.55
  181. height: 2 * screenScaleFactor
  182. color: UM.Theme.getColor("quality_slider_unavailable")
  183. anchors.verticalCenter: qualitySlider.verticalCenter
  184. x: 0
  185. }
  186. // Draw ticks
  187. Repeater
  188. {
  189. id: qualityRepeater
  190. model: qualityModel.totalTicks > 0 ? qualityModel : 0
  191. Rectangle
  192. {
  193. anchors.verticalCenter: parent.verticalCenter
  194. color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  195. width: 1 * screenScaleFactor
  196. height: 6 * screenScaleFactor
  197. y: 0
  198. x: qualityModel.qualitySliderStepWidth * index
  199. }
  200. }
  201. Rectangle {
  202. id: disabledHandleButton
  203. visible: !qualitySlider.visible
  204. anchors.centerIn: parent
  205. color: UM.Theme.getColor("quality_slider_unavailable")
  206. implicitWidth: 10 * screenScaleFactor
  207. implicitHeight: implicitWidth
  208. radius: width / 2
  209. }
  210. Slider
  211. {
  212. id: qualitySlider
  213. height: UM.Theme.getSize("sidebar_margin").height
  214. anchors.bottom: speedSlider.bottom
  215. enabled: qualityModel.availableTotalTicks > 0
  216. visible: qualityModel.totalTicks > 0
  217. updateValueWhileDragging : false
  218. minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0
  219. maximumValue: qualityModel.qualitySliderAvailableMax >= 0 ? qualityModel.qualitySliderAvailableMax : 0
  220. stepSize: 1
  221. value: qualityModel.activeQualityId
  222. width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks
  223. anchors.right: parent.right
  224. anchors.rightMargin: qualityModel.qualitySliderMarginRight
  225. style: SliderStyle
  226. {
  227. //Draw Available line
  228. groove: Rectangle {
  229. implicitHeight: 2 * screenScaleFactor
  230. color: UM.Theme.getColor("quality_slider_available")
  231. radius: height / 2
  232. }
  233. handle: Item {
  234. Rectangle {
  235. id: qualityhandleButton
  236. anchors.centerIn: parent
  237. color: UM.Theme.getColor("quality_slider_available")
  238. implicitWidth: 10 * screenScaleFactor
  239. implicitHeight: implicitWidth
  240. radius: implicitWidth / 2
  241. }
  242. }
  243. }
  244. onValueChanged: {
  245. if(Cura.MachineManager.activeMachine != null)
  246. {
  247. //Prevent updating during view initializing. Trigger only if the value changed by user
  248. if(qualitySlider.value != qualityModel.activeQualityId)
  249. {
  250. //start updating with short delay
  251. qualitySliderChangeTimer.start();
  252. }
  253. }
  254. }
  255. }
  256. }
  257. Text
  258. {
  259. id: speedLabel
  260. anchors.top: speedSlider.bottom
  261. anchors.left: parent.left
  262. text: catalog.i18nc("@label", "Print Speed")
  263. font: UM.Theme.getFont("default")
  264. color: UM.Theme.getColor("text")
  265. }
  266. Text
  267. {
  268. anchors.bottom: speedLabel.bottom
  269. anchors.left: speedSlider.left
  270. text: catalog.i18nc("@label", "Slower")
  271. font: UM.Theme.getFont("default")
  272. color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  273. horizontalAlignment: Text.AlignLeft
  274. }
  275. Text
  276. {
  277. anchors.bottom: speedLabel.bottom
  278. anchors.right: speedSlider.right
  279. text: catalog.i18nc("@label", "Faster")
  280. font: UM.Theme.getFont("default")
  281. color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  282. horizontalAlignment: Text.AlignRight
  283. }
  284. }
  285. //
  286. // Infill
  287. //
  288. Item
  289. {
  290. id: infillCellLeft
  291. anchors.top: qualityRow.bottom
  292. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
  293. anchors.left: parent.left
  294. width: UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width
  295. Text
  296. {
  297. id: infillLabel
  298. text: catalog.i18nc("@label", "Infill")
  299. font: UM.Theme.getFont("default")
  300. color: UM.Theme.getColor("text")
  301. anchors.top: parent.top
  302. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 1.7
  303. anchors.left: parent.left
  304. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  305. }
  306. }
  307. Item
  308. {
  309. id: infillCellRight
  310. height: infillSlider.height + UM.Theme.getSize("sidebar_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("sidebar_margin").height)
  311. width: UM.Theme.getSize("sidebar").width * .55
  312. anchors.left: infillCellLeft.right
  313. anchors.top: infillCellLeft.top
  314. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  315. Text {
  316. id: selectedInfillRateText
  317. //anchors.top: parent.top
  318. anchors.left: infillSlider.left
  319. anchors.leftMargin: (infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor
  320. anchors.right: parent.right
  321. text: infillSlider.value + "%"
  322. horizontalAlignment: Text.AlignLeft
  323. color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  324. }
  325. Slider
  326. {
  327. id: infillSlider
  328. anchors.top: selectedInfillRateText.bottom
  329. anchors.left: parent.left
  330. anchors.right: infillIcon.left
  331. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  332. height: UM.Theme.getSize("sidebar_margin").height
  333. width: infillCellRight.width - UM.Theme.getSize("sidebar_margin").width - style.handleWidth
  334. minimumValue: 0
  335. maximumValue: 100
  336. stepSize: (parseInt(infillDensity.properties.value) % 10 == 0) ? 10 : 1
  337. tickmarksEnabled: true
  338. // disable slider when gradual support is enabled
  339. enabled: parseInt(infillSteps.properties.value) == 0
  340. // set initial value from stack
  341. value: parseInt(infillDensity.properties.value)
  342. onValueChanged: {
  343. // Explicitly cast to string to make sure the value passed to Python is an integer.
  344. infillDensity.setPropertyValue("value", String(parseInt(infillSlider.value)))
  345. }
  346. style: SliderStyle
  347. {
  348. groove: Rectangle {
  349. id: groove
  350. implicitWidth: 200 * screenScaleFactor
  351. implicitHeight: 2 * screenScaleFactor
  352. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  353. radius: 1
  354. }
  355. handle: Item {
  356. Rectangle {
  357. id: handleButton
  358. anchors.centerIn: parent
  359. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  360. implicitWidth: 10 * screenScaleFactor
  361. implicitHeight: 10 * screenScaleFactor
  362. radius: 10 * screenScaleFactor
  363. }
  364. }
  365. tickmarks: Repeater {
  366. id: repeater
  367. model: control.maximumValue / control.stepSize + 1
  368. // check if a tick should be shown based on it's index and wether the infill density is a multiple of 10 (slider step size)
  369. function shouldShowTick (index) {
  370. if ((parseInt(infillDensity.properties.value) % 10 == 0) || (index % 10 == 0)) {
  371. return true
  372. }
  373. return false
  374. }
  375. Rectangle {
  376. anchors.verticalCenter: parent.verticalCenter
  377. color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  378. width: 1 * screenScaleFactor
  379. height: 6 * screenScaleFactor
  380. y: 0
  381. x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))
  382. visible: shouldShowTick(index)
  383. }
  384. }
  385. }
  386. }
  387. Rectangle
  388. {
  389. id: infillIcon
  390. width: (parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width)
  391. height: width
  392. anchors.right: parent.right
  393. anchors.top: parent.top
  394. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
  395. // we loop over all density icons and only show the one that has the current density and steps
  396. Repeater
  397. {
  398. id: infillIconList
  399. model: infillModel
  400. anchors.fill: parent
  401. property int activeIndex: {
  402. for (var i = 0; i < infillModel.count; i++) {
  403. var density = parseInt(infillDensity.properties.value)
  404. var steps = parseInt(infillSteps.properties.value)
  405. var infillModelItem = infillModel.get(i)
  406. if (density >= infillModelItem.percentageMin
  407. && density <= infillModelItem.percentageMax
  408. && steps >= infillModelItem.stepsMin
  409. && steps <= infillModelItem.stepsMax){
  410. return i
  411. }
  412. }
  413. return -1
  414. }
  415. Rectangle
  416. {
  417. anchors.fill: parent
  418. visible: infillIconList.activeIndex == index
  419. border.width: UM.Theme.getSize("default_lining").width
  420. border.color: UM.Theme.getColor("quality_slider_unavailable")
  421. UM.RecolorImage {
  422. anchors.fill: parent
  423. anchors.margins: 2 * screenScaleFactor
  424. sourceSize.width: width
  425. sourceSize.height: width
  426. source: UM.Theme.getIcon(model.icon)
  427. color: UM.Theme.getColor("quality_slider_unavailable")
  428. }
  429. }
  430. }
  431. }
  432. // Gradual Support Infill Checkbox
  433. CheckBox {
  434. id: enableGradualInfillCheckBox
  435. property alias _hovered: enableGradualInfillMouseArea.containsMouse
  436. anchors.top: infillSlider.bottom
  437. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 // closer to slider since it belongs to the same category
  438. anchors.left: infillCellRight.left
  439. style: UM.Theme.styles.checkbox
  440. enabled: base.settingsEnabled
  441. visible: infillSteps.properties.enabled == "True"
  442. checked: parseInt(infillSteps.properties.value) > 0
  443. MouseArea {
  444. id: enableGradualInfillMouseArea
  445. anchors.fill: parent
  446. hoverEnabled: true
  447. enabled: true
  448. onClicked: {
  449. infillSteps.setPropertyValue("value", (parseInt(infillSteps.properties.value) == 0) ? 5 : 0)
  450. infillDensity.setPropertyValue("value", 90)
  451. }
  452. onEntered: {
  453. base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillCellRight.x, 0),
  454. catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."))
  455. }
  456. onExited: {
  457. base.hideTooltip()
  458. }
  459. }
  460. Text {
  461. id: gradualInfillLabel
  462. anchors.left: enableGradualInfillCheckBox.right
  463. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2
  464. text: catalog.i18nc("@label", "Enable gradual")
  465. font: UM.Theme.getFont("default")
  466. color: UM.Theme.getColor("text")
  467. }
  468. }
  469. // Infill list model for mapping icon
  470. ListModel
  471. {
  472. id: infillModel
  473. Component.onCompleted:
  474. {
  475. infillModel.append({
  476. percentageMin: -1,
  477. percentageMax: 0,
  478. stepsMin: -1,
  479. stepsMax: 0,
  480. icon: "hollow"
  481. })
  482. infillModel.append({
  483. percentageMin: 0,
  484. percentageMax: 40,
  485. stepsMin: -1,
  486. stepsMax: 0,
  487. icon: "sparse"
  488. })
  489. infillModel.append({
  490. percentageMin: 40,
  491. percentageMax: 89,
  492. stepsMin: -1,
  493. stepsMax: 0,
  494. icon: "dense"
  495. })
  496. infillModel.append({
  497. percentageMin: 90,
  498. percentageMax: 9999999999,
  499. stepsMin: -1,
  500. stepsMax: 0,
  501. icon: "solid"
  502. })
  503. infillModel.append({
  504. percentageMin: 0,
  505. percentageMax: 9999999999,
  506. stepsMin: 1,
  507. stepsMax: 9999999999,
  508. icon: "gradual"
  509. })
  510. }
  511. }
  512. }
  513. //
  514. // Enable support
  515. //
  516. Text
  517. {
  518. id: enableSupportLabel
  519. visible: enableSupportCheckBox.visible
  520. anchors.top: infillCellRight.bottom
  521. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 1.5
  522. anchors.left: parent.left
  523. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  524. anchors.verticalCenter: enableSupportCheckBox.verticalCenter
  525. text: catalog.i18nc("@label", "Generate Support");
  526. font: UM.Theme.getFont("default");
  527. color: UM.Theme.getColor("text");
  528. }
  529. CheckBox
  530. {
  531. id: enableSupportCheckBox
  532. property alias _hovered: enableSupportMouseArea.containsMouse
  533. anchors.top: enableSupportLabel.top
  534. anchors.left: infillCellRight.left
  535. style: UM.Theme.styles.checkbox;
  536. enabled: base.settingsEnabled
  537. visible: supportEnabled.properties.enabled == "True"
  538. checked: supportEnabled.properties.value == "True";
  539. MouseArea
  540. {
  541. id: enableSupportMouseArea
  542. anchors.fill: parent
  543. hoverEnabled: true
  544. enabled: true
  545. onClicked:
  546. {
  547. // The value is a string "True" or "False"
  548. supportEnabled.setPropertyValue("value", supportEnabled.properties.value != "True");
  549. }
  550. onEntered:
  551. {
  552. base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0),
  553. catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."));
  554. }
  555. onExited:
  556. {
  557. base.hideTooltip();
  558. }
  559. }
  560. }
  561. Text
  562. {
  563. id: supportExtruderLabel
  564. visible: supportExtruderCombobox.visible
  565. anchors.left: parent.left
  566. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  567. anchors.verticalCenter: supportExtruderCombobox.verticalCenter
  568. text: catalog.i18nc("@label", "Support Extruder");
  569. font: UM.Theme.getFont("default");
  570. color: UM.Theme.getColor("text");
  571. }
  572. ComboBox
  573. {
  574. id: supportExtruderCombobox
  575. visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
  576. model: extruderModel
  577. property string color_override: "" // for manually setting values
  578. property string color: // is evaluated automatically, but the first time is before extruderModel being filled
  579. {
  580. var current_extruder = extruderModel.get(currentIndex);
  581. color_override = "";
  582. if (current_extruder === undefined) return ""
  583. return (current_extruder.color) ? current_extruder.color : "";
  584. }
  585. textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
  586. anchors.top: enableSupportCheckBox.bottom
  587. anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
  588. anchors.left: infillCellRight.left
  589. width: UM.Theme.getSize("sidebar").width * .55
  590. height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0
  591. Behavior on height { NumberAnimation { duration: 100 } }
  592. style: UM.Theme.styles.combobox_color
  593. enabled: base.settingsEnabled
  594. property alias _hovered: supportExtruderMouseArea.containsMouse
  595. currentIndex: supportExtruderNr.properties !== null ? parseFloat(supportExtruderNr.properties.value) : 0
  596. onActivated:
  597. {
  598. // Send the extruder nr as a string.
  599. supportExtruderNr.setPropertyValue("value", String(index));
  600. }
  601. MouseArea
  602. {
  603. id: supportExtruderMouseArea
  604. anchors.fill: parent
  605. hoverEnabled: true
  606. enabled: base.settingsEnabled
  607. acceptedButtons: Qt.NoButton
  608. onEntered:
  609. {
  610. base.showTooltip(supportExtruderCombobox, Qt.point(-supportExtruderCombobox.x, 0),
  611. 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."));
  612. }
  613. onExited:
  614. {
  615. base.hideTooltip();
  616. }
  617. }
  618. function updateCurrentColor()
  619. {
  620. var current_extruder = extruderModel.get(currentIndex);
  621. if (current_extruder !== undefined) {
  622. supportExtruderCombobox.color_override = current_extruder.color;
  623. }
  624. }
  625. }
  626. Text
  627. {
  628. id: adhesionHelperLabel
  629. visible: adhesionCheckBox.visible
  630. text: catalog.i18nc("@label", "Build Plate Adhesion")
  631. font: UM.Theme.getFont("default")
  632. color: UM.Theme.getColor("text")
  633. elide: Text.ElideRight
  634. anchors {
  635. left: parent.left
  636. leftMargin: UM.Theme.getSize("sidebar_margin").width
  637. right: infillCellLeft.right
  638. rightMargin: UM.Theme.getSize("sidebar_margin").width
  639. verticalCenter: adhesionCheckBox.verticalCenter
  640. }
  641. }
  642. CheckBox
  643. {
  644. id: adhesionCheckBox
  645. property alias _hovered: adhesionMouseArea.containsMouse
  646. anchors.top: enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom
  647. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
  648. anchors.left: infillCellRight.left
  649. //: Setting enable printing build-plate adhesion helper checkbox
  650. style: UM.Theme.styles.checkbox;
  651. enabled: base.settingsEnabled
  652. visible: platformAdhesionType.properties.enabled == "True"
  653. checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
  654. MouseArea
  655. {
  656. id: adhesionMouseArea
  657. anchors.fill: parent
  658. hoverEnabled: true
  659. enabled: base.settingsEnabled
  660. onClicked:
  661. {
  662. var adhesionType = "skirt";
  663. if(!parent.checked)
  664. {
  665. // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft
  666. platformAdhesionType.removeFromContainer(0);
  667. adhesionType = platformAdhesionType.properties.value;
  668. if(adhesionType == "skirt" || adhesionType == "none")
  669. {
  670. // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim
  671. adhesionType = "brim";
  672. }
  673. }
  674. platformAdhesionType.setPropertyValue("value", adhesionType);
  675. }
  676. onEntered:
  677. {
  678. base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0),
  679. 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."));
  680. }
  681. onExited:
  682. {
  683. base.hideTooltip();
  684. }
  685. }
  686. }
  687. ListModel
  688. {
  689. id: extruderModel
  690. Component.onCompleted: populateExtruderModel()
  691. }
  692. //: Model used to populate the extrudelModel
  693. Cura.ExtrudersModel
  694. {
  695. id: extruders
  696. onModelChanged: populateExtruderModel()
  697. }
  698. Item
  699. {
  700. id: tipsCell
  701. anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
  702. anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
  703. anchors.left: parent.left
  704. width: parent.width
  705. height: tipsText.contentHeight * tipsText.lineCount
  706. Text
  707. {
  708. id: tipsText
  709. anchors.left: parent.left
  710. anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
  711. anchors.right: parent.right
  712. anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
  713. anchors.top: parent.top
  714. wrapMode: Text.WordWrap
  715. 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")
  716. font: UM.Theme.getFont("default");
  717. color: UM.Theme.getColor("text");
  718. linkColor: UM.Theme.getColor("text_link")
  719. onLinkActivated: Qt.openUrlExternally(link)
  720. }
  721. }
  722. UM.SettingPropertyProvider
  723. {
  724. id: infillExtruderNumber
  725. containerStackId: Cura.MachineManager.activeStackId
  726. key: "infill_extruder_nr"
  727. watchedProperties: [ "value" ]
  728. storeIndex: 0
  729. }
  730. UM.SettingPropertyProvider
  731. {
  732. id: infillDensity
  733. containerStackId: Cura.MachineManager.activeStackId
  734. key: "infill_sparse_density"
  735. watchedProperties: [ "value" ]
  736. storeIndex: 0
  737. }
  738. UM.SettingPropertyProvider
  739. {
  740. id: infillSteps
  741. containerStackId: Cura.MachineManager.activeStackId
  742. key: "gradual_infill_steps"
  743. watchedProperties: ["value", "enabled"]
  744. storeIndex: 0
  745. }
  746. UM.SettingPropertyProvider
  747. {
  748. id: platformAdhesionType
  749. containerStackId: Cura.MachineManager.activeMachineId
  750. key: "adhesion_type"
  751. watchedProperties: [ "value", "enabled" ]
  752. storeIndex: 0
  753. }
  754. UM.SettingPropertyProvider
  755. {
  756. id: supportEnabled
  757. containerStackId: Cura.MachineManager.activeMachineId
  758. key: "support_enable"
  759. watchedProperties: [ "value", "enabled", "description" ]
  760. storeIndex: 0
  761. }
  762. UM.SettingPropertyProvider
  763. {
  764. id: machineExtruderCount
  765. containerStackId: Cura.MachineManager.activeMachineId
  766. key: "machine_extruder_count"
  767. watchedProperties: [ "value" ]
  768. storeIndex: 0
  769. }
  770. UM.SettingPropertyProvider
  771. {
  772. id: supportExtruderNr
  773. containerStackId: Cura.MachineManager.activeMachineId
  774. key: "support_extruder_nr"
  775. watchedProperties: [ "value" ]
  776. storeIndex: 0
  777. }
  778. }
  779. }
  780. function populateExtruderModel()
  781. {
  782. extruderModel.clear();
  783. for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++)
  784. {
  785. extruderModel.append({
  786. text: extruders.getItem(extruderNumber).name,
  787. color: extruders.getItem(extruderNumber).color
  788. })
  789. }
  790. supportExtruderCombobox.updateCurrentColor();
  791. }
  792. }