// Copyright (c) 2021 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Layouts 1.1 import UM 1.0 as UM import Cura 1.0 as Cura Item { id: sliderRoot // handle properties property real handleSize: UM.Theme.getSize("slider_handle").width property real handleRadius: handleSize / 2 property color handleColor: UM.Theme.getColor("slider_handle") property color handleActiveColor: UM.Theme.getColor("slider_handle_active") property color rangeColor: UM.Theme.getColor("slider_groove_fill") property real handleLabelWidth: width // track properties property real trackThickness: UM.Theme.getSize("slider_groove").width property real trackRadius: UM.Theme.getSize("slider_groove_radius").width property color trackColor: UM.Theme.getColor("slider_groove") // value properties property real maximumValue: 100 property real minimumValue: 0 property bool roundValues: true property real handleValue: maximumValue property bool pathsVisible: true property bool manuallyChanged: true // Indicates whether the value was changed manually or during simulation function getHandleValueFromSliderHandle() { return handle.getValue() } function setHandleValue(value) { handle.setValue(value) updateRangeHandle() } function updateRangeHandle() { rangeHandle.width = handle.x - sliderRoot.handleSize } function normalizeValue(value) { return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue) } onWidthChanged : { // After a width change, the pixel-position of the handle is out of sync with the property value setHandleValue(handleValue) } // slider track Rectangle { id: track width: sliderRoot.width - sliderRoot.handleSize height: sliderRoot.trackThickness radius: sliderRoot.trackRadius anchors.centerIn: sliderRoot color: sliderRoot.trackColor visible: sliderRoot.pathsVisible } // Progress indicator Item { id: rangeHandle x: handle.width height: sliderRoot.handleSize width: handle.x - sliderRoot.handleSize anchors.verticalCenter: sliderRoot.verticalCenter visible: sliderRoot.pathsVisible Rectangle { height: sliderRoot.trackThickness width: parent.width + sliderRoot.handleSize anchors.centerIn: parent radius: sliderRoot.trackRadius color: sliderRoot.rangeColor } } // Handle Rectangle { id: handle x: sliderRoot.handleSize width: sliderRoot.handleSize height: sliderRoot.handleSize anchors.verticalCenter: sliderRoot.verticalCenter radius: sliderRoot.handleRadius color: handleLabel.activeFocus ? sliderRoot.handleActiveColor : sliderRoot.handleColor visible: sliderRoot.pathsVisible function onHandleDragged() { sliderRoot.manuallyChanged = true // update the range handle sliderRoot.updateRangeHandle() // set the new value after moving the handle position UM.SimulationView.setCurrentPath(getValue()) } // get the value based on the slider position function getValue() { var result = x / (sliderRoot.width - sliderRoot.handleSize) result = result * sliderRoot.maximumValue result = sliderRoot.roundValues ? Math.round(result) : result return result } function setValueManually(value) { sliderRoot.manuallyChanged = true handle.setValue(value) } // set the slider position based on the value function setValue(value) { // Normalize values between range, since using arrow keys will create out-of-the-range values value = sliderRoot.normalizeValue(value) UM.SimulationView.setCurrentPath(value) var diff = value / sliderRoot.maximumValue var newXPosition = Math.round(diff * (sliderRoot.width - sliderRoot.handleSize)) x = newXPosition // update the range handle sliderRoot.updateRangeHandle() } Keys.onRightPressed: handleLabel.setValue(handleLabel.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) Keys.onLeftPressed: handleLabel.setValue(handleLabel.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) // dragging MouseArea { anchors.fill: parent drag { target: parent axis: Drag.XAxis minimumX: 0 maximumX: sliderRoot.width - sliderRoot.handleSize } onPressed: handleLabel.forceActiveFocus() onPositionChanged: parent.onHandleDragged() } SimulationSliderLabel { id: handleLabel height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height y: parent.y + sliderRoot.handleSize + UM.Theme.getSize("default_margin").height anchors.horizontalCenter: parent.horizontalCenter target: Qt.point(x + width / 2, sliderRoot.height) visible: false startFrom: 0 // custom properties maximumValue: sliderRoot.maximumValue value: sliderRoot.handleValue busy: UM.SimulationView.busy setValue: handle.setValueManually // connect callback functions } } }