SimulationViewMainComponent.qml 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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: Qt.resolvedUrl(!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. UM.SimulationView.setCurrentPath(UM.SimulationView.currentPath)
  106. simulationTimer.start()
  107. layerSlider.manuallyChanged = false
  108. pathSlider.manuallyChanged = false
  109. }
  110. }
  111. Timer
  112. {
  113. id: simulationTimer
  114. interval: 1000 / 15
  115. running: false
  116. repeat: true
  117. onTriggered:
  118. {
  119. // divide by 1000 to account for ms to s conversion
  120. const advance_time = simulationTimer.interval / 1000.0;
  121. UM.SimulationView.advanceTime(advance_time);
  122. // The status must be set here instead of in the resumeSimulation function otherwise it won't work
  123. // correctly, because part of the logic is in this trigger function.
  124. isSimulationPlaying = true;
  125. }
  126. }
  127. // Scrolls through Z layers
  128. LayerSlider
  129. {
  130. property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
  131. property double heightMargin: UM.Theme.getSize("default_margin").height * 3 // extra margin to accommodate layer number tooltips
  132. property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
  133. id: layerSlider
  134. width: UM.Theme.getSize("slider_handle").width
  135. height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
  136. anchors
  137. {
  138. right: parent.right
  139. verticalCenter: parent.verticalCenter
  140. verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
  141. rightMargin: UM.Theme.getSize("default_margin").width
  142. bottomMargin: heightMargin
  143. topMargin: heightMargin
  144. }
  145. // Custom properties
  146. upperValue: UM.SimulationView.currentLayer
  147. lowerValue: UM.SimulationView.minimumLayer
  148. maximumValue: UM.SimulationView.numLayers
  149. // Update values when layer data changes
  150. Connections
  151. {
  152. target: UM.SimulationView
  153. function onMaxLayersChanged() { layerSlider.setUpperValue(UM.SimulationView.currentLayer) }
  154. function onMinimumLayerChanged() { layerSlider.setLowerValue(UM.SimulationView.minimumLayer) }
  155. function onCurrentLayerChanged()
  156. {
  157. // Only pause the simulation when the layer was changed manually, not when the simulation is running
  158. if (layerSlider.manuallyChanged)
  159. {
  160. playButton.pauseSimulation()
  161. }
  162. layerSlider.setUpperValue(UM.SimulationView.currentLayer)
  163. }
  164. }
  165. // Make sure the slider handlers show the correct value after switching views
  166. Component.onCompleted:
  167. {
  168. layerSlider.setLowerValue(UM.SimulationView.minimumLayer)
  169. layerSlider.setUpperValue(UM.SimulationView.currentLayer)
  170. }
  171. }
  172. }