fixes
This commit is contained in:
parent
d2c85835d5
commit
f930f3e495
@ -7,5 +7,7 @@
|
||||
|
||||
<declare-styleable name="NumberRangeSeekBar">
|
||||
<attr name="boundaries" format="string"/>
|
||||
<attr name="steps" format="integer"/>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
@ -18,6 +18,7 @@
|
||||
a:title="Distance of drag event"
|
||||
a:text=" pxs"
|
||||
a:defaultValue="15;350"
|
||||
range:steps="10"
|
||||
range:boundaries="10;500"/>
|
||||
|
||||
<org.solovyev.android.view.prefs.FloatRangeSeekBarPreference
|
||||
@ -25,6 +26,7 @@
|
||||
a:title="Duration of drag event"
|
||||
a:text=" ms"
|
||||
a:defaultValue="40;2500"
|
||||
range:steps="10"
|
||||
range:boundaries="5;4000"/>
|
||||
|
||||
<org.solovyev.android.view.prefs.FloatRangeSeekBarPreference
|
||||
@ -32,6 +34,7 @@
|
||||
a:title="Angle of drag event"
|
||||
a:text=" degrees"
|
||||
a:defaultValue="0;45"
|
||||
range:steps="5"
|
||||
range:boundaries="0;45"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
@ -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
|
||||
|
@ -137,8 +137,9 @@ public abstract class AbstractDialogPreference<T> extends DialogPreference {
|
||||
private void persist(@Nullable T value) {
|
||||
final String toBePersistedString = getMapper().formatValue(value);
|
||||
if (toBePersistedString != null) {
|
||||
if ( callChangeListener(value) ) {
|
||||
persistString(toBePersistedString);
|
||||
callChangeListener(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,18 +24,26 @@ public abstract class RangeSeekBarPreference<T extends Number> extends AbstractD
|
||||
@NotNull
|
||||
private final Interval<T> 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<T>(boundaries, null, context);
|
||||
this.rangeSeekBar = new NumberRangeSeekBar<T>(boundaries, steps, context);
|
||||
this.rangeSeekBar.setNotifyWhileDragging(true);
|
||||
this.rangeSeekBar.setOnRangeSeekBarChangeListener(this);
|
||||
|
||||
|
@ -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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user