PathSlider.qml 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // Copyright (c) 2021 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Layouts 1.1
  5. import UM 1.0 as UM
  6. import Cura 1.0 as Cura
  7. Item
  8. {
  9. id: sliderRoot
  10. // handle properties
  11. property real handleSize: UM.Theme.getSize("slider_handle").width
  12. property real handleRadius: handleSize / 2
  13. property color handleColor: UM.Theme.getColor("slider_handle")
  14. property color handleActiveColor: UM.Theme.getColor("slider_handle_active")
  15. property color rangeColor: UM.Theme.getColor("slider_groove_fill")
  16. property real handleLabelWidth: width
  17. // track properties
  18. property real trackThickness: UM.Theme.getSize("slider_groove").width
  19. property real trackRadius: UM.Theme.getSize("slider_groove_radius").width
  20. property color trackColor: UM.Theme.getColor("slider_groove")
  21. // value properties
  22. property real maximumValue: 100
  23. property real minimumValue: 0
  24. property bool roundValues: true
  25. property real handleValue: maximumValue
  26. property bool pathsVisible: true
  27. property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation
  28. function getHandleValueFromSliderHandle()
  29. {
  30. return handle.getValue()
  31. }
  32. function setHandleValue(value)
  33. {
  34. handle.setValue(value)
  35. updateRangeHandle()
  36. }
  37. function updateRangeHandle()
  38. {
  39. rangeHandle.width = handle.x - sliderRoot.handleSize
  40. }
  41. function normalizeValue(value)
  42. {
  43. return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
  44. }
  45. onWidthChanged : {
  46. // After a width change, the pixel-position of the handle is out of sync with the property value
  47. setHandleValue(handleValue)
  48. }
  49. // slider track
  50. Rectangle
  51. {
  52. id: track
  53. width: sliderRoot.width - sliderRoot.handleSize
  54. height: sliderRoot.trackThickness
  55. radius: sliderRoot.trackRadius
  56. anchors.centerIn: sliderRoot
  57. color: sliderRoot.trackColor
  58. visible: sliderRoot.pathsVisible
  59. }
  60. // Progress indicator
  61. Item
  62. {
  63. id: rangeHandle
  64. x: handle.width
  65. height: sliderRoot.handleSize
  66. width: handle.x - sliderRoot.handleSize
  67. anchors.verticalCenter: sliderRoot.verticalCenter
  68. visible: sliderRoot.pathsVisible
  69. Rectangle
  70. {
  71. height: sliderRoot.trackThickness
  72. width: parent.width + sliderRoot.handleSize
  73. anchors.centerIn: parent
  74. radius: sliderRoot.trackRadius
  75. color: sliderRoot.rangeColor
  76. }
  77. }
  78. // Handle
  79. Rectangle
  80. {
  81. id: handle
  82. x: sliderRoot.handleSize
  83. width: sliderRoot.handleSize
  84. height: sliderRoot.handleSize
  85. anchors.verticalCenter: sliderRoot.verticalCenter
  86. radius: sliderRoot.handleRadius
  87. color: handleLabel.activeFocus ? sliderRoot.handleActiveColor : sliderRoot.handleColor
  88. visible: sliderRoot.pathsVisible
  89. function onHandleDragged()
  90. {
  91. sliderRoot.manuallyChanged = true
  92. // update the range handle
  93. sliderRoot.updateRangeHandle()
  94. // set the new value after moving the handle position
  95. UM.SimulationView.setCurrentPath(getValue())
  96. }
  97. // get the value based on the slider position
  98. function getValue()
  99. {
  100. var result = x / (sliderRoot.width - sliderRoot.handleSize)
  101. result = result * sliderRoot.maximumValue
  102. result = sliderRoot.roundValues ? Math.round(result) : result
  103. return result
  104. }
  105. function setValueManually(value)
  106. {
  107. sliderRoot.manuallyChanged = true
  108. handle.setValue(value)
  109. }
  110. // set the slider position based on the value
  111. function setValue(value)
  112. {
  113. // Normalize values between range, since using arrow keys will create out-of-the-range values
  114. value = sliderRoot.normalizeValue(value)
  115. UM.SimulationView.setCurrentPath(value)
  116. var diff = value / sliderRoot.maximumValue
  117. var newXPosition = Math.round(diff * (sliderRoot.width - sliderRoot.handleSize))
  118. x = newXPosition
  119. // update the range handle
  120. sliderRoot.updateRangeHandle()
  121. }
  122. Keys.onRightPressed: handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
  123. Keys.onLeftPressed: handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
  124. // dragging
  125. MouseArea
  126. {
  127. anchors.fill: parent
  128. drag
  129. {
  130. target: parent
  131. axis: Drag.XAxis
  132. minimumX: 0
  133. maximumX: sliderRoot.width - sliderRoot.handleSize
  134. }
  135. onPressed: handleLabel.forceActiveFocus()
  136. onPositionChanged: parent.onHandleDragged()
  137. }
  138. SimulationSliderLabel
  139. {
  140. id: handleLabel
  141. height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
  142. y: parent.y + sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
  143. anchors.horizontalCenter: parent.horizontalCenter
  144. target: Qt.point(x + width / 2, sliderRoot.height)
  145. visible: false
  146. startFrom: 0
  147. // custom properties
  148. maximumValue: sliderRoot.maximumValue
  149. value: sliderRoot.handleValue
  150. busy: UM.SimulationView.busy
  151. setValue: handle.setValueManually // connect callback functions
  152. }
  153. }
  154. }