From f930f3e4951510f6bf357906a655e7152eb6d5e8 Mon Sep 17 00:00:00 2001 From: serso Date: Sun, 25 Sep 2011 11:12:59 +0400 Subject: [PATCH] fixes --- res/values/attrs.xml | 2 + res/xml/preferences.xml | 3 + .../calculator/CalculatorActivity.java | 3 + .../view/prefs/AbstractDialogPreference.java | 5 +- .../view/prefs/RangeSeekBarPreference.java | 12 +++- .../view/widgets/AbstractRangeSeekBar.java | 57 ++++++++++++------- .../common/math/DiscreteNormalizer.java | 27 ++++++--- 7 files changed, 75 insertions(+), 34 deletions(-) diff --git a/res/values/attrs.xml b/res/values/attrs.xml index e62066d4..51f2e6a6 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -7,5 +7,7 @@ + + diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 1d426216..899bdca0 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -18,6 +18,7 @@ a:title="Distance of drag event" a:text=" pxs" a:defaultValue="15;350" + range:steps="10" range:boundaries="10;500"/> diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index be0ad54d..f9e6a368 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -8,6 +8,7 @@ package org.solovyev.android.calculator; import android.app.Activity; import android.content.*; import android.os.Bundle; +import android.preference.PreferenceManager; import android.text.ClipboardManager; import android.util.Log; import android.util.TypedValue; @@ -102,6 +103,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh }; registerReceiver(preferencesChangesReceiver, new IntentFilter(DragButtonCalibrationActivity.INTENT_ACTION)); + + PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this); } @Override diff --git a/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java b/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java index bdf441f8..809a93f6 100644 --- a/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java +++ b/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java @@ -137,8 +137,9 @@ public abstract class AbstractDialogPreference extends DialogPreference { private void persist(@Nullable T value) { final String toBePersistedString = getMapper().formatValue(value); if (toBePersistedString != null) { - persistString(toBePersistedString); - callChangeListener(value); + if ( callChangeListener(value) ) { + persistString(toBePersistedString); + } } } diff --git a/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java index b7c2c3fb..bd3c1bac 100644 --- a/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java +++ b/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java @@ -24,18 +24,26 @@ public abstract class RangeSeekBarPreference extends AbstractD @NotNull private final Interval boundaries; + private Integer steps; + public RangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) { super(context, attrs, null); + //noinspection ConstantConditions boundaries = getMapper().parseValue(attrs.getAttributeValue(localNameSpace, "boundaries")); - assert boundaries != null; + steps = attrs.getAttributeIntValue(localNameSpace, "steps", -1); + if ( steps.equals(-1) ) { + steps = null; + } + + assert steps == null || steps >= 2; createPreferenceView(); } private void createPreferenceView() { - this.rangeSeekBar = new NumberRangeSeekBar(boundaries, null, context); + this.rangeSeekBar = new NumberRangeSeekBar(boundaries, steps, context); this.rangeSeekBar.setNotifyWhileDragging(true); this.rangeSeekBar.setOnRangeSeekBarChangeListener(this); diff --git a/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java index 3091ed18..60f2beeb 100644 --- a/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java +++ b/src/main/java/org/solovyev/android/view/widgets/AbstractRangeSeekBar.java @@ -14,7 +14,6 @@ import android.widget.ImageView; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; -import org.solovyev.common.math.DiscreteNormalizer; import org.solovyev.common.math.LinearNormalizer; import org.solovyev.common.math.Normalizer; import org.solovyev.common.utils.Converter; @@ -44,7 +43,10 @@ public abstract class AbstractRangeSeekBar extends ImageView { private final T minValue, maxValue; @NotNull - private final Normalizer normalizer; + private final Normalizer fromValueNormalizer; + + @NotNull + private final Normalizer fromScreenNormalizer; private double normalizedMinValue = 0d; @@ -63,7 +65,8 @@ public abstract class AbstractRangeSeekBar extends ImageView { * * @param minValue The minimum value of the selectable range. * @param maxValue The maximum value of the selectable range. - * @param context + * @param steps number of steps to be used in range seek bar + * @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 AbstractRangeSeekBar(@NotNull T minValue, @NotNull T maxValue, @Nullable Integer steps, Context context) throws IllegalArgumentException { @@ -75,13 +78,28 @@ public abstract class AbstractRangeSeekBar extends ImageView { this.toDoubleConverter = getToDoubleConverter(); this.toTConverter = getToTConverter(); - if (steps == null) { - normalizer = new LinearNormalizer(toDoubleConverter.convert(minValue), toDoubleConverter.convert(maxValue)); - } else { - normalizer = new DiscreteNormalizer(toDoubleConverter.convert(minValue), toDoubleConverter.convert(maxValue), steps); - } + fromValueNormalizer = new LinearNormalizer(toDoubleConverter.convert(minValue), toDoubleConverter.convert(maxValue)); tc = new ThumbContainer(); + + fromScreenNormalizer = new Normalizer() { + @Override + public double normalize(double value) { + int width = getWidth(); + if (width <= 2 * tc.padding) { + // prevent division by zero, simply return 0. + return 0d; + } else { + double result = (value - tc.padding) / (width - 2 * tc.padding); + return Math.min(1d, Math.max(0d, result)); + } + } + + @Override + public double denormalize(double value) { + return (float) (tc.padding + value * (getWidth() - 2 * tc.padding)); + } + }; } @NotNull @@ -180,11 +198,15 @@ public abstract class AbstractRangeSeekBar extends ImageView { break; case MotionEvent.ACTION_MOVE: if (pressedThumb != null) { + + double value = convertToNormalizedValue(event.getX()); + if (Thumb.MIN.equals(pressedThumb)) { - setNormalizedMinValue(convertToNormalizedValue(event.getX())); + setNormalizedMinValue(value); } else if (Thumb.MAX.equals(pressedThumb)) { - setNormalizedMaxValue(convertToNormalizedValue(event.getX())); + setNormalizedMaxValue(value); } + if (notifyWhileDragging && listener != null) { listener.rangeSeekBarValuesChanged(getSelectedMinValue(), getSelectedMaxValue(), false); } @@ -317,7 +339,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { */ @SuppressWarnings("unchecked") private T denormalizeValue(double normalized) { - return toTConverter.convert(normalizer.denormalize(normalized)); + return toTConverter.convert(fromValueNormalizer.denormalize(normalized)); } /** @@ -327,7 +349,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { * @return The normalized double. */ private double normalizeValue(T value) { - return normalizer.normalize(toDoubleConverter.convert(value)); + return fromValueNormalizer.normalize(toDoubleConverter.convert(value)); } /** @@ -337,7 +359,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { * @return The converted value in screen space. */ private float convertToScreenValue(double normalizedValue) { - return (float) (tc.padding + normalizedValue * (getWidth() - 2 * tc.padding)); + return (float)this.fromScreenNormalizer.denormalize(normalizedValue); } /** @@ -347,14 +369,7 @@ public abstract class AbstractRangeSeekBar extends ImageView { * @return The normalized value. */ private double convertToNormalizedValue(float screenValue) { - int width = getWidth(); - if (width <= 2 * tc.padding) { - // prevent division by zero, simply return 0. - return 0d; - } else { - double result = (screenValue - tc.padding) / (width - 2 * tc.padding); - return Math.min(1d, Math.max(0d, result)); - } + return this.fromScreenNormalizer.normalize(screenValue); } /** diff --git a/src/main/java/org/solovyev/common/math/DiscreteNormalizer.java b/src/main/java/org/solovyev/common/math/DiscreteNormalizer.java index 0dff938b..14ccf0fb 100644 --- a/src/main/java/org/solovyev/common/math/DiscreteNormalizer.java +++ b/src/main/java/org/solovyev/common/math/DiscreteNormalizer.java @@ -1,6 +1,7 @@ package org.solovyev.common.math; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * User: serso @@ -10,35 +11,43 @@ import org.jetbrains.annotations.NotNull; public class DiscreteNormalizer implements Normalizer { @NotNull - private final LinearNormalizer linearNormalizer; + private final Normalizer normalizer; private final double min; private final double step; public DiscreteNormalizer(double min, double max, int steps) { + this(min, max, steps, null); + } + + public DiscreteNormalizer(double min, double max, int steps, @Nullable Normalizer normalizer) { assert min <= max; assert steps > 1; - this.linearNormalizer = new LinearNormalizer(min, max); + if (normalizer != null) { + this.normalizer = normalizer; + } else { + this.normalizer = new LinearNormalizer(min, max); + } - this.step = linearNormalizer.normalize((max - min) / (steps - 1)); - this.min = linearNormalizer.normalize(min); + this.step = this.normalizer.normalize((max - min) / (steps - 1)); + this.min = this.normalizer.normalize(min); } public DiscreteNormalizer(double min, double max, double step) { assert min <= max; assert step > 0; - this.linearNormalizer = new LinearNormalizer(min, max); + this.normalizer = new LinearNormalizer(min, max); - this.step = linearNormalizer.normalize(step); - this.min = linearNormalizer.normalize(min); + this.step = normalizer.normalize(step); + this.min = normalizer.normalize(min); } @Override public double normalize(double value) { - double normalizedValue = linearNormalizer.normalize(value); + double normalizedValue = normalizer.normalize(value); double result = min; while (true) { @@ -54,6 +63,6 @@ public class DiscreteNormalizer implements Normalizer { @Override public double denormalize(double value) { - return linearNormalizer.denormalize(value); + return normalizer.denormalize(value); } }