SimulationViewMainComponent.qml 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright (c) 2018 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.4
  4. import UM 1.4 as UM
  5. import Cura 1.0 as Cura
  6. Item
  7. {
  8. // An Item whose bounds are guaranteed to be safe for overlays to be placed.
  9. // Defaults to parent, ie. the entire available area
  10. // eg. the layer slider will not be placed in this area.
  11. property var safeArea: parent
  12. property bool isSimulationPlaying: false
  13. readonly property real layerSliderSafeYMin: safeArea.y
  14. readonly property real layerSliderSafeYMax: safeArea.y + safeArea.height
  15. readonly property real pathSliderSafeXMin: safeArea.x + playButton.width
  16. readonly property real pathSliderSafeXMax: safeArea.x + safeArea.width
  17. visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
  18. // A slider which lets users trace a single layer (XY movements)
  19. PathSlider
  20. {
  21. id: pathSlider
  22. readonly property real preferredWidth: UM.Theme.getSize("slider_layerview_size").height // not a typo, should be as long as layerview slider
  23. readonly property real margin: UM.Theme.getSize("default_margin").width
  24. readonly property real pathSliderSafeWidth: pathSliderSafeXMax - pathSliderSafeXMin
  25. height: UM.Theme.getSize("slider_handle").width
  26. width: preferredWidth + margin * 2 < pathSliderSafeWidth ? preferredWidth : pathSliderSafeWidth - margin * 2
  27. anchors.bottom: parent.bottom
  28. anchors.bottomMargin: margin
  29. anchors.horizontalCenter: parent.horizontalCenter
  30. anchors.horizontalCenterOffset: -(parent.width - pathSliderSafeXMax - pathSliderSafeXMin) / 2 // center between parent top and layerSliderSafeYMax
  31. visible: !UM.SimulationView.compatibilityMode
  32. // Custom properties
  33. handleValue: UM.SimulationView.currentPath
  34. maximumValue: UM.SimulationView.numPaths
  35. // Update values when layer data changes.
  36. Connections
  37. {
  38. target: UM.SimulationView
  39. function onMaxPathsChanged() { pathSlider.setHandleValue(UM.SimulationView.currentPath) }
  40. function onCurrentPathChanged()
  41. {
  42. // Only pause the simulation when the layer was changed manually, not when the simulation is running
  43. if (pathSlider.manuallyChanged)
  44. {
  45. playButton.pauseSimulation()
  46. }
  47. pathSlider.setHandleValue(UM.SimulationView.currentPath)
  48. }
  49. }
  50. // Ensure that the slider handlers show the correct value after switching views.
  51. Component.onCompleted:
  52. {
  53. pathSlider.setHandleValue(UM.SimulationView.currentPath)
  54. }
  55. }
  56. UM.SimpleButton
  57. {
  58. id: playButton
  59. iconSource: !isSimulationPlaying ? "./resources/Play.svg": "./resources/Pause.svg"
  60. width: UM.Theme.getSize("small_button").width
  61. height: UM.Theme.getSize("small_button").height
  62. hoverColor: UM.Theme.getColor("slider_handle_active")
  63. color: UM.Theme.getColor("slider_handle")
  64. iconMargin: UM.Theme.getSize("thick_lining").width
  65. visible: !UM.SimulationView.compatibilityMode
  66. Connections
  67. {
  68. target: UM.Preferences
  69. function onPreferenceChanged(preference)
  70. {
  71. if (preference !== "view/only_show_top_layers" && preference !== "view/top_layer_count" && ! preference.match("layerview/"))
  72. {
  73. return;
  74. }
  75. playButton.pauseSimulation()
  76. }
  77. }
  78. anchors
  79. {
  80. right: pathSlider.left
  81. verticalCenter: pathSlider.verticalCenter
  82. }
  83. onClicked:
  84. {
  85. if(isSimulationPlaying)
  86. {
  87. pauseSimulation()
  88. }
  89. else
  90. {
  91. resumeSimulation()
  92. }
  93. }
  94. function pauseSimulation()
  95. {
  96. UM.SimulationView.setSimulationRunning(false)
  97. simulationTimer.stop()
  98. isSimulationPlaying = false
  99. layerSlider.manuallyChanged = true
  100. pathSlider.manuallyChanged = true
  101. }
  102. function resumeSimulation()
  103. {
  104. UM.SimulationView.setSimulationRunning(true)
  105. simulationTimer.start()
  106. layerSlider.manuallyChanged = false
  107. pathSlider.manuallyChanged = false
  108. }
  109. }
  110. Timer
  111. {
  112. id: simulationTimer
  113. interval: 100
  114. running: false
  115. repeat: true
  116. onTriggered:
  117. {
  118. var currentPath = UM.SimulationView.currentPath
  119. var numPaths = UM.SimulationView.numPaths
  120. var currentLayer = UM.SimulationView.currentLayer
  121. var numLayers = UM.SimulationView.numLayers
  122. // When the user plays the simulation, if the path slider is at the end of this layer, we start
  123. // the simulation at the beginning of the current layer.
  124. if (!isSimulationPlaying)
  125. {
  126. if (currentPath >= numPaths)
  127. {
  128. UM.SimulationView.setCurrentPath(0)
  129. }
  130. else
  131. {
  132. UM.SimulationView.setCurrentPath(currentPath + 1)
  133. }
  134. }
  135. // If the simulation is already playing and we reach the end of a layer, then it automatically
  136. // starts at the beginning of the next layer.
  137. else
  138. {
  139. if (currentPath >= numPaths)
  140. {
  141. // At the end of the model, the simulation stops
  142. if (currentLayer >= numLayers)
  143. {
  144. playButton.pauseSimulation()
  145. }
  146. else
  147. {
  148. UM.SimulationView.setCurrentLayer(currentLayer + 1)
  149. UM.SimulationView.setCurrentPath(0)
  150. }
  151. }
  152. else
  153. {
  154. UM.SimulationView.setCurrentPath(currentPath + 1)
  155. }
  156. }
  157. // The status must be set here instead of in the resumeSimulation function otherwise it won't work
  158. // correctly, because part of the logic is in this trigger function.
  159. isSimulationPlaying = true
  160. }
  161. }
  162. // Scrolls through Z layers
  163. LayerSlider
  164. {
  165. property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
  166. property double heightMargin: UM.Theme.getSize("default_margin").height * 3 // extra margin to accommodate layer number tooltips
  167. property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
  168. id: layerSlider
  169. width: UM.Theme.getSize("slider_handle").width
  170. height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
  171. anchors
  172. {
  173. right: parent.right
  174. verticalCenter: parent.verticalCenter
  175. verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
  176. rightMargin: UM.Theme.getSize("default_margin").width
  177. bottomMargin: heightMargin
  178. topMargin: heightMargin
  179. }
  180. // Custom properties
  181. upperValue: UM.SimulationView.currentLayer
  182. lowerValue: UM.SimulationView.minimumLayer
  183. maximumValue: UM.SimulationView.numLayers
  184. // Update values when layer data changes
  185. Connections
  186. {
  187. target: UM.SimulationView
  188. function onMaxLayersChanged() { layerSlider.setUpperValue(UM.SimulationView.currentLayer) }
  189. function onMinimumLayerChanged() { layerSlider.setLowerValue(UM.SimulationView.minimumLayer) }
  190. function onCurrentLayerChanged()
  191. {
  192. // Only pause the simulation when the layer was changed manually, not when the simulation is running
  193. if (layerSlider.manuallyChanged)
  194. {
  195. playButton.pauseSimulation()
  196. }
  197. layerSlider.setUpperValue(UM.SimulationView.currentLayer)
  198. }
  199. }
  200. // Make sure the slider handlers show the correct value after switching views
  201. Component.onCompleted:
  202. {
  203. layerSlider.setLowerValue(UM.SimulationView.minimumLayer)
  204. layerSlider.setUpperValue(UM.SimulationView.currentLayer)
  205. }
  206. }
  207. }