From a2cf617d0c1b9e3b5c73111a190ebf396af750e6 Mon Sep 17 00:00:00 2001 From: serso Date: Mon, 19 Sep 2011 17:18:09 +0400 Subject: [PATCH] range preference --- .../view/prefs/RangeSeekPreference.java | 10 +- ...SeekBar.java => AbstractRangeSeekBar.java} | 97 +++++---------- .../view/widgets/NumberRangeSeekBar.java | 111 ++++++++++++++++++ 3 files changed, 145 insertions(+), 73 deletions(-) rename src/main/java/org/solovyev/android/view/widgets/{RangeSeekBar.java => AbstractRangeSeekBar.java} (85%) create mode 100644 src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java diff --git a/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java b/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java index cf3c7dab..8486b3ab 100644 --- a/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java +++ b/src/main/java/org/solovyev/android/view/prefs/RangeSeekPreference.java @@ -4,22 +4,22 @@ import android.content.Context; import android.util.AttributeSet; import android.widget.LinearLayout; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.view.widgets.NumberPicker; -import org.solovyev.android.view.widgets.RangeSeekBar; +import org.solovyev.android.view.widgets.AbstractRangeSeekBar; +import org.solovyev.android.view.widgets.NumberRangeSeekBar; /** * User: serso * Date: 9/19/11 * Time: 12:27 PM */ -public abstract class RangeSeekPreference extends AbstractDialogPreference implements RangeSeekBar.OnRangeSeekBarChangeListener { +public abstract class RangeSeekPreference extends AbstractDialogPreference implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener { @NotNull - private final RangeSeekBar rangeSeekBar; + private final AbstractRangeSeekBar rangeSeekBar; public RangeSeekPreference(@NotNull Context context, AttributeSet attrs) { super(context, attrs); - this.rangeSeekBar = new RangeSeekBar(getMinValue(), getMaxValue(), context); + this.rangeSeekBar = new NumberRangeSeekBar(getMinValue(), getMaxValue(), context); rangeSeekBar.setOnRangeSeekBarChangeListener(this); } diff --git a/src/main/java/org/solovyev/android/view/widgets/RangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java similarity index 85% rename from src/main/java/org/solovyev/android/view/widgets/RangeSeekBar.java rename to src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java index 0941849e..652d4555 100644 --- a/src/main/java/org/solovyev/android/view/widgets/RangeSeekBar.java +++ b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java @@ -12,9 +12,11 @@ import android.graphics.Paint.Style; import android.view.MotionEvent; import android.widget.ImageView; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; - -import java.math.BigDecimal; +import org.solovyev.common.utils.Converter; +import org.solovyev.common.utils.Interval; +import org.solovyev.common.utils.IntervalImpl; /** * Widget that lets users select a minimum and maximum value on a given numerical range. @@ -23,7 +25,7 @@ import java.math.BigDecimal; * @param The Number type of the range values. One of Long, Double, Integer, Float, Short, Byte or BigDecimal. * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) */ -public class RangeSeekBar extends ImageView { +public abstract class AbstractRangeSeekBar extends ImageView { @NotNull private final Paint paint = new Paint(); @@ -45,17 +47,26 @@ public class RangeSeekBar extends ImageView { private final float padding = thumbHalfWidth; @NotNull - private final T minValue, maxValue; + private final Converter toDoubleConverter; @NotNull - private final NumberType numberType; + private final Converter toTConverter; + + @NotNull + private final T minValue, maxValue; private final double dMinValue, dMaxValue; private double normalizedMinValue = 0d; + private double normalizedMaxValue = 1d; + private Thumb pressedThumb = null; + private boolean notifyWhileDragging = false; + + + @Nullable private OnRangeSeekBarChangeListener listener; /** @@ -66,18 +77,25 @@ public class RangeSeekBar extends ImageView { * @param context * @throws IllegalArgumentException Will be thrown if min/max value types are not one of Long, Double, Integer, Float, Short, Byte or BigDecimal. */ - public RangeSeekBar(@NotNull T minValue, @NotNull T maxValue, Context context) throws IllegalArgumentException { + public AbstractRangeSeekBar(@NotNull T minValue, @NotNull T maxValue, Context context) throws IllegalArgumentException { super(context); this.minValue = minValue; this.maxValue = maxValue; - dMinValue = minValue.doubleValue(); - dMaxValue = maxValue.doubleValue(); + this.toDoubleConverter = getToDoubleConverter(); + this.toTConverter = getToTConverter(); - numberType = NumberType.fromNumber(minValue); + dMinValue = toDoubleConverter.convert(minValue); + dMaxValue = toDoubleConverter.convert(maxValue); } + @NotNull + protected abstract Converter getToTConverter(); + + @NotNull + protected abstract Converter getToDoubleConverter(); + public boolean isNotifyWhileDragging() { return notifyWhileDragging; } @@ -314,7 +332,7 @@ public class RangeSeekBar extends ImageView { */ @SuppressWarnings("unchecked") private T normalizedToValue(double normalized) { - return (T) numberType.toNumber(dMinValue + normalized * (dMaxValue - dMinValue)); + return toTConverter.convert(dMinValue + normalized * (dMaxValue - dMinValue)); } /** @@ -325,7 +343,7 @@ public class RangeSeekBar extends ImageView { */ private double normalizeValue(T value) { assert 0 != dMaxValue - dMinValue; - return (value.doubleValue() - dMinValue) / (dMaxValue - dMinValue); + return (toDoubleConverter.convert(value) - dMinValue) / (dMaxValue - dMinValue); } /** @@ -373,61 +391,4 @@ public class RangeSeekBar extends ImageView { private static enum Thumb { MIN, MAX } - - /** - * Utility enumaration used to convert between Numbers and doubles. - * - * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) - */ - private static enum NumberType { - - LONG(Long.class), - DOUBLE(Double.class), - INTEGER(Integer.class), - FLOAT(Float.class), - SHORT(Short.class), - BYTE(Byte.class), - BIG_DECIMAL(BigDecimal.class); - - @NotNull - private final Class underlyingClass; - - private NumberType(@NotNull Class underlyingClass) { - this.underlyingClass = underlyingClass; - } - - @NotNull - public static NumberType fromNumber(E value) throws IllegalArgumentException { - - for (NumberType numberType : NumberType.values()) { - if ( numberType.underlyingClass.isInstance(value) ) { - return numberType; - } - } - - throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported"); - } - - public Number toNumber(double value) { - - switch (this) { - case LONG: - return (long) value; - case DOUBLE: - return value; - case INTEGER: - return (int)value; - case FLOAT: - return (float)value; - case SHORT: - return (short)value; - case BYTE: - return (byte)value; - case BIG_DECIMAL: - return new BigDecimal(value); - } - - throw new InstantiationError("can't convert " + this + " to a Number object"); - } - } } diff --git a/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java new file mode 100644 index 00000000..386d5b32 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java @@ -0,0 +1,111 @@ +package org.solovyev.android.view.widgets; + +import android.content.Context; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.common.utils.Converter; +import org.solovyev.common.utils.Mapper; +import org.solovyev.common.utils.NumberValuer; + +import java.math.BigDecimal; + +/** + * User: serso + * Date: 9/19/11 + * Time: 4:26 PM + */ +public class NumberRangeSeekBar extends AbstractRangeSeekBar { + + @NotNull + private final NumberType numberType; + + /** + * Creates a new RangeSeekBar. + * + * @param minValue The minimum value of the selectable range. + * @param maxValue The maximum value of the selectable range. + * @param context parent context + * @throws IllegalArgumentException Will be thrown if min/max value types are not one of Long, Double, Integer, Float, Short, Byte or BigDecimal. + */ + public NumberRangeSeekBar(@NotNull T minValue, @NotNull T maxValue, Context context) throws IllegalArgumentException { + super(minValue, maxValue, context); + + numberType = NumberType.fromNumber(minValue); + + } + + @NotNull + @Override + protected Converter getToTConverter() { + return new Converter() { + @Override + public T convert(@NotNull Double aDouble) { + return (T) numberType.toNumber(aDouble); + } + }; + } + + @NotNull + @Override + protected Converter getToDoubleConverter() { + return new NumberValuer(); + } + + + /** + * Utility enumeration used to convert between Numbers and doubles. + * + * @author Stephan Tittel (stephan.tittel@kom.tu-darmstadt.de) + */ + private static enum NumberType { + + LONG(Long.class), + DOUBLE(Double.class), + INTEGER(Integer.class), + FLOAT(Float.class), + SHORT(Short.class), + BYTE(Byte.class), + BIG_DECIMAL(BigDecimal.class); + + @NotNull + private final Class underlyingClass; + + private NumberType(@NotNull Class underlyingClass) { + this.underlyingClass = underlyingClass; + } + + @NotNull + public static NumberType fromNumber(E value) throws IllegalArgumentException { + + for (NumberType numberType : NumberType.values()) { + if (numberType.underlyingClass.isInstance(value)) { + return numberType; + } + } + + throw new IllegalArgumentException("Number class '" + value.getClass().getName() + "' is not supported"); + } + + public T toNumber(double value) { + + switch (this) { + case LONG: + return (T)new Long((long) value); + case DOUBLE: + return (T)new Double(value); + case INTEGER: + return (T)new Integer((int) value); + case FLOAT: + return (T)new Float((float) value); + case SHORT: + return (T)new Short((short) value); + case BYTE: + return (T)new Byte((byte) value); + case BIG_DECIMAL: + return (T)new BigDecimal(value); + } + + throw new InstantiationError("can't convert " + this + " to a Number object"); + } + } +}