RecommendedInfillDensitySelector.qml 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.7
  4. import QtQuick.Controls 2.15
  5. import UM 1.5 as UM
  6. import Cura 1.0 as Cura
  7. //
  8. // Infill
  9. //
  10. Item
  11. {
  12. id: infillRow
  13. height: childrenRect.height
  14. property real labelColumnWidth: Math.round(width / 3)
  15. // Create a binding to update the icon when the infill density changes
  16. Binding
  17. {
  18. target: infillRowTitle
  19. property: "source"
  20. value:
  21. {
  22. var density = parseInt(infillDensity.properties.value)
  23. if (parseInt(infillSteps.properties.value) != 0)
  24. {
  25. return UM.Theme.getIcon("InfillGradual")
  26. }
  27. if (density <= 0)
  28. {
  29. return UM.Theme.getIcon("Infill0")
  30. }
  31. if (density < 40)
  32. {
  33. return UM.Theme.getIcon("Infill3")
  34. }
  35. if (density < 90)
  36. {
  37. return UM.Theme.getIcon("Infill2")
  38. }
  39. return UM.Theme.getIcon("Infill100")
  40. }
  41. }
  42. // We use a binding to make sure that after manually setting infillSlider.value it is still bound to the property provider
  43. Binding
  44. {
  45. target: infillSlider
  46. property: "value"
  47. value: parseInt(infillDensity.properties.value)
  48. }
  49. // Here are the elements that are shown in the left column
  50. Cura.IconWithText
  51. {
  52. id: infillRowTitle
  53. anchors.top: parent.top
  54. anchors.left: parent.left
  55. source: UM.Theme.getIcon("Infill1")
  56. text: catalog.i18nc("@label", "Infill") + " (%)"
  57. font: UM.Theme.getFont("medium")
  58. width: labelColumnWidth
  59. iconSize: UM.Theme.getSize("medium_button_icon").width
  60. tooltipText: catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top.")
  61. }
  62. Item
  63. {
  64. id: infillSliderContainer
  65. height: childrenRect.height
  66. anchors
  67. {
  68. left: infillRowTitle.right
  69. right: parent.right
  70. verticalCenter: infillRowTitle.verticalCenter
  71. }
  72. Slider
  73. {
  74. id: infillSlider
  75. width: parent.width
  76. height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider
  77. from: 0
  78. to: 100
  79. stepSize: 1
  80. // disable slider when gradual support is enabled
  81. enabled: parseInt(infillSteps.properties.value) == 0
  82. // set initial value from stack
  83. value: parseInt(infillDensity.properties.value)
  84. //Draw line
  85. background: Rectangle
  86. {
  87. id: backgroundLine
  88. height: UM.Theme.getSize("print_setup_slider_groove").height
  89. width: parent.width - UM.Theme.getSize("print_setup_slider_handle").width
  90. anchors.horizontalCenter: parent.horizontalCenter
  91. anchors.verticalCenter: parent.verticalCenter
  92. color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  93. Repeater
  94. {
  95. id: repeater
  96. anchors.fill: parent
  97. model: infillSlider.to / infillSlider.stepSize + 1
  98. Rectangle
  99. {
  100. color: infillSlider.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
  101. implicitWidth: UM.Theme.getSize("print_setup_slider_tickmarks").width
  102. implicitHeight: UM.Theme.getSize("print_setup_slider_tickmarks").height
  103. anchors.verticalCenter: parent.verticalCenter
  104. // Do not use Math.round otherwise the tickmarks won't be aligned
  105. // (space between steps) * index of step
  106. x: (backgroundLine.width / (repeater.count - 1)) * index
  107. radius: Math.round(implicitWidth / 2)
  108. visible: (index % 10) == 0 // Only show steps of 10%
  109. UM.Label
  110. {
  111. text: index
  112. visible: (index % 20) == 0 // Only show steps of 20%
  113. anchors.horizontalCenter: parent.horizontalCenter
  114. y: UM.Theme.getSize("thin_margin").height
  115. color: UM.Theme.getColor("quality_slider_available")
  116. }
  117. }
  118. }
  119. }
  120. handle: Rectangle
  121. {
  122. id: handleButton
  123. x: infillSlider.leftPadding + infillSlider.visualPosition * (infillSlider.availableWidth - width)
  124. y: infillSlider.topPadding + infillSlider.availableHeight / 2 - height / 2
  125. color: infillSlider.enabled ? UM.Theme.getColor("primary") : UM.Theme.getColor("quality_slider_unavailable")
  126. implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width
  127. implicitHeight: implicitWidth
  128. radius: Math.round(implicitWidth / 2)
  129. border.color: UM.Theme.getColor("slider_groove_fill")
  130. border.width: UM.Theme.getSize("default_lining").height
  131. }
  132. Connections
  133. {
  134. target: infillSlider
  135. function onValueChanged()
  136. {
  137. // Don't round the value if it's already the same
  138. if (parseInt(infillDensity.properties.value) == infillSlider.value)
  139. {
  140. return
  141. }
  142. // Round the slider value to the nearest multiple of 10 (simulate step size of 10)
  143. var roundedSliderValue = Math.round(infillSlider.value / 10) * 10
  144. // Update the slider value to represent the rounded value
  145. infillSlider.value = roundedSliderValue
  146. // Update value only if the Recommended mode is Active,
  147. // Otherwise if I change the value in the Custom mode the Recommended view will try to repeat
  148. // same operation
  149. const active_mode = UM.Preferences.getValue("cura/active_mode")
  150. if (visible // Workaround: 'visible' is checked because on startup in Windows it spuriously gets an 'onValueChanged' with value '0' if this isn't checked.
  151. && (active_mode == 0 || active_mode == "simple"))
  152. {
  153. Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
  154. Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance")
  155. }
  156. }
  157. }
  158. }
  159. }
  160. // Gradual Support Infill Checkbox
  161. UM.CheckBox
  162. {
  163. id: enableGradualInfillCheckBox
  164. property alias _hovered: enableGradualInfillMouseArea.containsMouse
  165. anchors.top: infillSliderContainer.bottom
  166. anchors.topMargin: UM.Theme.getSize("wide_margin").height
  167. anchors.left: infillSliderContainer.left
  168. text: catalog.i18nc("@label", "Gradual infill")
  169. enabled: recommendedPrintSetup.settingsEnabled
  170. visible: infillSteps.properties.enabled == "True"
  171. checked: parseInt(infillSteps.properties.value) > 0
  172. MouseArea
  173. {
  174. id: enableGradualInfillMouseArea
  175. anchors.fill: parent
  176. hoverEnabled: true
  177. enabled: true
  178. property var previousInfillDensity: parseInt(infillDensity.properties.value)
  179. onClicked:
  180. {
  181. // Set to 90% only when enabling gradual infill
  182. var newInfillDensity;
  183. if (parseInt(infillSteps.properties.value) == 0)
  184. {
  185. previousInfillDensity = parseInt(infillDensity.properties.value)
  186. newInfillDensity = 90
  187. } else {
  188. newInfillDensity = previousInfillDensity
  189. }
  190. Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity))
  191. var infill_steps_value = 0
  192. if (parseInt(infillSteps.properties.value) == 0)
  193. {
  194. infill_steps_value = 5
  195. }
  196. Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value)
  197. }
  198. onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x - UM.Theme.getSize("thick_margin").width, 0),
  199. catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."))
  200. onExited: base.hideTooltip()
  201. }
  202. }
  203. UM.SettingPropertyProvider
  204. {
  205. id: infillDensity
  206. containerStackId: Cura.MachineManager.activeStackId
  207. key: "infill_sparse_density"
  208. watchedProperties: [ "value" ]
  209. storeIndex: 0
  210. }
  211. UM.SettingPropertyProvider
  212. {
  213. id: infillSteps
  214. containerStackId: Cura.MachineManager.activeStackId
  215. key: "gradual_infill_steps"
  216. watchedProperties: ["value", "enabled"]
  217. storeIndex: 0
  218. }
  219. }