Number format preferences screen
This commit is contained in:
parent
49ab48a44c
commit
eb1c733153
@ -22,35 +22,12 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
|
|
||||||
import org.solovyev.android.Check;
|
|
||||||
import org.solovyev.android.calculator.functions.FunctionsRegistry;
|
|
||||||
import org.solovyev.android.calculator.operators.OperatorsRegistry;
|
|
||||||
import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry;
|
|
||||||
import org.solovyev.android.prefs.BooleanPreference;
|
|
||||||
import org.solovyev.android.prefs.CharacterPreference;
|
|
||||||
import org.solovyev.android.prefs.IntegerPreference;
|
|
||||||
import org.solovyev.android.prefs.Preference;
|
|
||||||
import org.solovyev.android.prefs.StringPreference;
|
|
||||||
import org.solovyev.common.NumberFormatter;
|
|
||||||
import org.solovyev.common.text.EnumMapper;
|
|
||||||
import org.solovyev.common.text.NumberMapper;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import jscl.AngleUnit;
|
import jscl.AngleUnit;
|
||||||
import jscl.JsclMathEngine;
|
import jscl.JsclMathEngine;
|
||||||
import jscl.MathEngine;
|
import jscl.MathEngine;
|
||||||
@ -59,6 +36,25 @@ import jscl.math.operator.Operator;
|
|||||||
import jscl.text.Identifier;
|
import jscl.text.Identifier;
|
||||||
import jscl.text.Parser;
|
import jscl.text.Parser;
|
||||||
import midpcalc.Real;
|
import midpcalc.Real;
|
||||||
|
import org.solovyev.android.Check;
|
||||||
|
import org.solovyev.android.calculator.functions.FunctionsRegistry;
|
||||||
|
import org.solovyev.android.calculator.operators.OperatorsRegistry;
|
||||||
|
import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry;
|
||||||
|
import org.solovyev.android.calculator.preferences.PreferenceEntry;
|
||||||
|
import org.solovyev.android.prefs.*;
|
||||||
|
import org.solovyev.common.text.CharacterMapper;
|
||||||
|
import org.solovyev.common.NumberFormatter;
|
||||||
|
import org.solovyev.common.text.EnumMapper;
|
||||||
|
import org.solovyev.common.text.NumberMapper;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class Engine implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class Engine implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
@ -98,13 +94,6 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
|
|||||||
this.mathEngine.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
|
this.mathEngine.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull BooleanPreference preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) {
|
|
||||||
if (!preferences.contains(oldKey)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
editor.putBoolean(preference.getKey(), preferences.getBoolean(oldKey, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull StringPreference<?> preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) {
|
private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull StringPreference<?> preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) {
|
||||||
if (!preferences.contains(oldKey)) {
|
if (!preferences.contains(oldKey)) {
|
||||||
return;
|
return;
|
||||||
@ -112,15 +101,6 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
|
|||||||
editor.putString(preference.getKey(), preferences.getString(oldKey, null));
|
editor.putString(preference.getKey(), preferences.getString(oldKey, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void migratePreference(@Nonnull SharedPreferences preferences, @Nonnull CharacterPreference preference, @Nonnull String oldKey, @Nonnull SharedPreferences.Editor editor) {
|
|
||||||
if (!preferences.contains(oldKey)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String s = preferences.getString(oldKey, null);
|
|
||||||
editor.putInt(preference.getKey(), TextUtils.isEmpty(s) ? 0 : s.charAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean isValidName(@Nullable String name) {
|
public static boolean isValidName(@Nullable String name) {
|
||||||
if (!TextUtils.isEmpty(name)) {
|
if (!TextUtils.isEmpty(name)) {
|
||||||
try {
|
try {
|
||||||
@ -261,7 +241,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Notation {
|
public enum Notation implements PreferenceEntry {
|
||||||
dec(Real.NumberFormat.FSE_NONE, R.string.cpp_number_format_dec),
|
dec(Real.NumberFormat.FSE_NONE, R.string.cpp_number_format_dec),
|
||||||
eng(Real.NumberFormat.FSE_ENG, R.string.cpp_number_format_eng),
|
eng(Real.NumberFormat.FSE_ENG, R.string.cpp_number_format_eng),
|
||||||
sci(Real.NumberFormat.FSE_SCI, R.string.cpp_number_format_sci);
|
sci(Real.NumberFormat.FSE_SCI, R.string.cpp_number_format_sci);
|
||||||
@ -274,6 +254,18 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public CharSequence getName(@NonNull Context context) {
|
||||||
|
return context.getString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public CharSequence getId() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ChangedEvent {
|
public static class ChangedEvent {
|
||||||
@ -307,7 +299,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
|
|||||||
public static class Output {
|
public static class Output {
|
||||||
public static final StringPreference<Integer> precision = StringPreference.ofTypedValue("engine.output.precision", "5", NumberMapper.of(Integer.class));
|
public static final StringPreference<Integer> precision = StringPreference.ofTypedValue("engine.output.precision", "5", NumberMapper.of(Integer.class));
|
||||||
public static final StringPreference<Notation> notation = StringPreference.ofEnum("engine.output.notation", Notation.dec, Notation.class);
|
public static final StringPreference<Notation> notation = StringPreference.ofEnum("engine.output.notation", Notation.dec, Notation.class);
|
||||||
public static final CharacterPreference separator = CharacterPreference.of("engine.output.separator", JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
|
public static final StringPreference<Character> separator = StringPreference.ofTypedValue("engine.output.separator", JsclMathEngine.GROUPING_SEPARATOR_DEFAULT, CharacterMapper.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package org.solovyev.android.calculator.preferences;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import jscl.JsclMathEngine;
|
||||||
|
import org.solovyev.android.material.preferences.Preference;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class NumberFormatExamplesPreference extends Preference {
|
||||||
|
public NumberFormatExamplesPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberFormatExamplesPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberFormatExamplesPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberFormatExamplesPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(JsclMathEngine engine) {
|
||||||
|
final StringBuilder examples = new StringBuilder();
|
||||||
|
examples.append(" 1/3 = ").append(engine.format(1d / 3)).append("\n");
|
||||||
|
examples.append(" √2 = ").append(engine.format(Math.sqrt(2d))).append("\n");
|
||||||
|
examples.append("\n");
|
||||||
|
examples.append(" 1000 = ").append(engine.format(1000d)).append("\n");
|
||||||
|
examples.append(" 1000000 = ").append(engine.format(1000000d)).append("\n");
|
||||||
|
examples.append(" 11^10 = ").append(engine.format(Math.pow(11d, 10))).append("\n");
|
||||||
|
examples.append(" 10^24 = ").append(engine.format(Math.pow(10d, 24))).append("\n");
|
||||||
|
examples.append("\n");
|
||||||
|
examples.append(" 0.001 = ").append(engine.format(0.001d)).append("\n");
|
||||||
|
examples.append("0.000001 = ").append(engine.format(0.000001d)).append("\n");
|
||||||
|
examples.append(" 11^−10 = ").append(engine.format(Math.pow(11d, -10))).append("\n");
|
||||||
|
examples.append(" 10^−24 = ").append(engine.format(Math.pow(10d, -24)));
|
||||||
|
setSummary(examples);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View onCreateView(ViewGroup parent) {
|
||||||
|
final View view = super.onCreateView(parent);
|
||||||
|
final View summary = view.findViewById(android.R.id.summary);
|
||||||
|
if (summary instanceof TextView) {
|
||||||
|
final TextView textView = (TextView) summary;
|
||||||
|
textView.setMaxLines(12);
|
||||||
|
textView.setLines(12);
|
||||||
|
textView.setTypeface(Typeface.MONOSPACE);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
@ -1,119 +0,0 @@
|
|||||||
package org.solovyev.android.calculator.preferences;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.preference.DialogPreference;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
|
|
||||||
import org.solovyev.android.calculator.App;
|
|
||||||
import org.solovyev.android.calculator.Engine;
|
|
||||||
import org.solovyev.android.calculator.Named;
|
|
||||||
import org.solovyev.android.calculator.R;
|
|
||||||
import org.solovyev.android.calculator.text.NaturalComparator;
|
|
||||||
import org.solovyev.android.views.DiscreteSeekBar;
|
|
||||||
import org.solovyev.common.NumberFormatter;
|
|
||||||
|
|
||||||
import butterknife.Bind;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
|
|
||||||
import static org.solovyev.android.calculator.Engine.Preferences.Output;
|
|
||||||
|
|
||||||
public class NumberFormatPreference extends DialogPreference {
|
|
||||||
@Bind(R.id.nf_notation_spinner)
|
|
||||||
Spinner notationSpinner;
|
|
||||||
ArrayAdapter<Named<Engine.Notation>> notationAdapter;
|
|
||||||
@Bind(R.id.nf_precision_seekbar)
|
|
||||||
DiscreteSeekBar precisionSeekBar;
|
|
||||||
@Bind(R.id.nf_separator_spinner)
|
|
||||||
Spinner separatorSpinner;
|
|
||||||
ArrayAdapter<Named<Character>> separatorAdapter;
|
|
||||||
|
|
||||||
{
|
|
||||||
setPersistent(false);
|
|
||||||
setDialogLayoutResource(R.layout.preference_number_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public NumberFormatPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberFormatPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberFormatPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
public NumberFormatPreference(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onBindDialogView(View view) {
|
|
||||||
super.onBindDialogView(view);
|
|
||||||
ButterKnife.bind(this, view);
|
|
||||||
|
|
||||||
final SharedPreferences preferences = getSharedPreferences();
|
|
||||||
precisionSeekBar.setMax(NumberFormatter.MAX_PRECISION);
|
|
||||||
precisionSeekBar.setCurrentTick(Math.max(0, Math.min(NumberFormatter.MAX_PRECISION, Output.precision.getPreference(preferences))));
|
|
||||||
notationAdapter = makeNotationAdapter();
|
|
||||||
notationSpinner.setAdapter(notationAdapter);
|
|
||||||
notationSpinner.setSelection(indexOf(notationAdapter, Output.notation.getPreference(preferences)));
|
|
||||||
|
|
||||||
separatorAdapter = makeSeparatorAdapter();
|
|
||||||
separatorSpinner.setAdapter(separatorAdapter);
|
|
||||||
separatorSpinner.setSelection(indexOf(separatorAdapter, Output.separator.getPreference(preferences)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDialogClosed(boolean save) {
|
|
||||||
super.onDialogClosed(save);
|
|
||||||
if (!save) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final SharedPreferences.Editor editor = getSharedPreferences().edit();
|
|
||||||
Output.precision.putPreference(editor, precisionSeekBar.getCurrentTick());
|
|
||||||
Output.notation.putPreference(editor, notationAdapter.getItem(notationSpinner.getSelectedItemPosition()).item);
|
|
||||||
Output.separator.putPreference(editor, separatorAdapter.getItem(separatorSpinner.getSelectedItemPosition()).item);
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> int indexOf(ArrayAdapter<Named<T>> adapter, T item) {
|
|
||||||
for (int i = 0; i < adapter.getCount(); i++) {
|
|
||||||
if (adapter.getItem(i).item.equals(item)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private ArrayAdapter<Named<Engine.Notation>> makeNotationAdapter() {
|
|
||||||
final Context context = getContext();
|
|
||||||
final ArrayAdapter<Named<Engine.Notation>> adapter = App.makeSimpleSpinnerAdapter(context);
|
|
||||||
for (Engine.Notation notation : Engine.Notation.values()) {
|
|
||||||
adapter.add(Named.create(notation, notation.name, context));
|
|
||||||
}
|
|
||||||
adapter.sort(NaturalComparator.INSTANCE);
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private ArrayAdapter<Named<Character>> makeSeparatorAdapter() {
|
|
||||||
final Context context = getContext();
|
|
||||||
final ArrayAdapter<Named<Character>> adapter = App.makeSimpleSpinnerAdapter(context);
|
|
||||||
adapter.add(Named.create(NumberFormatter.NO_GROUPING, R.string.p_grouping_separator_no, context));
|
|
||||||
adapter.add(Named.create('\'', R.string.p_grouping_separator_apostrophe, context));
|
|
||||||
adapter.add(Named.create(' ', R.string.p_grouping_separator_space, context));
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
package org.solovyev.android.calculator.preferences;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.preference.DialogPreference;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import butterknife.Bind;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import org.solovyev.android.calculator.Engine;
|
||||||
|
import org.solovyev.android.calculator.R;
|
||||||
|
import org.solovyev.android.views.DiscreteSeekBar;
|
||||||
|
|
||||||
|
import static org.solovyev.common.NumberFormatter.MAX_PRECISION;
|
||||||
|
import static org.solovyev.common.NumberFormatter.MIN_PRECISION;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class PrecisionPreference extends DialogPreference {
|
||||||
|
|
||||||
|
@Bind(R.id.precision_seekbar)
|
||||||
|
DiscreteSeekBar seekBar;
|
||||||
|
|
||||||
|
{
|
||||||
|
setPersistent(false);
|
||||||
|
setDialogLayoutResource(R.layout.preference_precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public PrecisionPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrecisionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrecisionPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public PrecisionPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindDialogView(View view) {
|
||||||
|
super.onBindDialogView(view);
|
||||||
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
final SharedPreferences preferences = getSharedPreferences();
|
||||||
|
seekBar.setMax(MAX_PRECISION - 1);
|
||||||
|
final int precision = Math.max(MIN_PRECISION, Math.min(MAX_PRECISION, Engine.Preferences.Output.precision.getPreference(preferences)));
|
||||||
|
seekBar.setCurrentTick(precision - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDialogClosed(boolean save) {
|
||||||
|
super.onDialogClosed(save);
|
||||||
|
if (!save) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int precision = seekBar.getCurrentTick() + 1;
|
||||||
|
if (callChangeListener(precision)) {
|
||||||
|
final SharedPreferences.Editor editor = getSharedPreferences().edit();
|
||||||
|
Engine.Preferences.Output.precision.putPreference(editor, precision);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
preferenceDefs.append(R.xml.preferences, new PrefDef("screen-main", R.string.cpp_settings));
|
preferenceDefs.append(R.xml.preferences, new PrefDef("screen-main", R.string.cpp_settings));
|
||||||
|
preferenceDefs.append(R.xml.preferences_number_format, new PrefDef("screen-number-format", R.string.c_prefs_calculations_category));
|
||||||
preferenceDefs.append(R.xml.preferences_calculations, new PrefDef("screen-calculations", R.string.c_prefs_calculations_category));
|
preferenceDefs.append(R.xml.preferences_calculations, new PrefDef("screen-calculations", R.string.c_prefs_calculations_category));
|
||||||
preferenceDefs.append(R.xml.preferences_appearance, new PrefDef("screen-appearance", R.string.c_prefs_appearance_category));
|
preferenceDefs.append(R.xml.preferences_appearance, new PrefDef("screen-appearance", R.string.c_prefs_appearance_category));
|
||||||
preferenceDefs.append(R.xml.preferences_other, new PrefDef("screen-other", R.string.c_prefs_other_category));
|
preferenceDefs.append(R.xml.preferences_other, new PrefDef("screen-other", R.string.c_prefs_other_category));
|
||||||
|
@ -11,8 +11,11 @@ import android.support.v4.app.FragmentActivity;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
import com.squareup.otto.Bus;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
import jscl.JsclMathEngine;
|
||||||
import org.solovyev.android.calculator.AdView;
|
import org.solovyev.android.calculator.AdView;
|
||||||
|
import org.solovyev.android.calculator.Engine;
|
||||||
import org.solovyev.android.calculator.Preferences;
|
import org.solovyev.android.calculator.Preferences;
|
||||||
import org.solovyev.android.calculator.Preferences.Gui.Theme;
|
import org.solovyev.android.calculator.Preferences.Gui.Theme;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
@ -22,14 +25,15 @@ import org.solovyev.android.checkout.BillingRequests;
|
|||||||
import org.solovyev.android.checkout.Checkout;
|
import org.solovyev.android.checkout.Checkout;
|
||||||
import org.solovyev.android.checkout.ProductTypes;
|
import org.solovyev.android.checkout.ProductTypes;
|
||||||
import org.solovyev.android.checkout.RequestListener;
|
import org.solovyev.android.checkout.RequestListener;
|
||||||
|
import org.solovyev.android.prefs.StringPreference;
|
||||||
import org.solovyev.android.wizard.Wizards;
|
import org.solovyev.android.wizard.Wizards;
|
||||||
|
import org.solovyev.common.text.CharacterMapper;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.solovyev.android.calculator.App.cast;
|
import static org.solovyev.android.calculator.App.cast;
|
||||||
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
|
import static org.solovyev.android.calculator.wizard.CalculatorWizards.DEFAULT_WIZARD_FLOW;
|
||||||
@ -48,11 +52,15 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
Languages languages;
|
Languages languages;
|
||||||
@Inject
|
@Inject
|
||||||
Wizards wizards;
|
Wizards wizards;
|
||||||
|
@Inject
|
||||||
|
JsclMathEngine engine;
|
||||||
|
@Inject
|
||||||
|
Bus bus;
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static PreferencesFragment create(int preferencesResId, int layoutResId) {
|
public static PreferencesFragment create(int preferences, int layout) {
|
||||||
final PreferencesFragment fragment = new PreferencesFragment();
|
final PreferencesFragment fragment = new PreferencesFragment();
|
||||||
fragment.setArguments(createArguments(preferencesResId, layoutResId, NO_THEME));
|
fragment.setArguments(createArguments(preferences, layout, NO_THEME));
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +70,7 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
cast(this).getComponent().inject(this);
|
cast(this).getComponent().inject(this);
|
||||||
|
|
||||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
|
bus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPreferenceIntent(int xml, @Nonnull PreferencesActivity.PrefDef def) {
|
private void setPreferenceIntent(int xml, @Nonnull PreferencesActivity.PrefDef def) {
|
||||||
@ -108,6 +117,11 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if (preference == R.xml.preferences_number_format) {
|
||||||
|
prepareListPreference(Engine.Preferences.Output.notation, Engine.Notation.class);
|
||||||
|
preparePrecisionPreference();
|
||||||
|
prepareSeparatorPreference();
|
||||||
|
prepareNumberFormatExamplesPreference();
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareLanguagePreference(preference);
|
prepareLanguagePreference(preference);
|
||||||
@ -136,6 +150,73 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prepareNumberFormatExamplesPreference() {
|
||||||
|
final NumberFormatExamplesPreference preference = (NumberFormatExamplesPreference) preferenceManager.findPreference("numberFormat.examples");
|
||||||
|
if (preference == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
preference.update(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareSeparatorPreference() {
|
||||||
|
final ListPreference preference = (ListPreference) preferenceManager.findPreference(Engine.Preferences.Output.separator.getKey());
|
||||||
|
preference.setSummary(separatorName(Engine.Preferences.Output.separator.getPreference(preferences)));
|
||||||
|
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference p, Object newValue) {
|
||||||
|
preference.setSummary(separatorName(CharacterMapper.INSTANCE.parseValue(String.valueOf(newValue))));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int separatorName(char separator) {
|
||||||
|
switch (separator) {
|
||||||
|
case '\'':
|
||||||
|
return R.string.p_grouping_separator_apostrophe;
|
||||||
|
case ' ':
|
||||||
|
return R.string.p_grouping_separator_space;
|
||||||
|
case 0:
|
||||||
|
return R.string.p_grouping_separator_no;
|
||||||
|
}
|
||||||
|
return R.string.p_grouping_separator_no;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preparePrecisionPreference() {
|
||||||
|
final PrecisionPreference preference = (PrecisionPreference) preferenceManager.findPreference(Engine.Preferences.Output.precision.getKey());
|
||||||
|
preference.setSummary(String.valueOf(Engine.Preferences.Output.precision.getPreference(preferences)));
|
||||||
|
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference p, Object newValue) {
|
||||||
|
preference.setSummary(String.valueOf(newValue));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private <E extends Enum<E> & PreferenceEntry> void prepareListPreference(@Nonnull final StringPreference<E> p, @Nonnull Class<E> type) {
|
||||||
|
final ListPreference preference = (ListPreference) preferenceManager.findPreference(p.getKey());
|
||||||
|
if (preference == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final E[] entries = type.getEnumConstants();
|
||||||
|
final FragmentActivity activity = getActivity();
|
||||||
|
populate(preference, entries);
|
||||||
|
preference.setSummary(p.getPreference(preferences).getName(activity));
|
||||||
|
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference p, Object newValue) {
|
||||||
|
for (E entry : entries) {
|
||||||
|
if (entry.getId().equals(newValue)) {
|
||||||
|
preference.setSummary(entry.getName(activity));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void prepareLayoutPreference(int preference) {
|
private void prepareLayoutPreference(int preference) {
|
||||||
if (preference != R.xml.preferences_appearance) {
|
if (preference != R.xml.preferences_appearance) {
|
||||||
return;
|
return;
|
||||||
@ -220,6 +301,11 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onEngineChanged(Engine.ChangedEvent e) {
|
||||||
|
prepareNumberFormatExamplesPreference();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
@ -246,6 +332,7 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
bus.unregister(this);
|
||||||
preferences.unregisterOnSharedPreferenceChangeListener(this);
|
preferences.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,11 @@ public final class StringPreference<T> extends AbstractPreference<T> {
|
|||||||
return new StringPreference<T>(key, mapper.parseValue(defaultValue), mapper);
|
return new StringPreference<T>(key, mapper.parseValue(defaultValue), mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static <T> StringPreference<T> ofTypedValue(@Nonnull String key, @Nullable T defaultValue, @Nonnull Mapper<T> mapper) {
|
||||||
|
return new StringPreference<T>(key, defaultValue, mapper);
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static <T extends Enum> StringPreference<T> ofEnum(@Nonnull String key, @Nullable T defaultValue, @Nonnull Class<T> enumType) {
|
public static <T extends Enum> StringPreference<T> ofEnum(@Nonnull String key, @Nullable T defaultValue, @Nonnull Class<T> enumType) {
|
||||||
return new StringPreference<T>(key, defaultValue, EnumMapper.of(enumType));
|
return new StringPreference<T>(key, defaultValue, EnumMapper.of(enumType));
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package org.solovyev.common.text;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class CharacterMapper implements Mapper<Character> {
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static final CharacterMapper INSTANCE = new CharacterMapper();
|
||||||
|
|
||||||
|
private CharacterMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String formatValue(@Nullable Character value) throws IllegalArgumentException {
|
||||||
|
return value == null || value == 0 ? "" : String.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Character parseValue(@Nullable String value) throws IllegalArgumentException {
|
||||||
|
return TextUtils.isEmpty(value) ? 0 : value.charAt(0);
|
||||||
|
}
|
||||||
|
}
|
@ -1,45 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="@dimen/cpp_dialog_spacing">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/CppLabel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Notation"/>
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/nf_notation_spinner"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/CppLabel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Precision"/>
|
|
||||||
|
|
||||||
<org.solovyev.android.views.DiscreteSeekBar
|
|
||||||
android:id="@+id/nf_precision_seekbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:labelsColor="?android:attr/textColorSecondary"
|
|
||||||
app:labelsSize="12sp"
|
|
||||||
app:values="@array/cpp_prefs_precisions"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="@style/CppLabel"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Separator"/>
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/nf_separator_spinner"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
11
app/src/main/res/layout/preference_precision.xml
Normal file
11
app/src/main/res/layout/preference_precision.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<org.solovyev.android.views.DiscreteSeekBar android:id="@+id/precision_seekbar"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="@dimen/cpp_dialog_spacing"
|
||||||
|
app:labelsColor="?android:attr/textColorSecondary"
|
||||||
|
app:labelsSize="12sp"
|
||||||
|
app:values="@array/cpp_prefs_precisions" />
|
@ -18,7 +18,6 @@
|
|||||||
<string name="cpp_exponent" translatable="false">E</string>
|
<string name="cpp_exponent" translatable="false">E</string>
|
||||||
<string name="cpp_theme_black" translatable="false">%1$s (AMOLED)</string>
|
<string name="cpp_theme_black" translatable="false">%1$s (AMOLED)</string>
|
||||||
<string-array name="cpp_prefs_precisions" translatable="false">
|
<string-array name="cpp_prefs_precisions" translatable="false">
|
||||||
<item>0</item>
|
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
a:key="restart_wizard"
|
a:key="restart_wizard"
|
||||||
a:title="@string/cpp_restart_wizard" />
|
a:title="@string/cpp_restart_wizard" />
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
a:key="screen-number-format"
|
||||||
|
a:title="Number format" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
a:key="screen-calculations"
|
a:key="screen-calculations"
|
||||||
a:title="@string/c_prefs_calculations_category" />
|
a:title="@string/c_prefs_calculations_category" />
|
||||||
|
@ -24,30 +24,6 @@
|
|||||||
|
|
||||||
<PreferenceScreen xmlns:a="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:a="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<org.solovyev.android.calculator.preferences.NumberFormatPreference
|
|
||||||
a:key="engine.output.numberFormat"
|
|
||||||
a:title="Number format" />
|
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
a:entries="@array/cpp_prefs_precisions"
|
|
||||||
a:entryValues="@array/cpp_prefs_precisions"
|
|
||||||
a:key="engine.output.precision"
|
|
||||||
a:summary="@string/c_calc_result_precision_summary"
|
|
||||||
a:title="@string/p_calc_result_precision_title" />
|
|
||||||
|
|
||||||
<android.preference.CheckBoxPreference
|
|
||||||
a:defaultValue="false"
|
|
||||||
a:key="engine.output.scientificNotation"
|
|
||||||
a:summary="@string/c_calc_science_notation_summary"
|
|
||||||
a:title="@string/c_calc_science_notation_title" />
|
|
||||||
|
|
||||||
<ListPreference
|
|
||||||
a:entries="@array/p_grouping_separator_names"
|
|
||||||
a:entryValues="@array/p_grouping_separator_values"
|
|
||||||
a:key="engine.groupingSeparator"
|
|
||||||
a:summary="@string/c_calc_grouping_separator_summary"
|
|
||||||
a:title="@string/c_calc_grouping_separator" />
|
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
a:entries="@array/p_angle_units_names"
|
a:entries="@array/p_angle_units_names"
|
||||||
a:entryValues="@array/p_angle_units"
|
a:entryValues="@array/p_angle_units"
|
||||||
|
49
app/src/main/res/xml/preferences_number_format.xml
Normal file
49
app/src/main/res/xml/preferences_number_format.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ Copyright 2016 serso aka se.solovyev
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
~
|
||||||
|
~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
~ Contact details
|
||||||
|
~
|
||||||
|
~ Email: se.solovyev@gmail.com
|
||||||
|
~ Site: http://se.solovyev.org
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:m="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<org.solovyev.android.material.preferences.ListPreference
|
||||||
|
a:key="engine.output.notation"
|
||||||
|
a:title="Notation"
|
||||||
|
m:materialColor="@color/material_text_selector" />
|
||||||
|
|
||||||
|
<org.solovyev.android.calculator.preferences.PrecisionPreference
|
||||||
|
a:key="engine.output.precision"
|
||||||
|
a:title="@string/p_calc_result_precision_title" />
|
||||||
|
|
||||||
|
<org.solovyev.android.material.preferences.ListPreference
|
||||||
|
a:entries="@array/p_grouping_separator_names"
|
||||||
|
a:entryValues="@array/p_grouping_separator_values"
|
||||||
|
a:key="engine.output.separator"
|
||||||
|
a:title="@string/c_calc_grouping_separator"
|
||||||
|
m:materialColor="@color/material_text_selector" />
|
||||||
|
|
||||||
|
<org.solovyev.android.calculator.preferences.NumberFormatExamplesPreference
|
||||||
|
a:key="numberFormat.examples"
|
||||||
|
a:selectable="false"
|
||||||
|
a:title="Examples" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
@ -14,6 +14,7 @@ public class NumberFormatter {
|
|||||||
public static final char NO_GROUPING = 0;
|
public static final char NO_GROUPING = 0;
|
||||||
public static final int NO_ROUNDING = -1;
|
public static final int NO_ROUNDING = -1;
|
||||||
public static final int DEFAULT_MAGNITUDE = 5;
|
public static final int DEFAULT_MAGNITUDE = 5;
|
||||||
|
public static final int MIN_PRECISION = 1;
|
||||||
public static final int MAX_PRECISION = 15;
|
public static final int MAX_PRECISION = 15;
|
||||||
|
|
||||||
private final Real.NumberFormat numberFormat = new Real.NumberFormat();
|
private final Real.NumberFormat numberFormat = new Real.NumberFormat();
|
||||||
@ -39,7 +40,7 @@ public class NumberFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setPrecision(int precision) {
|
public void setPrecision(int precision) {
|
||||||
this.precision = precision;
|
this.precision = Math.max(MIN_PRECISION, Math.min(precision, MAX_PRECISION));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroupingSeparator(char groupingSeparator) {
|
public void setGroupingSeparator(char groupingSeparator) {
|
||||||
|
Loading…
Reference in New Issue
Block a user