Index: sources/gui/qml/components/Slider.qml =================================================================== diff -u -r642f08650a7a88ad6a2305fdea6bd18365aab5c7 -rc80e4dade15bd769ea20f8098b37655fb22407b7 --- sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision 642f08650a7a88ad6a2305fdea6bd18365aab5c7) +++ sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision c80e4dade15bd769ea20f8098b37655fb22407b7) @@ -24,7 +24,7 @@ * \brief Denali project ProgressBar */ RangeRect { id: _root - property real value : _progressRect.value + property real value : minimum property real step : 1 property bool stepSnap : false @@ -40,23 +40,55 @@ property alias handlerColor : _handler.color property alias handlerVisible : _handler.visible + readonly property alias handleAdjusted : _private.sliderAdjusted + property alias diameter : _handler.diameter property bool isActive : true property bool inActiveZero : false // if inActiveZero:true, when is not active (inActive or active:false) sets to zero instead of minimum + property bool showActiveDisabled : false // if showActiveDisabled: true the slider is highlighted active even if the slider is isActive:false property alias progressRectMargin : _progressRect.margin - property int tickMarksThickness : 2 + property int tickMarksThickness : 2 + property bool isTickMarksCentered : false ///< Indicate whether the tickmarks are centered in the slider body + property int tickMarkYDisplacement : (-_handler.height/2 - _handler.border.width*2) ///< The amount of y displacement if the TickMarks are not centered property bool isRoundedEnds : true property bool hasBorder : true - property color borderColor : Colors.borderDisableButton + QtObject { id:_private + // To avoid displaying and updating _root.value with intermediate values, + // the _root.value aliasing to _progressRect.value is removed. Causing any setting of + // _root.value outside of slider actions (handle dragging, slider-line clicking, etc) + // to not update the _progressRect.value. This will cause the visuals to not line up + // to _root.value's current number. Adding a boolean to indicate when the _root.value + // changes is internal to avoid updating the _progressRect.value. + // This value is set primarily in the update() function and checked for in + // onValueChanged handler + property bool isInternalValueUpdate : false + + // Indicate the active state of the slider visually (borders) + property bool isVisualActive : false + + // Indicate whether the slider have been modified/adjusted + // When property changes, update the visuals of the slider to reflect + property bool sliderAdjusted : false + onSliderAdjustedChanged: setActiveVisuals(sliderAdjusted) + } + + onValueChanged: { + // See note about _private.isInternalValueUpdated + if (! _private.isInternalValueUpdate) { + _progressRect.value = value // update the slider visual + } + } + signal activeChanged() signal handleSelected() signal sliderSelected() + function incrementValue (vInStepSegments) { updateValue(vInStepSegments, true) } @@ -90,31 +122,30 @@ update(newValue) } - function setActiveVisuals(active) { - if (active) { - color = Colors.sliderHighlightColor + function setActiveVisuals(vActive) { + // NOTE: the slider borders are set separately from here and + // based on _private.isVisualActive + + if (vActive) { + color = Colors.sliderHighlightColor // _progressRect body color handlerColor = Colors.createTreatmentActive } else { - color = Colors.createTreatmentInactive + color = Colors.createTreatmentInactive // _progressRect body color handlerColor = Colors.createTreatmentInactive } + + _private.isVisualActive = vActive } - onEnabledChanged: _progressRect.value = minimum // reset the visual progress bar - onIsActiveChanged: { - setActiveVisuals(isActive) - - // value is assigned a different value based on active-ness of the slider - // This is to resolve the use of slider with a switch and arrows enabled. - // It allows correct behavior when using arrow on a first initialize increment of - // the slider when the slider has inActiveZero to true. if(!isActive) { _root.value = inActiveZero ? 0 : minimum + setActiveVisuals(showActiveDisabled) } else { - _root.value = _progressRect.value = minimum + _progressRect.value = minimum + _private.sliderAdjusted = false + setActiveVisuals(false) } - activeChanged() // emit } @@ -125,7 +156,7 @@ radius : _root.isRoundedEnds ? (height/2) : Variables.rangeRectRadius border.width: _root.hasBorder ? Variables.rangeRectBorderWidth : 0 - border.color: _root.isActive ? Colors.borderButton : Colors.borderDisableButton + border.color: _private.isVisualActive ? Colors.borderButton : Colors.borderDisableButton minimum : 0 maximum : 0 @@ -162,7 +193,17 @@ } function update(vValue) { + // See note at _private.isInternalValueUpdate + _private.isInternalValueUpdate = true + + // Update the _root.value / the exposed value of slider _root.value = vValue + + // indicate that the slider have modified value state + _private.sliderAdjusted = true + + // reset state to allow _root.value value updating externally + _private.isInternalValueUpdate = false } function calculateValue(x, isSnappingToTicks) { @@ -213,29 +254,9 @@ return mValue; } - // used loader for performance since it may not always be required. - // and can be a heavy Component - Loader { id: _ticksLoader - active : ticks - anchors.fill : parent - sourceComponent : TickMarks { - decimal : _root.decimal - minimum : _root.minimum - maximum : _root.maximum - step : _root.step - stepSnap : _root.stepSnap - textColor : _root.color - lineTickMarkHeight : _progressRect.height - lineTickMarkThickness : _root.tickMarksThickness - isTickMarkRound : _root.isRoundedEnds - yDisplacement : _root.isRoundedEnds ? (-_handler.height/2 - _handler.border.width/2) : 0 - color : _root.isActive ? Colors.borderButton : Colors.borderDisableButton - } - } - ProgressRect { id: _progressRect property real previousSliderValue: Number.NaN - value : minimum + value : _root.value color : Colors.sliderHighlightColor decimal : _root.decimal @@ -246,7 +267,7 @@ radius : _root.isRoundedEnds ? (height/2) : Variables.rangeRectRadius border.width: _root.hasBorder ? Variables.rangeRectBorderWidth : 0 - border.color: _root.isActive ? Colors.sliderProgressBorderActive : Colors.borderDisableButton + border.color: _private.isVisualActive ? Colors.sliderProgressBorderActive : Colors.borderDisableButton // propagation is not working on drag ! onDragged: { @@ -260,6 +281,35 @@ } } + // used loader for performance since it may not always be required. + // and can be a heavy Component + Loader { id: _ticksLoader + active : ticks + width : _root.width + height : (_progressRect.height - Variables.sliderDefaultRoundTickMarkDiameter) + anchors.bottom : _root.bottom + sourceComponent : TickMarks { + decimal : _root.decimal + minimum : _root.minimum + maximum : _root.maximum + step : _root.step + stepSnap : _root.stepSnap + textColor : _root.color + lineTickMarkHeight : _progressRect.height + lineTickMarkThickness : _root.tickMarksThickness + isTickMarkRound : _root.isRoundedEnds + showEndMarks : !_root.isTickMarksCentered + yDisplacement : { + if ( _root.isTickMarksCentered ) { + return (_root.border.width/2 - 1) // had to subtract 1 to center on the _progressRect + } else { + return _root.tickMarkYDisplacement + } + } + color : _private.isVisualActive ? Colors.borderButton : Colors.borderDisableButton + } + } + function updateHandleValue(vCurrentPositionX) { // Passing false for snapping to get exact value in respect to x @@ -281,7 +331,6 @@ // update slider value with rounded new value update(calculateRoundedValue(newCurrentValue)) - } }