Index: sources/gui/qml/compounds/ValueAdjuster.qml =================================================================== diff -u -r5f4b3aacfede4aa545a44c7f3b33ca649b81aac7 -rb16fd955f65d83321decdc54bd3d5695fc81c32c --- sources/gui/qml/compounds/ValueAdjuster.qml (.../ValueAdjuster.qml) (revision 5f4b3aacfede4aa545a44c7f3b33ca649b81aac7) +++ sources/gui/qml/compounds/ValueAdjuster.qml (.../ValueAdjuster.qml) (revision b16fd955f65d83321decdc54bd3d5695fc81c32c) @@ -30,50 +30,94 @@ property bool editable : true property bool canOff : false property bool canRefresh : false + property alias textColor : _text.color - // fix floating-point precision issue - readonly property real stepVal : Math.round(step * 100) / 100 - readonly property real minVal : Math.round(minimum * 100) / 100 - readonly property real val : Math.round(value * 100) / 100 + QtObject { id: _private + // fix floating-point precision issue + readonly property int multiplier : Math.pow(10, decimal) + readonly property real stepVal : calculatePrecisionValue(step) + readonly property real minVal : calculatePrecisionValue(minimum) + readonly property real maxVal : calculatePrecisionValue(maximum) + readonly property real val : calculatePrecisionValue(value) - readonly property bool canIncrement : isActive ? value < maximum : true - readonly property bool canDecrement : isActive ? canOff ? value > 0 : - value > minimum : true + readonly property bool canIncrement : isActive ? val < calculateMaximum() : true + readonly property bool canDecrement : isActive ? canOff ? val > 0 : + val > calculateMinimum() : true + + // round the value based on the given precision (not step) + function calculatePrecisionValue(value) { + return Math.round(value * _private.multiplier) / _private.multiplier + } - signal didChange (real vValue) - signal didActiveChange (bool vState) + // calculate the minimum value rounded up to the next higher step size + function calculateMinimum() { + let fixedMin = _private.fixedValue(_private.minVal) + let fixedStep = _private.fixedValue(_private.stepVal) + return (Math.ceil(fixedMin / fixedStep) * fixedStep) / _private.multiplier + } - onIsActiveChanged : { - if ( canRefresh ) { canRefresh = false; return; } + // calculate the maximum value rounded down to the next higher step size + function calculateMaximum() { + let fixedMax = _private.fixedValue(_private.maxVal) + let fixedStep = _private.fixedValue(_private.stepVal) + return (Math.floor(fixedMax / fixedStep) * fixedStep) / _private.multiplier + } - if ( isActive ) { didChange(_root.defaultValue) } - } + // return a fixed point int from the inputted float (using the set precision) + function fixedValue(value) { + return Math.round(value * _private.multiplier) + } - function refresh() { canRefresh = true } + function increment() { + if ( ! isActive ) { didActiveChange(true); return } - function clear() { didActiveChange(false) } + let tValue = _private.val + if (canOff && _private.val < _private.minVal) { + tValue = _private.minVal + } + else { + let fixedVal = _private.fixedValue(_private.val) + let fixedStep = _private.fixedValue(_private.stepVal) + let fixedDelta = fixedStep - (fixedVal % fixedStep) + tValue = (fixedVal + fixedDelta) / _private.multiplier + tValue = Math.min(_private.maxVal, tValue) + } - function increment() { - let tValue = value - if ( ! isActive ) { didActiveChange(true); return; } + didChange(tValue) + } - if ( canOff ) { tValue = val < minVal ? minVal : val + stepVal } - else { tValue += stepVal } + function decrement() { + if ( ! isActive ) { didActiveChange(true); return } - didChange(tValue) + let tValue = _private.val + if (canOff && _private.val === _private.minVal) { + tValue = 0 + } + else { + let fixedVal = _private.fixedValue(_private.val) + let fixedStep = _private.fixedValue(_private.stepVal) + let fixedDelta = fixedVal % fixedStep + tValue = (fixedVal - (fixedDelta > 0 ? fixedDelta : fixedStep)) / _private.multiplier + tValue = Math.max(_private.minVal, tValue) + } + didChange(tValue) + } } - function decrement(vValue) { - let tValue = value - if ( ! isActive ) { didActiveChange(true); return; } + signal didChange (real vValue) + signal didActiveChange (bool vState) - if ( canOff ) { tValue = val > minVal ? val - stepVal : 0 } - else { tValue -= stepVal } + onIsActiveChanged : { + if ( canRefresh ) { canRefresh = false; return } - didChange(tValue) + if ( isActive ) { didChange(_root.defaultValue) } } + function refresh() { canRefresh = true } + + function clear() { didActiveChange(false) } + Text { id: _text anchors.centerIn: parent text : _root.isActive ? _root.canOff ? _root.value === 0 ? @@ -137,8 +181,7 @@ } onReleased: { - _sliderMouseArea.grabbed = true -. grabbed = false + _sliderMouseArea.grabbed = false _slider.opacity = 0 } @@ -185,11 +228,11 @@ leftMargin : Variables.defaultMargin } iconSize : Variables.circleButtonDefaultDiameter - enabled : _root.canDecrement + enabled : _private.canDecrement visible : _root.editable iconImageSource : enabled ? "qrc:/images/iArrowLeft" : "qrc:/images/iArrowLeftDisabled" - onClicked : decrement() + onClicked : _private.decrement() } IconButton { id: _rightArrow @@ -199,10 +242,10 @@ rightMargin : Variables.defaultMargin } iconSize : Variables.circleButtonDefaultDiameter - enabled : _root.canIncrement + enabled : _private.canIncrement visible : _root.editable iconImageSource : enabled ? "qrc:/images/iArrowRight" : "qrc:/images/iArrowRightDisabled" - onClicked : increment() + onClicked : _private.increment() } }