diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5fbeb4ad..e62066d4 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -6,7 +6,6 @@
-
-
+
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index a09699a8..72310bb3 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -14,14 +14,26 @@
+ a:key="org.solovyev.android.calculator.DragButtonCalibrationActivity_distance"
+ a:title="Distance of drag event"
+ a:text=" pxs"
+ a:defaultValue="40;150"
+ range:boundaries="15;500"/>
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
index 50eb77e8..c5fa014a 100644
--- a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
@@ -11,6 +11,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
+import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -18,12 +19,10 @@ import android.view.View;
import android.widget.ImageView;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.widgets.*;
+import org.solovyev.common.FloatIntervalMapper;
import org.solovyev.common.collections.ManyValuedHashMap;
import org.solovyev.common.collections.ManyValuedMap;
-import org.solovyev.common.utils.Interval;
-import org.solovyev.common.utils.IntervalImpl;
-import org.solovyev.common.utils.MathUtils;
-import org.solovyev.common.utils.Point2d;
+import org.solovyev.common.utils.*;
import java.util.ArrayList;
import java.util.HashMap;
@@ -42,13 +41,6 @@ public class DragButtonCalibrationActivity extends Activity {
private final Map map = new HashMap();
- public static final String PREFERENCES = "dragButtonPreferences";
-
- public static final String PREFERENCES_FIRST_RUN = "firstRun";
-
- public static final String PREFERENCES_MIN = "min";
- public static final String PREFERENCES_MAX = "max";
-
private static final float DEFAULT_VALUE = -999;
private static final int MIN_HISTORY_FOR_CALIBRATION = 10;
public static final String INTENT_ACTION = "org.solovyev.android.calculator.DragButtonPreferencesChanged";
@@ -168,7 +160,7 @@ public class DragButtonCalibrationActivity extends Activity {
Log.d(this.getClass().getName(), "Time statistics: ");
logStatData(timeStatData);
- final SharedPreferences settings = getSharedPreferences(PREFERENCES, 0);
+ final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = settings.edit();
setPreferences(angleStatData, editor, PreferenceType.angle);
@@ -186,59 +178,61 @@ public class DragButtonCalibrationActivity extends Activity {
}
private void setPreferences(@NotNull Map statData, @NotNull SharedPreferences.Editor editor, @NotNull PreferenceType preferenceType) {
+ final Mapper> mapper = new FloatIntervalMapper();
for (Map.Entry entry : statData.entrySet()) {
final float min = (float) entry.getValue().getMean() - 2 * (float) entry.getValue().getStandardDeviation();
final float max = (float) entry.getValue().getMean() + 2 * (float) entry.getValue().getStandardDeviation();
- editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MIN, Math.max(0, min));
- editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MAX, max);
+ editor.putString(getPreferenceId(preferenceType, entry.getKey()), mapper.formatValue(transformInterval(preferenceType, entry.getKey(), new IntervalImpl(Math.max(0, min), max))));
}
}
+ // todo serso: currently we do not use direction
+ public static String getPreferenceId(@NotNull PreferenceType preferenceType, @NotNull DragDirection direction) {
+ return "org.solovyev.android.calculator.DragButtonCalibrationActivity" + "_" + preferenceType.name() /*+ "_" + direction.name()*/;
+ }
+
@NotNull
public static Preferences getPreferences(@NotNull Context context) {
- SharedPreferences preferences = context.getSharedPreferences(PREFERENCES, MODE_PRIVATE);
+ final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+
+ final Mapper> mapper = new FloatIntervalMapper();
final Preferences result = new Preferences();
for (PreferenceType preferenceType : PreferenceType.values()) {
for (DragDirection dragDirection : DragDirection.values()) {
- final float defaultMin;
- final float defaultMax;
+ final Interval defaultValue;
switch (preferenceType) {
case angle:
switch (dragDirection) {
case up:
- defaultMin = 130f;
- defaultMax = 180f;
+ defaultValue = new IntervalImpl(130f, 180f);
break;
case down:
- defaultMin = 0f;
- defaultMax = 50f;
+ defaultValue = new IntervalImpl(0f, 50f);
break;
default:
- defaultMin = 0;
- defaultMax = 0;
+ defaultValue = new IntervalImpl(0f, 0f);
}
break;
case distance:
- defaultMin = 10f;
- defaultMax = 150f;
+ defaultValue = new IntervalImpl(10f, 150f);
break;
case duration:
- defaultMin = 40f;
- defaultMax = 1000f;
+ defaultValue = new IntervalImpl(40f, 1000f);
break;
default:
- defaultMin = DEFAULT_VALUE;
- defaultMax = DEFAULT_VALUE;
+ defaultValue = new IntervalImpl(DEFAULT_VALUE, DEFAULT_VALUE);
}
- final float min = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MIN, defaultMin);
- final float max = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MAX, defaultMax);
+ final String value = preferences.getString(getPreferenceId(preferenceType, dragDirection), mapper.formatValue(defaultValue));
- if (min != DEFAULT_VALUE && max != DEFAULT_VALUE) {
- final DragPreference directionPreference = new DragPreference(dragDirection, new IntervalImpl(min, max));
+ final Interval interval = mapper.parseValue(value);
+ transformInterval(preferenceType, dragDirection, interval);
+ if (new IntervalImpl(DEFAULT_VALUE, DEFAULT_VALUE).equals(interval)) {
+ assert interval != null;
+ final DragPreference directionPreference = new DragPreference(dragDirection, interval);
Preference preference = result.getPreferencesMap().get(preferenceType);
if (preference == null) {
@@ -257,6 +251,17 @@ public class DragButtonCalibrationActivity extends Activity {
return result;
}
+ @NotNull
+ private static Interval transformInterval(@NotNull PreferenceType preferenceType, @NotNull DragDirection dragDirection, @NotNull Interval interval) {
+ if ( preferenceType == PreferenceType.angle && dragDirection == DragDirection.down ) {
+ final Interval clone = interval.clone();
+ interval.setLeftBorder(180f - clone.getRightBorder());
+ interval.setRightBorder(180f - clone.getLeftBorder());
+ }
+
+ return interval;
+ }
+
public static class DragPreference {
@NotNull
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 ff309979..bc079fdc 100644
--- a/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java
+++ b/src/main/java/org/solovyev/android/view/prefs/AbstractDialogPreference.java
@@ -4,17 +4,19 @@ import android.content.Context;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.Gravity;
+import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.utils.Mapper;
/**
* User: serso
* Date: 9/19/11
* Time: 3:17 PM
*/
-public class AbstractDialogPreference extends DialogPreference {
+public abstract class AbstractDialogPreference extends DialogPreference {
@NotNull
protected static final String androidns = "http://schemas.android.com/apk/res/android";
@@ -26,38 +28,118 @@ public class AbstractDialogPreference extends DialogPreference {
protected final Context context;
@Nullable
- protected String dialogMessage;
+ protected String description;
- public AbstractDialogPreference(Context context, AttributeSet attrs) {
+ @Nullable
+ protected T value;
+
+ @Nullable
+ private T defaultValue;
+
+ @Nullable
+ protected String valueText;
+
+ @Nullable
+ private final String defaultStringValue;
+
+
+ public AbstractDialogPreference(Context context, AttributeSet attrs, @Nullable String defaultStringValue) {
super(context, attrs);
this.context = context;
+ this.defaultStringValue = defaultStringValue;
- dialogMessage = attrs.getAttributeValue(androidns, "dialogMessage");
+ final String defaultValueFromAttrs = attrs.getAttributeValue(androidns, "defaultValue");
+ if ( defaultValueFromAttrs != null ) {
+ defaultValue = getMapper().parseValue(defaultValueFromAttrs);
+ } else if (defaultStringValue != null) {
+ defaultValue = getMapper().parseValue(defaultStringValue);
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ description = attrs.getAttributeValue(androidns, "dialogMessage");
+ valueText = attrs.getAttributeValue(androidns, "text");
}
@Override
+ @NotNull
protected LinearLayout onCreateDialogView() {
- LinearLayout.LayoutParams params;
- LinearLayout layout = new LinearLayout(context);
- layout.setOrientation(LinearLayout.VERTICAL);
- layout.setPadding(6, 6, 6, 6);
-
- final TextView splashText = new TextView(context);
- if (dialogMessage != null) {
- splashText.setText(dialogMessage);
+ if (shouldPersist()) {
+ value = getPersistedValue();
+ }
+
+ final LinearLayout result = new LinearLayout(context);
+ result.setOrientation(LinearLayout.VERTICAL);
+ result.setPadding(6, 6, 6, 6);
+
+ if (description != null) {
+ final TextView splashText = new TextView(context);
+ splashText.setText(description);
+ result.addView(splashText);
}
- layout.addView(splashText);
valueTextView = new TextView(context);
valueTextView.setGravity(Gravity.CENTER_HORIZONTAL);
valueTextView.setTextSize(32);
- params = new LinearLayout.LayoutParams(
+
+ final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
- layout.addView(valueTextView, params);
+ result.addView(valueTextView, params);
- return layout;
+ return result;
}
+ @Override
+ protected void onSetInitialValue(boolean restore, Object defaultValue) {
+ super.onSetInitialValue(restore, defaultValue);
+ if (restore) {
+ if (shouldPersist()) {
+ value = getPersistedValue();
+ } else {
+ value = this.defaultValue;
+ }
+ } else {
+ value = (T) defaultValue;
+ if (shouldPersist()) {
+ persist(this.value);
+ }
+ }
+ }
+
+ @Override
+ protected void onBindDialogView(View v) {
+ super.onBindDialogView(v);
+ initPreferenceView();
+ }
+
+ protected abstract void initPreferenceView();
+
+ private T getPersistedValue() {
+ String persistedString = getPersistedString(defaultStringValue);
+ if ( persistedString == defaultStringValue ) {
+ return defaultValue;
+ } else {
+ return getMapper().parseValue(persistedString);
+ }
+ }
+
+ protected void persistValue(@Nullable T value) {
+ if (callChangeListener(value)) {
+ if (shouldPersist()) {
+ persist(value);
+ }
+ }
+ }
+
+ private void persist(@Nullable T value) {
+ final String toBePersistedString = getMapper().formatValue(value);
+ if (toBePersistedString != null) {
+ persistString(toBePersistedString);
+ }
+ }
+
+ @NotNull
+ protected abstract Mapper getMapper();
}
diff --git a/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java
index d6a17a58..e0183685 100644
--- a/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java
+++ b/src/main/java/org/solovyev/android/view/prefs/IntegerRangeSeekBarPreference.java
@@ -9,7 +9,8 @@ package org.solovyev.android.view.prefs;
import android.content.Context;
import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull;
-import org.solovyev.common.utils.Converter;
+import org.solovyev.common.IntegerIntervalMapper;
+import org.solovyev.common.utils.*;
/**
* User: serso
@@ -24,13 +25,8 @@ public class IntegerRangeSeekBarPreference extends RangeSeekBarPreference getConverter() {
- return new Converter() {
- @NotNull
- @Override
- public Integer convert(@NotNull String value) {
- return Integer.valueOf(value);
- }
- };
+ protected Mapper> getMapper() {
+ return new IntegerIntervalMapper();
}
+
}
diff --git a/src/main/java/org/solovyev/android/view/prefs/PersistenceValueGetter.java b/src/main/java/org/solovyev/android/view/prefs/PersistenceValueGetter.java
new file mode 100644
index 00000000..69749f07
--- /dev/null
+++ b/src/main/java/org/solovyev/android/view/prefs/PersistenceValueGetter.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.view.prefs;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: serso
+ * Date: 9/20/11
+ * Time: 10:15 PM
+ */
+public interface PersistenceValueGetter {
+
+ @Nullable
+ T getPersistedValue(@Nullable T defaultValue);
+}
diff --git a/src/main/java/org/solovyev/android/view/prefs/PersistenceValueSetter.java b/src/main/java/org/solovyev/android/view/prefs/PersistenceValueSetter.java
new file mode 100644
index 00000000..63acddbe
--- /dev/null
+++ b/src/main/java/org/solovyev/android/view/prefs/PersistenceValueSetter.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.view.prefs;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: serso
+ * Date: 9/20/11
+ * Time: 10:14 PM
+ */
+public interface PersistenceValueSetter {
+
+ void persist(@Nullable T value);
+}
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 113cf827..982f0c87 100644
--- a/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java
+++ b/src/main/java/org/solovyev/android/view/prefs/RangeSeekBarPreference.java
@@ -2,24 +2,19 @@ package org.solovyev.android.view.prefs;
import android.content.Context;
import android.util.AttributeSet;
-import android.view.View;
import android.widget.LinearLayout;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.widgets.AbstractRangeSeekBar;
import org.solovyev.android.view.widgets.NumberRangeSeekBar;
-import org.solovyev.common.utils.CollectionsUtils;
-import org.solovyev.common.utils.Converter;
-import org.solovyev.common.utils.StringMapper;
-
-import java.util.Arrays;
-import java.util.List;
+import org.solovyev.common.utils.Interval;
+import org.solovyev.common.utils.NumberInterval;
/**
* User: serso
* Date: 9/19/11
* Time: 12:27 PM
*/
-public abstract class RangeSeekBarPreference extends AbstractDialogPreference implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener {
+public abstract class RangeSeekBarPreference extends AbstractDialogPreference> implements AbstractRangeSeekBar.OnRangeSeekBarChangeListener {
public final static String localNameSpace = "http://schemas.android.com/apk/res/org.solovyev.android.calculator";
@@ -27,52 +22,26 @@ public abstract class RangeSeekBarPreference extends AbstractD
private AbstractRangeSeekBar rangeSeekBar;
@NotNull
- private T min;
-
- @NotNull
- private T max;
-
- @NotNull
- private T selectedMin;
-
- @NotNull
- private T selectedMax;
-
+ private final Interval boundaries;
public RangeSeekBarPreference(@NotNull Context context, AttributeSet attrs) {
- super(context, attrs);
+ super(context, attrs, null);
+ boundaries = getMapper().parseValue(attrs.getAttributeValue(localNameSpace, "boundaries"));
- final Converter c = getConverter();
-
- String minString = attrs.getAttributeValue(localNameSpace, "min");
- min = c.convert(minString == null ? "0" : minString);
- String maxString = attrs.getAttributeValue(localNameSpace, "max");
- max = c.convert(maxString == null ? "100" : maxString);
-
-
- this.rangeSeekBar = new NumberRangeSeekBar(min, max, null, context);
+ assert boundaries != null;
+ this.rangeSeekBar = new NumberRangeSeekBar(boundaries, null, context);
rangeSeekBar.setOnRangeSeekBarChangeListener(this);
}
- public void setMin(@NotNull String min) {
- this.min = getConverter().convert(min);
- }
-
- public void setMax(@NotNull String max) {
- this.max = getConverter().convert(max);
- }
-
@NotNull
- abstract Converter getConverter();
-
@Override
protected LinearLayout onCreateDialogView() {
final LinearLayout result = super.onCreateDialogView();
- this.rangeSeekBar = new NumberRangeSeekBar(min, max, null, context);
+ this.rangeSeekBar = new NumberRangeSeekBar(boundaries, null, context);
rangeSeekBar.setOnRangeSeekBarChangeListener(this);
- initRangeSeekBar();
+ initPreferenceView();
result.addView(rangeSeekBar);
@@ -80,38 +49,24 @@ public abstract class RangeSeekBarPreference extends AbstractD
}
@Override
- protected void onBindDialogView(View v) {
- super.onBindDialogView(v);
- initRangeSeekBar();
- }
-
- private void initRangeSeekBar() {
- rangeSeekBar.setSelectedMinValue(selectedMin);
- rangeSeekBar.setSelectedMaxValue(selectedMax);
- }
-
- @Override
- protected void onSetInitialValue(boolean restore, Object defaultValue) {
- super.onSetInitialValue(restore, defaultValue);
-
- final List values;
- if (restore) {
- values = CollectionsUtils.split(getPersistedString("0;100"), ";", new StringMapper());
- } else {
- values = CollectionsUtils.split(String.valueOf(defaultValue), ";", new StringMapper());
+ protected void initPreferenceView() {
+ if (value != null) {
+ rangeSeekBar.setSelectedMinValue(value.getLeftBorder());
+ rangeSeekBar.setSelectedMaxValue(value.getRightBorder());
+ setValueText(value);
}
-
- selectedMin = getConverter().convert(values.get(0));
- selectedMax = getConverter().convert(values.get(1));
}
-
@Override
public void rangeSeekBarValuesChanged(T minValue, T maxValue) {
- final String value = CollectionsUtils.formatValue(Arrays.asList(String.valueOf(minValue), String.valueOf(maxValue)), ";", new StringMapper());
- if (shouldPersist()) {
- persistString(value);
- }
- callChangeListener(value);
+ final Interval interval = new NumberInterval(minValue, maxValue);
+ persistValue(interval);
+
+ setValueText(interval);
+ }
+
+ private void setValueText(@NotNull Interval interval) {
+ final String t = String.valueOf(interval);
+ valueTextView.setText(valueText == null ? t : t.concat(valueText));
}
}
diff --git a/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java b/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java
index 9398cd3b..67efa38b 100644
--- a/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java
+++ b/src/main/java/org/solovyev/android/view/prefs/SeekBarPreference.java
@@ -8,11 +8,11 @@ package org.solovyev.android.view.prefs;
import android.content.Context;
import android.util.AttributeSet;
-import android.view.View;
-import android.widget.SeekBar;
import android.widget.LinearLayout;
+import android.widget.SeekBar;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.utils.Mapper;
/* The following code was written by Matthew Wiggins
@@ -21,24 +21,20 @@ import org.jetbrains.annotations.Nullable;
* http://www.apache.org/licenses/LICENSE-2.0
*/
-public class SeekBarPreference extends AbstractDialogPreference implements SeekBar.OnSeekBarChangeListener {
+public class SeekBarPreference extends AbstractDialogPreference implements SeekBar.OnSeekBarChangeListener {
@NotNull
private SeekBar seekBar;
- private int defaultValue, max, value = 0;
-
- @Nullable
- protected String valueText;
+ private int max = 0;
public SeekBarPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
+ super(context, attrs, "50");
- defaultValue = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
max = attrs.getAttributeIntValue(androidns, "max", 100);
- valueText = attrs.getAttributeValue(androidns, "text");
}
+ @NotNull
@Override
protected LinearLayout onCreateDialogView() {
final LinearLayout layout = super.onCreateDialogView();
@@ -47,40 +43,45 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
seekBar.setOnSeekBarChangeListener(this);
layout.addView(seekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
- if (shouldPersist())
- value = getPersistedInt(defaultValue);
-
- initSeekBar();
+ initPreferenceView();
return layout;
}
- private void initSeekBar() {
+ @Override
+ protected void initPreferenceView() {
seekBar.setMax(max);
- seekBar.setProgress(value);
+ if (value != null) {
+ seekBar.setProgress(value);
+ setValueText(value);
+ }
}
+ @NotNull
@Override
- protected void onBindDialogView(View v) {
- super.onBindDialogView(v);
- initSeekBar();
- }
+ protected Mapper getMapper() {
+ return new Mapper() {
+ @Override
+ public String formatValue(@Nullable Integer integer) throws IllegalArgumentException {
+ return integer == null ? null : String.valueOf(integer);
+ }
- @Override
- protected void onSetInitialValue(boolean restore, Object defaultValue) {
- super.onSetInitialValue(restore, defaultValue);
- if (restore)
- value = shouldPersist() ? getPersistedInt(this.defaultValue) : 0;
- else
- value = (Integer) defaultValue;
+ @Override
+ public Integer parseValue(@Nullable String s) throws IllegalArgumentException {
+ return s == null ? null : Integer.valueOf(s);
+ }
+ };
}
public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
+ setValueText(value);
+
+ persistValue(value);
+ }
+
+ private void setValueText(int value) {
String t = String.valueOf(value);
valueTextView.setText(valueText == null ? t : t.concat(valueText));
- if (shouldPersist())
- persistInt(value);
- callChangeListener(new Integer(value));
}
public void onStartTrackingTouch(SeekBar seek) {
@@ -99,8 +100,7 @@ public class SeekBarPreference extends AbstractDialogPreference implements SeekB
public void setProgress(int progress) {
value = progress;
- if (seekBar != null)
- seekBar.setProgress(progress);
+ seekBar.setProgress(progress);
}
public int getProgress() {
diff --git a/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java
index c7b0d06f..2feac78c 100644
--- a/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java
+++ b/src/main/java/org/solovyev/android/view/widgets/NumberRangeSeekBar.java
@@ -4,6 +4,7 @@ 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.Interval;
import org.solovyev.common.utils.NumberValuer;
/**
@@ -16,12 +17,17 @@ public class NumberRangeSeekBar extends AbstractRangeSeekBar boundaries, @Nullable Integer steps, Context context) throws IllegalArgumentException {
+ this(boundaries.getLeftBorder(), boundaries.getRightBorder(), steps, context);
+ }
+
/**
* Creates a new RangeSeekBar.
*
* @param minValue The minimum value of the selectable range.
* @param maxValue The maximum value of the selectable range.
- * @param steps number of steps of range
+ * @param steps number of steps of 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.
*/
diff --git a/src/main/java/org/solovyev/common/AbstractIntervalMapper.java b/src/main/java/org/solovyev/common/AbstractIntervalMapper.java
new file mode 100644
index 00000000..bad45364
--- /dev/null
+++ b/src/main/java/org/solovyev/common/AbstractIntervalMapper.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.utils.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * User: serso
+ * Date: 9/21/11
+ * Time: 12:02 AM
+ */
+public abstract class AbstractIntervalMapper implements Mapper> {
+
+ @Override
+ public String formatValue(@Nullable Interval interval) throws IllegalArgumentException {
+ if (interval != null) {
+ return CollectionsUtils.formatValue(Arrays.asList(interval.getLeftBorder(), interval.getRightBorder()), ";", getFormatter());
+ } else {
+ return null;
+ }
+ }
+
+ @NotNull
+ protected abstract Formatter getFormatter();
+
+ @Override
+ public Interval parseValue(@Nullable String s) throws IllegalArgumentException {
+ final List list = CollectionsUtils.split(s, ";", getParser());
+
+ assert list.size() == 2;
+ return new IntervalImpl(list.get(0), list.get(1));
+ }
+
+ @NotNull
+ protected abstract Parser getParser();
+}
diff --git a/src/main/java/org/solovyev/common/FloatIntervalMapper.java b/src/main/java/org/solovyev/common/FloatIntervalMapper.java
new file mode 100644
index 00000000..75d7940a
--- /dev/null
+++ b/src/main/java/org/solovyev/common/FloatIntervalMapper.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.math.ValueOfFormatter;
+import org.solovyev.common.utils.Formatter;
+import org.solovyev.common.utils.Parser;
+
+/**
+ * User: serso
+ * Date: 9/21/11
+ * Time: 12:06 AM
+ */
+public class FloatIntervalMapper extends AbstractIntervalMapper {
+ @NotNull
+ @Override
+ protected Formatter getFormatter() {
+ return new ValueOfFormatter();
+ }
+
+ @NotNull
+ @Override
+ protected Parser getParser() {
+ return new Parser() {
+ @Override
+ public Float parseValue(@Nullable String s) throws IllegalArgumentException {
+ return Float.valueOf(s);
+ }
+ };
+ }
+}
diff --git a/src/main/java/org/solovyev/common/IntegerIntervalMapper.java b/src/main/java/org/solovyev/common/IntegerIntervalMapper.java
new file mode 100644
index 00000000..b87141b1
--- /dev/null
+++ b/src/main/java/org/solovyev/common/IntegerIntervalMapper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.common;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.math.ValueOfFormatter;
+import org.solovyev.common.utils.*;
+
+/**
+* User: serso
+* Date: 9/20/11
+* Time: 11:56 PM
+*/
+public class IntegerIntervalMapper extends AbstractIntervalMapper {
+
+ @NotNull
+ protected Formatter getFormatter() {
+ return new ValueOfFormatter();
+ }
+
+ @NotNull
+ protected Parser getParser() {
+ return new Parser() {
+ @Override
+ public Integer parseValue(@Nullable String s) throws IllegalArgumentException {
+ return Integer.valueOf(s);
+ }
+ };
+ }
+}
diff --git a/src/main/java/org/solovyev/common/math/ValueOfFormatter.java b/src/main/java/org/solovyev/common/math/ValueOfFormatter.java
new file mode 100644
index 00000000..82f3f401
--- /dev/null
+++ b/src/main/java/org/solovyev/common/math/ValueOfFormatter.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.common.math;
+
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.utils.Formatter;
+
+/**
+ * User: serso
+ * Date: 9/20/11
+ * Time: 10:52 PM
+ */
+public class ValueOfFormatter implements Formatter{
+
+ @Override
+ public String formatValue(@Nullable T t) throws IllegalArgumentException {
+ return String.valueOf(t);
+ }
+}