mdawid / range-seek-bar

Automatically exported from code.google.com/p/range-seek-bar
0 stars 0 forks source link

Allow minimum distance between min and max values. #21

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This would be a very useful enhancement..

So if we had a range of say 1 to 20 and the "minimum distance" would be 2, then 
the user would not be able to have a range of 7-8, or 8-8. Only 6-8.

Original issue reported on code.google.com by eurigjo...@gmail.com on 21 Mar 2013 at 8:06

GoogleCodeExporter commented 9 years ago
hi eurigjones, wouldn't that be a duplicate of issue #1?

Original comment by tittel@kom.e-technik.tu-darmstadt.de on 21 Mar 2013 at 8:17

GoogleCodeExporter commented 9 years ago
No. The code in issue 1 is very useful, but different to what I mean here.

This issue is to specify a minimum distance between left and right sliders. 
Issue one specifies the step size when moving the sliders.

Original comment by eurigjo...@gmail.com on 21 Mar 2013 at 8:29

GoogleCodeExporter commented 9 years ago
Anyway, I have modified the code in issue one to provide this functionality. 
Let me know if you want me to post it somewhere.

Original comment by eurigjo...@gmail.com on 21 Mar 2013 at 8:30

GoogleCodeExporter commented 9 years ago
sorry for misunderstanding. It'd be nice if you posted your changes as an 
attachment here. I can't promise to merge it any time soon but it's on my 
list... 

Original comment by tittel@kom.e-technik.tu-darmstadt.de on 21 Mar 2013 at 8:38

GoogleCodeExporter commented 9 years ago
Here is my code to support stepSize (thanks coder from issue 1) as well as a 
differenceLimit...

public class DiscreteRangeSeekBar<T extends Number> extends RangeSeekBar<T> {

    private double normalizedStepSize;
    private double normalizedDiffLimit;

    @SuppressWarnings("unchecked")
    public DiscreteRangeSeekBar(T absoluteMinValue, T absoluteMaxValue, T stepSize, T diffLimit, Context context)
            throws IllegalArgumentException {
        super(absoluteMinValue, absoluteMaxValue, context);

        this.normalizedStepSize = valueToNormalized((T) numberType.toNumber(absoluteMinValue.doubleValue()
                + stepSize.doubleValue()));
        normalizedDiffLimit = valueToNormalized((T) numberType.toNumber(absoluteMinValue.doubleValue()
                + stepSize.doubleValue()));
    }

    @Override
    protected void trackTouchEvent(MotionEvent event) {
        final int pointerIndex = event.findPointerIndex(mActivePointerId);
        final float x = event.getX(pointerIndex);

        if (Thumb.MIN.equals(pressedThumb)) {
            setNormalizedMinValue(findClosestNormalizedStep(screenToNormalized(x)));
        } else if (Thumb.MAX.equals(pressedThumb)) {
            setNormalizedMaxValue(findClosestNormalizedStep(screenToNormalized(x)));
        }
    }

    /**
     * Return normalized location of the nearest step or max (if closer)
     */
    private double findClosestNormalizedStep(double value) {
        int numbStepsBelow = (int) Math.floor(value / normalizedStepSize);

        double stepBelow = normalizedStepSize * numbStepsBelow;
        double stepAbove = Math.min(normalizedStepSize * (numbStepsBelow + 1), 1.0d);

        double distanceBelow = value - stepBelow;
        double distanceAbove = stepAbove - value;

        if (distanceBelow < distanceAbove)
            return stepBelow;
        return stepAbove;
    }

    @Override
    public void setNormalizedMinValue(double value)
    {
        Double newVal = Math.max(0d, Math.min(1d, Math.min(value, normalizedMaxValue)));
        if (normalizedMaxValue - newVal > normalizedDiffLimit)
        {
            normalizedMinValue = newVal;
            invalidate();
        }
    }

    @Override
    public void setNormalizedMaxValue(double value)
    {
        Double newVal = Math.max(0d, Math.min(1d, Math.max(value, normalizedMinValue)));
        if (newVal - normalizedMinValue > normalizedDiffLimit)
        {
            normalizedMaxValue = newVal;
            invalidate();
        }
    }
}

Original comment by eurigjo...@gmail.com on 21 Mar 2013 at 8:45

GoogleCodeExporter commented 9 years ago
I am having problems using this code.  When I create a new DiscreteRangeSeekBar 
with the parameters (1.0, 10.0, 1.0, 1.0, getActivity()), when I move the 
seekbar to where 7 should be, I get 6.  This also happens if I change the 
values of the parameters to values like  (0.0, 9.0, 1.0, 1.0, getActivity()) or 
(0.0, 20.0, 10.0, 1.0, getActivity()).  I have the same problem when I use 
integers instead of doubles.  

Original comment by Noel...@gmail.com on 13 Aug 2013 at 7:21

GoogleCodeExporter commented 9 years ago
I had two problems with eurigjone's code.  I was having problems with the 
difference limit and the conditional which compared it.  
The current code does not use diffLimit given in the constructor.  The code 
should be:
normalizedDiffLimit = valueToNormalized((T) 
numberType.toNumber(absoluteMinValue.doubleValue()
                + diffLimit.doubleValue()));
Not:
normalizedDiffLimit = valueToNormalized((T) 
numberType.toNumber(absoluteMinValue.doubleValue()
                + stepSize.doubleValue()));
The stepSize needed to be changed to diffLimit.  
My second problem was solved by changed the condition in setNormalizedMaxValue 
to:
if (newVal - normalizedMinValue >= normalizedDiffLimit)
Not:
if (newVal - normalizedMinValue > normalizedDiffLimit)

This fixed the problem with difflimit not actually working and also the two 
ranges not being able to get together closer when min is set at 0 and 
attempting to move max  
withing 1 of the min when I used:
DiscreteRangeSeekBar<Double>(0.0, 9.0, 1.0, 1.0, getActivity());

Original comment by Noel...@gmail.com on 14 Aug 2013 at 2:26