PathSlider.qml 5.7 KB

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