SimulationViewMainComponent.qml 8.6 KB

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