RecommendedInfillDensitySelector.qml 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. }
  61. Item
  62. {
  63. id: infillSliderContainer
  64. height: childrenRect.height
  65. anchors
  66. {
  67. left: infillRowTitle.right
  68. right: parent.right
  69. verticalCenter: infillRowTitle.verticalCenter
  70. }
  71. Slider
  72. {
  73. id: infillSlider
  74. width: parent.width
  75. height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider
  76. from: 0
  77. to: 100
  78. stepSize: 1
  79. // disable slider when gradual support is enabled
  80. enabled: parseInt(infillSteps.properties.value) == 0
  81. // set initial value from stack
  82. value: parseInt(infillDensity.properties.value)
  83. //Draw line
  84. background: Rectangle
  85. {
  86. id: backgroundLine
  87. height: UM.Theme.getSize("print_setup_slider_groove").height
  88. width: parent.width - UM.Theme.getSize("print_setup_slider_handle").width
  89. implicitWidth: 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. renderType: Text.NativeRendering
  116. color: UM.Theme.getColor("quality_slider_available")
  117. }
  118. }
  119. }
  120. }
  121. handle: Rectangle
  122. {
  123. id: handleButton
  124. x: infillSlider.leftPadding + infillSlider.visualPosition * (infillSlider.availableWidth - width)
  125. y: infillSlider.topPadding + infillSlider.availableHeight / 2 - height / 2
  126. color: infillSlider.enabled ? UM.Theme.getColor("primary") : UM.Theme.getColor("quality_slider_unavailable")
  127. implicitWidth: UM.Theme.getSize("print_setup_slider_handle").width
  128. implicitHeight: implicitWidth
  129. radius: Math.round(implicitWidth / 2)
  130. border.color: UM.Theme.getColor("slider_groove_fill")
  131. border.width: UM.Theme.getSize("default_lining").height
  132. }
  133. Connections
  134. {
  135. target: infillSlider
  136. function onValueChanged()
  137. {
  138. // Don't round the value if it's already the same
  139. if (parseInt(infillDensity.properties.value) == infillSlider.value)
  140. {
  141. return
  142. }
  143. // Round the slider value to the nearest multiple of 10 (simulate step size of 10)
  144. var roundedSliderValue = Math.round(infillSlider.value / 10) * 10
  145. // Update the slider value to represent the rounded value
  146. infillSlider.value = roundedSliderValue
  147. // Update value only if the Recommended mode is Active,
  148. // Otherwise if I change the value in the Custom mode the Recommended view will try to repeat
  149. // same operation
  150. const active_mode = UM.Preferences.getValue("cura/active_mode")
  151. if (visible // Workaround: 'visible' is checked because on startup in Windows it spuriously gets an 'onValueChanged' with value '0' if this isn't checked.
  152. && (active_mode == 0 || active_mode == "simple"))
  153. {
  154. Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
  155. Cura.MachineManager.resetSettingForAllExtruders("infill_line_distance")
  156. }
  157. }
  158. }
  159. }
  160. }
  161. // Gradual Support Infill Checkbox
  162. UM.CheckBox
  163. {
  164. id: enableGradualInfillCheckBox
  165. property alias _hovered: enableGradualInfillMouseArea.containsMouse
  166. anchors.top: infillSliderContainer.bottom
  167. anchors.topMargin: UM.Theme.getSize("wide_margin").height
  168. anchors.left: infillSliderContainer.left
  169. text: catalog.i18nc("@label", "Gradual infill")
  170. enabled: recommendedPrintSetup.settingsEnabled
  171. visible: infillSteps.properties.enabled == "True"
  172. checked: parseInt(infillSteps.properties.value) > 0
  173. MouseArea
  174. {
  175. id: enableGradualInfillMouseArea
  176. anchors.fill: parent
  177. hoverEnabled: true
  178. enabled: true
  179. property var previousInfillDensity: parseInt(infillDensity.properties.value)
  180. onClicked:
  181. {
  182. // Set to 90% only when enabling gradual infill
  183. var newInfillDensity;
  184. if (parseInt(infillSteps.properties.value) == 0)
  185. {
  186. previousInfillDensity = parseInt(infillDensity.properties.value)
  187. newInfillDensity = 90
  188. } else {
  189. newInfillDensity = previousInfillDensity
  190. }
  191. Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity))
  192. var infill_steps_value = 0
  193. if (parseInt(infillSteps.properties.value) == 0)
  194. {
  195. infill_steps_value = 5
  196. }
  197. Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value)
  198. }
  199. onEntered: base.showTooltip(enableGradualInfillCheckBox, Qt.point(-infillSliderContainer.x - UM.Theme.getSize("thick_margin").width, 0),
  200. catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."))
  201. onExited: base.hideTooltip()
  202. }
  203. }
  204. UM.SettingPropertyProvider
  205. {
  206. id: infillDensity
  207. containerStackId: Cura.MachineManager.activeStackId
  208. key: "infill_sparse_density"
  209. watchedProperties: [ "value" ]
  210. storeIndex: 0
  211. }
  212. UM.SettingPropertyProvider
  213. {
  214. id: infillSteps
  215. containerStackId: Cura.MachineManager.activeStackId
  216. key: "gradual_infill_steps"
  217. watchedProperties: ["value", "enabled"]
  218. storeIndex: 0
  219. }
  220. }