From 5233ba9e18fa64103f33908c10ca88d32cadb1da Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Thu, 22 Dec 2011 01:53:39 +0400 Subject: [PATCH] math entities list activities refactored + categories added --- AndroidManifest.xml | 12 +- res/layout/history_tabs.xml | 30 -- .../{functions.xml => math_entities.xml} | 0 res/layout/{var.xml => math_entity.xml} | 8 +- res/layout/operators.xml | 20 - res/layout/tabs.xml | 30 ++ res/values-hdpi/styles.xml | 4 +- res/values-ldpi/styles.xml | 4 +- res/values-mdpi/styles.xml | 4 +- res/values/strings.xml | 9 + res/values/styles-common-history.xml | 6 +- res/values/styles-common-var.xml | 4 +- res/values/styles.xml | 4 +- .../AbstractMathEntityListActivity.java | 213 +++++++++ .../CalculatorActivityLauncher.java | 4 +- .../CalculatorFunctionsActivity.java | 109 +---- .../CalculatorFunctionsTabActivity.java | 39 ++ .../CalculatorOperatorsActivity.java | 130 ++---- .../calculator/CalculatorVarsActivity.java | 419 +----------------- .../calculator/CalculatorVarsTabActivity.java | 375 ++++++++++++++++ .../history/CalculatorHistoryActivity.java | 7 +- .../model/AndroidFunctionsMathRegistry.java | 91 +++- .../calculator/model/AndroidMathRegistry.java | 6 +- .../model/AndroidMathRegistryImpl.java | 6 +- .../model/AndroidOperatorsMathRegistry.java | 5 + .../AndroidPostfixFunctionsRegistry.java | 5 + .../calculator/model/AndroidVarsRegistry.java | 55 ++- .../model/AndroidVarsRegistryImpl.java | 21 + .../android/view/prefs/AndroidUtils.java | 55 +++ 29 files changed, 1012 insertions(+), 663 deletions(-) delete mode 100644 res/layout/history_tabs.xml rename res/layout/{functions.xml => math_entities.xml} (100%) rename res/layout/{var.xml => math_entity.xml} (80%) delete mode 100644 res/layout/operators.xml create mode 100644 res/layout/tabs.xml create mode 100644 src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java create mode 100644 src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java create mode 100644 src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java create mode 100644 src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 797a07ac..0428df4f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -61,7 +61,11 @@ a:label="@string/c_help" a:configChanges="orientation|keyboardHidden"/> - + + @@ -69,7 +73,11 @@ a:label="@string/c_operators" a:configChanges="orientation|keyboardHidden"/> - + + diff --git a/res/layout/history_tabs.xml b/res/layout/history_tabs.xml deleted file mode 100644 index d25fabe6..00000000 --- a/res/layout/history_tabs.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/functions.xml b/res/layout/math_entities.xml similarity index 100% rename from res/layout/functions.xml rename to res/layout/math_entities.xml diff --git a/res/layout/var.xml b/res/layout/math_entity.xml similarity index 80% rename from res/layout/var.xml rename to res/layout/math_entity.xml index 0a07b948..a9445603 100644 --- a/res/layout/var.xml +++ b/res/layout/math_entity.xml @@ -16,18 +16,18 @@ a:layout_width="fill_parent" a:layout_height="fill_parent"> - + style="@style/math_entity_text"> - + style="@style/math_entity_description"> \ No newline at end of file diff --git a/res/layout/operators.xml b/res/layout/operators.xml deleted file mode 100644 index c0165d13..00000000 --- a/res/layout/operators.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/res/layout/tabs.xml b/res/layout/tabs.xml new file mode 100644 index 00000000..9f4c04f3 --- /dev/null +++ b/res/layout/tabs.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values-hdpi/styles.xml b/res/values-hdpi/styles.xml index 276197f4..42bdf52f 100644 --- a/res/values-hdpi/styles.xml +++ b/res/values-hdpi/styles.xml @@ -30,11 +30,11 @@ 5dp - - diff --git a/res/values-ldpi/styles.xml b/res/values-ldpi/styles.xml index 0b4b67f4..235261a5 100644 --- a/res/values-ldpi/styles.xml +++ b/res/values-ldpi/styles.xml @@ -30,11 +30,11 @@ 5dp - - diff --git a/res/values-mdpi/styles.xml b/res/values-mdpi/styles.xml index d9050a1c..0b1db34f 100644 --- a/res/values-mdpi/styles.xml +++ b/res/values-mdpi/styles.xml @@ -30,11 +30,11 @@ 5dp - - diff --git a/res/values/strings.xml b/res/values/strings.xml index d013d627..b4514aba 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -321,4 +321,13 @@ Check the \'Round result\' preference in application settings - it should be tur History was successfully removed! History was successfully saved! + + Trigonometric + Hyperbolic trigonometric + Comparison + Common + + System + My + diff --git a/res/values/styles-common-history.xml b/res/values/styles-common-history.xml index 0ff121d6..f39a28ac 100644 --- a/res/values/styles-common-history.xml +++ b/res/values/styles-common-history.xml @@ -6,10 +6,10 @@ - diff --git a/res/values/styles-common-var.xml b/res/values/styles-common-var.xml index 195a9db9..ecbc45d1 100644 --- a/res/values/styles-common-var.xml +++ b/res/values/styles-common-var.xml @@ -7,7 +7,7 @@ - - - - diff --git a/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java b/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java new file mode 100644 index 00000000..011ad936 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/AbstractMathEntityListActivity.java @@ -0,0 +1,213 @@ +/* + * 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.calculator; + +import android.app.Activity; +import android.app.ListActivity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.model.AndroidMathRegistry; +import org.solovyev.common.math.MathEntity; +import org.solovyev.common.utils.EqualsTool; +import org.solovyev.common.utils.Filter; +import org.solovyev.common.utils.FilterRule; +import org.solovyev.common.utils.StringUtils; + +import java.util.Comparator; +import java.util.List; + +/** + * User: serso + * Date: 12/21/11 + * Time: 9:24 PM + */ +public abstract class AbstractMathEntityListActivity extends ListActivity { + + public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category"; + + @NotNull + private MathEntityArrayAdapter adapter; + + @Nullable + private String category; + + static void createTab(@NotNull Context context, + @NotNull TabHost tabHost, + @NotNull String tabId, + @NotNull String categoryId, + int tabCaptionId, + @NotNull Class activityClass, + @Nullable Intent parentIntent) { + + TabHost.TabSpec spec; + + final Intent intent; + if (parentIntent != null) { + intent = new Intent(parentIntent); + } else { + intent = new Intent(); + } + intent.setClass(context, activityClass); + intent.putExtra(MATH_ENTITY_CATEGORY_EXTRA_STRING, categoryId); + + // Initialize a TabSpec for each tab and add it to the TabHost + spec = tabHost.newTabSpec(tabId).setIndicator(context.getString(tabCaptionId)).setContent(intent); + + tabHost.addTab(spec); + } + + protected int getLayoutId() { + return R.layout.math_entities; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(getLayoutId()); + + final Intent intent = getIntent(); + if ( intent != null ) { + category = intent.getStringExtra(MATH_ENTITY_CATEGORY_EXTRA_STRING); + } + + final ListView lv = getListView(); + lv.setTextFilterEnabled(true); + + lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(final AdapterView parent, + final View view, + final int position, + final long id) { + + CalculatorModel.instance.processDigitButtonAction(((MathEntity) parent.getItemAtPosition(position)).getName(), false); + + AbstractMathEntityListActivity.this.finish(); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + + adapter = new MathEntityArrayAdapter(getDescriptionGetter(), this, R.layout.math_entity, R.id.math_entity_text, getMathEntitiesByCategory()); + setListAdapter(adapter); + + sort(); + } + + @NotNull + private List getMathEntitiesByCategory() { + final List result = getMathEntities(); + + new Filter(new FilterRule() { + @Override + public boolean isFiltered(T t) { + return !isInCategory(t); + } + }).filter(result.iterator()); + + return result; + } + + protected boolean isInCategory(@Nullable T t) { + return t != null && EqualsTool.areEqual(getMathEntityCategory(t), category); + } + + @NotNull + protected MathEntityArrayAdapter getAdapter() { + return adapter; + } + + @NotNull + protected abstract MathEntityDescriptionGetter getDescriptionGetter(); + + @NotNull + protected abstract List getMathEntities(); + + @Nullable + protected abstract String getMathEntityCategory(@NotNull T t); + + protected void sort() { + AbstractMathEntityListActivity.this.adapter.sort(new Comparator() { + @Override + public int compare(T function1, T function2) { + return function1.getName().compareTo(function2.getName()); + } + }); + + AbstractMathEntityListActivity.this.adapter.notifyDataSetChanged(); + } + + protected static class MathEntityArrayAdapter extends ArrayAdapter { + + @NotNull + private final MathEntityDescriptionGetter descriptionGetter; + + private MathEntityArrayAdapter(@NotNull MathEntityDescriptionGetter descriptionGetter, @NotNull Context context, int resource, int textViewResourceId, @NotNull List objects) { + super(context, resource, textViewResourceId, objects); + this.descriptionGetter = descriptionGetter; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent); + + final T mathEntity = getItem(position); + + final String mathEntityDescription = descriptionGetter.getDescription(getContext(), mathEntity.getName()); + if (!StringUtils.isEmpty(mathEntityDescription)) { + TextView description = (TextView) result.findViewById(R.id.math_entity_description); + if (description == null) { + final LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(LAYOUT_INFLATER_SERVICE); + final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.math_entity, null); + description = (TextView) itemView.findViewById(R.id.math_entity_description); + itemView.removeView(description); + result.addView(description); + } + description.setText(mathEntityDescription); + } else { + TextView description = (TextView) result.findViewById(R.id.math_entity_description); + if (description != null) { + result.removeView(description); + } + } + + + return result; + } + } + + protected static class MathEntityDescriptionGetterImpl implements MathEntityDescriptionGetter { + + @NotNull + private final AndroidMathRegistry mathRegistry; + + public MathEntityDescriptionGetterImpl(@NotNull AndroidMathRegistry mathRegistry) { + this.mathRegistry = mathRegistry; + } + + @Override + public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { + return this.mathRegistry.getDescription(context, mathEntityName); + } + } + + protected static interface MathEntityDescriptionGetter { + + @Nullable + String getDescription(@NotNull Context context, @NotNull String mathEntityName); + } +} diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index a0a66435..fe2bd3ad 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -58,9 +58,9 @@ public class CalculatorActivityLauncher { if (calculatorModel.getDisplay().isValid() ) { final String varValue = calculatorModel.getDisplay().getText().toString(); if (!StringUtils.isEmpty(varValue)) { - if (CalculatorVarsActivity.isValidValue(varValue)) { + if (CalculatorVarsTabActivity.isValidValue(varValue)) { final Intent intent = new Intent(context, CalculatorVarsActivity.class); - intent.putExtra(CalculatorVarsActivity.CREATE_VAR_EXTRA_STRING, varValue); + intent.putExtra(CalculatorVarsTabActivity.CREATE_VAR_EXTRA_STRING, varValue); context.startActivity(intent); } else { Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show(); diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java index 819ada86..e971c3dc 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsActivity.java @@ -6,106 +6,33 @@ package org.solovyev.android.calculator; -import android.app.ListActivity; -import android.content.Context; +import android.app.TabActivity; import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.*; -import jscl.math.function.Function; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.model.Var; -import org.solovyev.common.utils.StringUtils; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; +import android.widget.TabHost; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.model.AndroidFunctionsMathRegistry; +import org.solovyev.android.view.prefs.AndroidUtils; /** * User: serso - * Date: 10/29/11 - * Time: 4:55 PM + * Date: 12/21/11 + * Time: 10:33 PM */ -public class CalculatorFunctionsActivity extends ListActivity { +public class CalculatorFunctionsActivity extends TabActivity { - @NotNull - private FunctionsArrayAdapter adapter; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + setContentView(R.layout.tabs); - setContentView(R.layout.functions); + final TabHost tabHost = getTabHost(); - adapter = new FunctionsArrayAdapter(this, R.layout.var, R.id.var_text, new ArrayList(CalculatorEngine.instance.getFunctionsRegistry().getEntities())); - setListAdapter(adapter); - - final ListView lv = getListView(); - lv.setTextFilterEnabled(true); - - lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(final AdapterView parent, - final View view, - final int position, - final long id) { - - CalculatorModel.instance.processDigitButtonAction(((Function) parent.getItemAtPosition(position)).getName(), false); - - CalculatorFunctionsActivity.this.finish(); - } - }); - - sort(); - - } - - private void sort() { - CalculatorFunctionsActivity.this.adapter.sort(new Comparator() { - @Override - public int compare(Function function1, Function function2) { - return function1.getName().compareTo(function2.getName()); - } - }); - - CalculatorFunctionsActivity.this.adapter.notifyDataSetChanged(); - } - - private class FunctionsArrayAdapter extends ArrayAdapter { - - private FunctionsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) { - super(context, resource, textViewResourceId, objects); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent); - - final Function function = getItem(position); - - final String functionDescription = CalculatorEngine.instance.getFunctionsRegistry().getDescription(getContext(), function.getName()); - if (!StringUtils.isEmpty(functionDescription)) { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description == null) { - final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); - final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null); - description = (TextView) itemView.findViewById(R.id.var_description); - itemView.removeView(description); - result.addView(description); - } - description.setText(functionDescription); - } else { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description != null) { - result.removeView(description); - } - } - - - return result; - } - } + for (AndroidFunctionsMathRegistry.Category category : AndroidFunctionsMathRegistry.Category.getCategoriesByTabOrder()) { + AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorFunctionsTabActivity.class, null); + } + AndroidUtils.centerAndWrapTabsFor(tabHost); + } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java new file mode 100644 index 00000000..79dce327 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/CalculatorFunctionsTabActivity.java @@ -0,0 +1,39 @@ +/* + * 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.calculator; + +import jscl.math.function.Function; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.model.CalculatorEngine; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 10/29/11 + * Time: 4:55 PM + */ +public class CalculatorFunctionsTabActivity extends AbstractMathEntityListActivity { + + @NotNull + @Override + protected MathEntityDescriptionGetter getDescriptionGetter() { + return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getFunctionsRegistry()); + } + + @NotNull + @Override + protected List getMathEntities() { + return new ArrayList(CalculatorEngine.instance.getFunctionsRegistry().getEntities()); + } + + @Override + protected String getMathEntityCategory(@NotNull Function function) { + return CalculatorEngine.instance.getFunctionsRegistry().getCategory(function); + } +} diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java index 0003d497..bcec75c0 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorOperatorsActivity.java @@ -1,22 +1,12 @@ package org.solovyev.android.calculator; -import android.app.ListActivity; import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.TextView; import jscl.math.operator.Operator; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.common.utils.StringUtils; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; /** @@ -25,92 +15,48 @@ import java.util.List; * Time: 1:53 PM */ -public class CalculatorOperatorsActivity extends ListActivity { +public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity { - @NotNull - private OperatorsArrayAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.operators); - - List elements = new ArrayList(); - elements.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities()); - elements.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities()); - adapter = new OperatorsArrayAdapter(this, R.layout.var, R.id.var_text, elements); - setListAdapter(adapter); - - final ListView lv = getListView(); - lv.setTextFilterEnabled(true); - - lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(final AdapterView parent, - final View view, - final int position, - final long id) { - - CalculatorModel.instance.processDigitButtonAction(((Operator) parent.getItemAtPosition(position)).getName(), false); - - CalculatorOperatorsActivity.this.finish(); - } - }); - - sort(); - - } - - private void sort() { - CalculatorOperatorsActivity.this.adapter.sort(new Comparator() { - @Override - public int compare(Operator operator1, Operator operator2) { - return operator1.getName().compareTo(operator2.getName()); - } - }); - - CalculatorOperatorsActivity.this.adapter.notifyDataSetChanged(); - } - - private class OperatorsArrayAdapter extends ArrayAdapter { - - private OperatorsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) { - super(context, resource, textViewResourceId, objects); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent); - - final Operator operator = getItem(position); - - String operatorDescription = CalculatorEngine.instance.getOperatorsRegistry().getDescription(getContext(), operator.getName()); - if (StringUtils.isEmpty(operatorDescription)) { - operatorDescription = CalculatorEngine.instance.getPostfixFunctionsRegistry().getDescription(getContext(), operator.getName()); - } - - if (!StringUtils.isEmpty(operatorDescription)) { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description == null) { - final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); - final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null); - description = (TextView) itemView.findViewById(R.id.var_description); - itemView.removeView(description); - result.addView(description); - } - description.setText(operatorDescription); - } else { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description != null) { - result.removeView(description); - } - } + @NotNull + @Override + protected MathEntityDescriptionGetter getDescriptionGetter() { + return new OperatorDescriptionGetter(); + } - return result; - } - } + @NotNull + @Override + protected List getMathEntities() { + final List result = new ArrayList(); + result.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities()); + result.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities()); + + return result; + } + + @Override + protected String getMathEntityCategory(@NotNull Operator operator) { + String result = CalculatorEngine.instance.getOperatorsRegistry().getCategory(operator); + if (result == null) { + result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getCategory(operator); + } + + return result; + } + + private static class OperatorDescriptionGetter implements MathEntityDescriptionGetter { + + @Override + public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { + String result = CalculatorEngine.instance.getOperatorsRegistry().getDescription(context, mathEntityName); + if (StringUtils.isEmpty(result)) { + result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getDescription(context, mathEntityName); + } + + return result; + } + } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java index 1db14da2..3bfb0a7a 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java @@ -6,415 +6,38 @@ package org.solovyev.android.calculator; -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; +import android.app.TabActivity; import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.*; -import android.widget.*; -import jscl.text.Identifier; -import jscl.text.MutableInt; -import jscl.text.ParseException; -import jscl.text.Parser; -import org.jetbrains.annotations.NotNull; +import android.widget.TabHost; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.AndroidVarsRegistry; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.model.Var; -import org.solovyev.common.utils.CollectionsUtils; -import org.solovyev.common.utils.Finder; -import org.solovyev.common.utils.StringUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import org.solovyev.android.view.prefs.AndroidUtils; /** * User: serso - * Date: 9/28/11 - * Time: 10:55 PM + * Date: 12/21/11 + * Time: 11:05 PM */ -public class CalculatorVarsActivity extends ListActivity { +public class CalculatorVarsActivity extends TabActivity { - public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var"; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - private final static List acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray())); + setContentView(R.layout.tabs); - @NotNull - private VarsArrayAdapter adapter; + final TabHost tabHost = getTabHost(); - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + for (AndroidVarsRegistry.Category category : AndroidVarsRegistry.Category.getCategoriesByTabOrder()) { + if (category == AndroidVarsRegistry.Category.my) { + AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, getIntent()); + } else { + AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, null); + } + } - setContentView(R.layout.vars); + tabHost.setCurrentTab(0); + AndroidUtils.centerAndWrapTabsFor(tabHost); + } - final List vars = new ArrayList(CalculatorEngine.instance.getVarsRegister().getEntities()); - CollectionsUtils.removeAll(vars, new Finder() { - @Override - public boolean isFound(@Nullable Var var) { - return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN); - } - }); - adapter = new VarsArrayAdapter(this, R.layout.var, R.id.var_text, vars); - setListAdapter(adapter); - - final ListView lv = getListView(); - lv.setTextFilterEnabled(true); - - - lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - final Var var = (Var) parent.getItemAtPosition(position); - createEditVariableDialog(var, var.getName(), StringUtils.getNotEmpty(var.getValue(), ""), var.getDescription()); - return true; - } - }); - - lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { - public void onItemClick(final AdapterView parent, - final View view, - final int position, - final long id) { - - CalculatorModel.instance.doTextOperation(new CalculatorModel.TextOperation() { - @Override - public void doOperation(@NotNull EditText editor) { - editor.getText().insert(editor.getSelectionStart(), ((Var) parent.getItemAtPosition(position)).getName()); - } - }, false); - - CalculatorVarsActivity.this.finish(); - } - }); - - sort(); - - final Intent intent = getIntent(); - if ( intent != null ) { - final String varValue = intent.getStringExtra(CREATE_VAR_EXTRA_STRING); - if (!StringUtils.isEmpty(varValue)) { - createEditVariableDialog(null, null, varValue, null); - } - } - - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void addVarButtonClickHandler(@NotNull View v) { - createEditVariableDialog(null, null, null, null); - } - - - private void createEditVariableDialog(@Nullable final Var var, @Nullable final String name, @Nullable final String value, @Nullable final String description) { - if (var == null || !var.isSystem()) { - - final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); - final View editView = layoutInflater.inflate(R.layout.var_edit, null); - - final String errorMsg = CalculatorVarsActivity.this.getString(R.string.c_char_is_not_accepted); - - final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); - editName.setText(name); - editName.addTextChangedListener(new TextWatcher() { - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - for ( int i = 0; i < s.length(); i++ ) { - char c = s.charAt(i); - if (!acceptableChars.contains(c)) { - s.delete(i, i+1); - Toast.makeText(CalculatorVarsActivity.this, String.format(errorMsg, c), Toast.LENGTH_SHORT).show(); - } - } - } - }); - - final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); - if (!StringUtils.isEmpty(value)) { - editValue.setText(value); - } - - final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); - editDescription.setText(description); - - final Var.Builder varBuilder; - if (var != null) { - varBuilder = new Var.Builder(var); - } else { - varBuilder = new Var.Builder(); - } - - final AlertDialog.Builder builder = new AlertDialog.Builder(this) - .setCancelable(true) - .setNegativeButton(R.string.c_cancel, null) - .setPositiveButton(R.string.c_save, new VarEditorSaver(varBuilder, var, editView)) - .setView(editView); - - if ( var != null ) { - // EDIT mode - - builder.setTitle(R.string.c_var_edit_var); - builder.setNeutralButton(R.string.c_remove, new VarEditorRemover(var, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - createEditVariableDialog(var, name, value, description); - } - })); - } else { - // CREATE mode - - builder.setTitle(R.string.c_var_create_var); - } - - builder.create().show(); - } else { - Toast.makeText(this, getString(R.string.c_sys_var_cannot_be_changed), Toast.LENGTH_LONG).show(); - } - } - - private class VarEditorSaver implements DialogInterface.OnClickListener { - - @NotNull - private Var.Builder varBuilder; - - @Nullable - private final Var editedInstance; - - @NotNull - private View editView; - - public VarEditorSaver(@NotNull Var.Builder varBuilder, @Nullable Var editedInstance, @NotNull View editView) { - this.varBuilder = varBuilder; - this.editedInstance = editedInstance; - this.editView = editView; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - final Integer error; - - final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); - String name = editName.getText().toString(); - - final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); - String value = editValue.getText().toString(); - - final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); - String description = editDescription.getText().toString(); - - - final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister(); - if (isValidName(name)) { - - boolean canBeSaved = false; - - final Var varFromRegister = varsRegistry.get(name); - if ( varFromRegister == null ) { - canBeSaved = true; - } else if ( editedInstance != null && varFromRegister.getId().equals(editedInstance.getId()) ) { - canBeSaved = true; - } - - if (canBeSaved) { - final MathType.Result mathType = MathType.getType(name, 0, false); - - if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) { - - if (StringUtils.isEmpty(value)) { - // value is empty => undefined variable - varBuilder.setName(name); - varBuilder.setDescription(description); - varBuilder.setValue(null); - error = null; - } else { - // value is not empty => must be a number - boolean valid = isValidValue(value); - - if (valid) { - varBuilder.setName(name); - varBuilder.setDescription(description); - varBuilder.setValue(value); - error = null; - } else { - error = R.string.c_value_is_not_a_number; - } - } - } else { - error = R.string.c_var_name_clashes; - } - } else { - error = R.string.c_var_already_exists; - } - } else { - error = R.string.c_name_is_not_valid; - } - - if (error != null) { - Toast.makeText(CalculatorVarsActivity.this, getString(error), Toast.LENGTH_LONG).show(); - createEditVariableDialog(editedInstance, name, value, description); - } else { - if ( editedInstance == null ) { - CalculatorVarsActivity.this.adapter.add(varsRegistry.add(varBuilder)); - } else { - final Var newInstance = varsRegistry.add(varBuilder); - CalculatorVarsActivity.this.adapter.remove(editedInstance); - CalculatorVarsActivity.this.adapter.add(newInstance); - } - - varsRegistry.save(CalculatorVarsActivity.this); - - sort(); - } - } - } - } - - private void sort() { - CalculatorVarsActivity.this.adapter.sort(new Comparator() { - @Override - public int compare(Var var, Var var1) { - return var.getName().compareTo(var1.getName()); - } - }); - - CalculatorVarsActivity.this.adapter.notifyDataSetChanged(); - } - - private static boolean isValidName(@Nullable String name) { - boolean result = false; - - if (!StringUtils.isEmpty(name)) { - try { - Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null); - result = true; - } catch (ParseException e) { - // not valid name; - } - } - - return result; - } - - public static boolean isValidValue(@NotNull String value) { - // now every string might be constant - return true; - } - - private class VarsArrayAdapter extends ArrayAdapter { - - private VarsArrayAdapter(Context context, int resource, int textViewResourceId, List objects) { - super(context, resource, textViewResourceId, objects); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent); - - final Var var = getItem(position); - - if (!StringUtils.isEmpty(var.getDescription())) { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description == null) { - final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); - final ViewGroup itemView = (ViewGroup) layoutInflater.inflate(R.layout.var, null); - description = (TextView) itemView.findViewById(R.id.var_description); - itemView.removeView(description); - result.addView(description); - } - description.setText(var.getDescription()); - } else { - TextView description = (TextView) result.findViewById(R.id.var_description); - if (description != null) { - result.removeView(description); - } - } - - - return result; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - final MenuInflater menuInflater = getMenuInflater(); - menuInflater.inflate(R.menu.var_menu, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - boolean result; - - switch (item.getItemId()) { - case R.id.var_menu_add_var: - createEditVariableDialog(null, null, null, null); - result = true; - break; - default: - result = super.onOptionsItemSelected(item); - } - - return result; - } - - private class VarEditorRemover implements DialogInterface.OnClickListener { - - @NotNull - private final Var var; - - @Nullable - private final DialogInterface.OnClickListener callbackOnCancel; - - private final boolean confirmed; - - public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel) { - this(var, callbackOnCancel, false); - } - - public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel, boolean confirmed) { - this.var = var; - this.callbackOnCancel = callbackOnCancel; - this.confirmed = confirmed; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if (!confirmed) { - final TextView question = new TextView(CalculatorVarsActivity.this); - question.setText(String.format(getString(R.string.c_var_removal_confirmation_question), var.getName())); - question.setPadding(6, 6, 6, 6); - final AlertDialog.Builder builder = new AlertDialog.Builder(CalculatorVarsActivity.this) - .setCancelable(true) - .setView(question) - .setTitle(R.string.c_var_removal_confirmation) - .setNegativeButton(R.string.c_no, callbackOnCancel) - .setPositiveButton(R.string.c_yes, new VarEditorRemover(var, callbackOnCancel, true)); - - builder.create().show(); - } else { - adapter.remove(var); - final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister(); - varsRegistry.remove(var); - varsRegistry.save(CalculatorVarsActivity.this); - CalculatorVarsActivity.this.adapter.notifyDataSetChanged(); - } - } - } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java new file mode 100644 index 00000000..185bce95 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsTabActivity.java @@ -0,0 +1,375 @@ +/* + * 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.calculator; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.*; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; +import jscl.text.Identifier; +import jscl.text.MutableInt; +import jscl.text.ParseException; +import jscl.text.Parser; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.android.calculator.model.AndroidVarsRegistry; +import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.Var; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.common.utils.Finder; +import org.solovyev.common.utils.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * User: serso + * Date: 9/28/11 + * Time: 10:55 PM + */ +public class CalculatorVarsTabActivity extends AbstractMathEntityListActivity { + + public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var"; + + private final static List acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray())); + + @Override + protected int getLayoutId() { + return R.layout.vars; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + final Var var = (Var) parent.getItemAtPosition(position); + createEditVariableDialog(var, var.getName(), StringUtils.getNotEmpty(var.getValue(), ""), var.getDescription()); + return true; + } + }); + + final Intent intent = getIntent(); + if ( intent != null ) { + final String varValue = intent.getStringExtra(CREATE_VAR_EXTRA_STRING); + if (!StringUtils.isEmpty(varValue)) { + createEditVariableDialog(null, null, varValue, null); + + // in order to stop intent for other tabs + intent.removeExtra(CREATE_VAR_EXTRA_STRING); + } + } + } + + @NotNull + @Override + protected MathEntityDescriptionGetter getDescriptionGetter() { + return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getVarsRegister()); + } + + @SuppressWarnings({"UnusedDeclaration"}) + public void addVarButtonClickHandler(@NotNull View v) { + createEditVariableDialog(null, null, null, null); + } + + @NotNull + @Override + protected List getMathEntities() { + final List result = new ArrayList(CalculatorEngine.instance.getVarsRegister().getEntities()); + + CollectionsUtils.removeAll(result, new Finder() { + @Override + public boolean isFound(@Nullable Var var) { + return var != null && CollectionsUtils.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN); + } + }); + + return result; + } + + @Override + protected String getMathEntityCategory(@NotNull Var var) { + return CalculatorEngine.instance.getVarsRegister().getCategory(var); + } + + private void createEditVariableDialog(@Nullable final Var var, @Nullable final String name, @Nullable final String value, @Nullable final String description) { + if (var == null || !var.isSystem()) { + + final LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); + final View editView = layoutInflater.inflate(R.layout.var_edit, null); + + final String errorMsg = CalculatorVarsTabActivity.this.getString(R.string.c_char_is_not_accepted); + + final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); + editName.setText(name); + editName.addTextChangedListener(new TextWatcher() { + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + for ( int i = 0; i < s.length(); i++ ) { + char c = s.charAt(i); + if (!acceptableChars.contains(c)) { + s.delete(i, i+1); + Toast.makeText(CalculatorVarsTabActivity.this, String.format(errorMsg, c), Toast.LENGTH_SHORT).show(); + } + } + } + }); + + final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); + if (!StringUtils.isEmpty(value)) { + editValue.setText(value); + } + + final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); + editDescription.setText(description); + + final Var.Builder varBuilder; + if (var != null) { + varBuilder = new Var.Builder(var); + } else { + varBuilder = new Var.Builder(); + } + + final AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setCancelable(true) + .setNegativeButton(R.string.c_cancel, null) + .setPositiveButton(R.string.c_save, new VarEditorSaver(varBuilder, var, editView)) + .setView(editView); + + if ( var != null ) { + // EDIT mode + + builder.setTitle(R.string.c_var_edit_var); + builder.setNeutralButton(R.string.c_remove, new VarEditorRemover(var, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + createEditVariableDialog(var, name, value, description); + } + })); + } else { + // CREATE mode + + builder.setTitle(R.string.c_var_create_var); + } + + builder.create().show(); + } else { + Toast.makeText(this, getString(R.string.c_sys_var_cannot_be_changed), Toast.LENGTH_LONG).show(); + } + } + + private class VarEditorSaver implements DialogInterface.OnClickListener { + + @NotNull + private Var.Builder varBuilder; + + @Nullable + private final Var editedInstance; + + @NotNull + private View editView; + + public VarEditorSaver(@NotNull Var.Builder varBuilder, @Nullable Var editedInstance, @NotNull View editView) { + this.varBuilder = varBuilder; + this.editedInstance = editedInstance; + this.editView = editView; + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == DialogInterface.BUTTON_POSITIVE) { + final Integer error; + + final EditText editName = (EditText) editView.findViewById(R.id.var_edit_name); + String name = editName.getText().toString(); + + final EditText editValue = (EditText) editView.findViewById(R.id.var_edit_value); + String value = editValue.getText().toString(); + + final EditText editDescription = (EditText) editView.findViewById(R.id.var_edit_description); + String description = editDescription.getText().toString(); + + + final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister(); + if (isValidName(name)) { + + boolean canBeSaved = false; + + final Var varFromRegister = varsRegistry.get(name); + if ( varFromRegister == null ) { + canBeSaved = true; + } else if ( editedInstance != null && varFromRegister.getId().equals(editedInstance.getId()) ) { + canBeSaved = true; + } + + if (canBeSaved) { + final MathType.Result mathType = MathType.getType(name, 0, false); + + if (mathType.getMathType() == MathType.text || mathType.getMathType() == MathType.constant) { + + if (StringUtils.isEmpty(value)) { + // value is empty => undefined variable + varBuilder.setName(name); + varBuilder.setDescription(description); + varBuilder.setValue(null); + error = null; + } else { + // value is not empty => must be a number + boolean valid = isValidValue(value); + + if (valid) { + varBuilder.setName(name); + varBuilder.setDescription(description); + varBuilder.setValue(value); + error = null; + } else { + error = R.string.c_value_is_not_a_number; + } + } + } else { + error = R.string.c_var_name_clashes; + } + } else { + error = R.string.c_var_already_exists; + } + } else { + error = R.string.c_name_is_not_valid; + } + + if (error != null) { + Toast.makeText(CalculatorVarsTabActivity.this, getString(error), Toast.LENGTH_LONG).show(); + createEditVariableDialog(editedInstance, name, value, description); + } else { + final Var addedVar = varsRegistry.add(varBuilder); + if (isInCategory(addedVar)) { + if ( editedInstance != null ) { + CalculatorVarsTabActivity.this.getAdapter().remove(editedInstance); + } + CalculatorVarsTabActivity.this.getAdapter().add(addedVar); + } + + varsRegistry.save(CalculatorVarsTabActivity.this); + + if (isInCategory(addedVar)) { + sort(); + } + } + } + } + } + + private static boolean isValidName(@Nullable String name) { + boolean result = false; + + if (!StringUtils.isEmpty(name)) { + try { + Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorEngine.instance.getEngine()), null); + result = true; + } catch (ParseException e) { + // not valid name; + } + } + + return result; + } + + public static boolean isValidValue(@NotNull String value) { + // now every string might be constant + return true; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + final MenuInflater menuInflater = getMenuInflater(); + menuInflater.inflate(R.menu.var_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + boolean result; + + switch (item.getItemId()) { + case R.id.var_menu_add_var: + createEditVariableDialog(null, null, null, null); + result = true; + break; + default: + result = super.onOptionsItemSelected(item); + } + + return result; + } + + private class VarEditorRemover implements DialogInterface.OnClickListener { + + @NotNull + private final Var var; + + @Nullable + private final DialogInterface.OnClickListener callbackOnCancel; + + private final boolean confirmed; + + public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel) { + this(var, callbackOnCancel, false); + } + + public VarEditorRemover(@NotNull Var var, @Nullable DialogInterface.OnClickListener callbackOnCancel, boolean confirmed) { + this.var = var; + this.callbackOnCancel = callbackOnCancel; + this.confirmed = confirmed; + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (!confirmed) { + final TextView question = new TextView(CalculatorVarsTabActivity.this); + question.setText(String.format(getString(R.string.c_var_removal_confirmation_question), var.getName())); + question.setPadding(6, 6, 6, 6); + final AlertDialog.Builder builder = new AlertDialog.Builder(CalculatorVarsTabActivity.this) + .setCancelable(true) + .setView(question) + .setTitle(R.string.c_var_removal_confirmation) + .setNegativeButton(R.string.c_no, callbackOnCancel) + .setPositiveButton(R.string.c_yes, new VarEditorRemover(var, callbackOnCancel, true)); + + builder.create().show(); + } else { + if (isInCategory(var)) { + getAdapter().remove(var); + } + final AndroidVarsRegistry varsRegistry = CalculatorEngine.instance.getVarsRegister(); + varsRegistry.remove(var); + varsRegistry.save(CalculatorVarsTabActivity.this); + if (isInCategory(var)) { + CalculatorVarsTabActivity.this.getAdapter().notifyDataSetChanged(); + } + } + } + } +} diff --git a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java index 7772417f..d1065b39 100644 --- a/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java +++ b/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryActivity.java @@ -14,6 +14,7 @@ import android.widget.TabHost; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; +import org.solovyev.android.view.prefs.AndroidUtils; /** * User: serso @@ -26,7 +27,7 @@ public class CalculatorHistoryActivity extends TabActivity { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.history_tabs); + setContentView(R.layout.tabs); final TabHost tabHost = getTabHost(); @@ -34,6 +35,8 @@ public class CalculatorHistoryActivity extends TabActivity { createTab(tabHost, "history", R.string.c_history, HistoryActivityTab.class); tabHost.setCurrentTab(0); + + AndroidUtils.centerAndWrapTabsFor(tabHost); } private void createTab(@NotNull TabHost tabHost, @@ -46,7 +49,7 @@ public class CalculatorHistoryActivity extends TabActivity { final Intent intent = new Intent().setClass(this, activityClass); // Initialize a TabSpec for each tab and add it to the TabHost - spec = tabHost.newTabSpec(tabId).setIndicator(getString(tabCaptionId)).setContent(intent); + spec = tabHost.newTabSpec(tabId).setIndicator(this.getString(tabCaptionId)).setContent(intent); tabHost.addTab(spec); } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java index 8d25d821..c5204baa 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidFunctionsMathRegistry.java @@ -6,11 +6,16 @@ package org.solovyev.android.calculator.model; +import jscl.math.function.ArcTrigonometric; +import jscl.math.function.Comparison; +import jscl.math.function.Function; +import jscl.math.function.Trigonometric; import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.R; import org.solovyev.common.math.MathRegistry; +import org.solovyev.common.utils.CollectionsUtils; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * User: serso @@ -19,6 +24,77 @@ import java.util.Map; */ public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl { + public static enum Category { + + trigonometric(R.string.c_fun_category_trig, 100){ + @Override + boolean isInCategory(@NotNull Function function) { + return (function instanceof Trigonometric || function instanceof ArcTrigonometric) && !hyperbolic_trigonometric.isInCategory(function); + } + }, + + hyperbolic_trigonometric(R.string.c_fun_category_hyper_trig, 300) { + + private final List names = Arrays.asList("sinh", "cosh", "tanh", "coth", "asinh", "acosh", "atanh", "acoth"); + + @Override + boolean isInCategory(@NotNull Function function) { + return names.contains(function.getName()); + } + }, + + comparison(R.string.c_fun_category_comparison, 200) { + @Override + boolean isInCategory(@NotNull Function function) { + return function instanceof Comparison; + } + }, + + common(R.string.c_fun_category_common, 0) { + @Override + boolean isInCategory(@NotNull Function function) { + for (Category category : values()) { + if ( category != this ) { + if ( category.isInCategory(function) ) { + return false; + } + } + } + + return true; + } + }; + + private final int captionId; + + private final int tabOrder; + + Category(int captionId, int tabOrder) { + this.captionId = captionId; + this.tabOrder = tabOrder; + } + + public int getCaptionId() { + return captionId; + } + + abstract boolean isInCategory(@NotNull Function function); + + @NotNull + public static List getCategoriesByTabOrder() { + final List result = CollectionsUtils.asList(Category.values()); + + Collections.sort(result, new Comparator() { + @Override + public int compare(Category category, Category category1) { + return category.tabOrder - category1.tabOrder; + } + }); + + return result; + } + } + @NotNull private static final Map substitutes = new HashMap(); static { @@ -37,4 +113,15 @@ public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl getSubstitutes() { return substitutes; } + + @Override + public String getCategory(@NotNull Function function) { + for (Category category : Category.values()) { + if ( category.isInCategory(function) ) { + return category.name(); + } + } + + return null; + } } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java index 70e762c5..8d898582 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistry.java @@ -7,7 +7,6 @@ package org.solovyev.android.calculator.model; import android.content.Context; -import jscl.math.function.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.common.math.MathEntity; @@ -21,5 +20,8 @@ import org.solovyev.common.math.MathRegistry; public interface AndroidMathRegistry extends MathRegistry { @Nullable - String getDescription(@NotNull Context context, @NotNull String functionName); + String getDescription(@NotNull Context context, @NotNull String mathEntityName); + + @Nullable + String getCategory(@NotNull T mathEntity); } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java index cdca7963..ae7135e6 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidMathRegistryImpl.java @@ -40,13 +40,13 @@ public abstract class AndroidMathRegistryImpl implements A @Nullable @Override - public String getDescription(@NotNull Context context, @NotNull String name) { + public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { final String stringName; final Map substitutes = getSubstitutes(); - final String substitute = substitutes.get(name); + final String substitute = substitutes.get(mathEntityName); if (substitute == null) { - stringName = prefix + name; + stringName = prefix + mathEntityName; } else { stringName = prefix + substitute; } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java index 261b61de..79b37cf2 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidOperatorsMathRegistry.java @@ -43,4 +43,9 @@ public class AndroidOperatorsMathRegistry extends AndroidMathRegistryImpl getSubstitutes() { return substitutes; } + + @Override + public String getCategory(@NotNull Operator mathEntity) { + return null; + } } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java index 58c0277a..58075907 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidPostfixFunctionsRegistry.java @@ -42,4 +42,9 @@ public class AndroidPostfixFunctionsRegistry extends AndroidMathRegistryImpl getSubstitutes() { return substitutes; } + + @Override + public String getCategory(@NotNull Operator mathEntity) { + return null; + } } diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java index 156d3c0a..80b2b85e 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistry.java @@ -10,14 +10,65 @@ import android.content.Context; import android.content.SharedPreferences; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.common.math.MathRegistry; +import org.solovyev.android.calculator.R; +import org.solovyev.common.utils.CollectionsUtils; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; /** * User: serso * Date: 10/6/11 * Time: 9:31 PM */ -public interface AndroidVarsRegistry extends MathRegistry{ +public interface AndroidVarsRegistry extends AndroidMathRegistry{ + + public static enum Category { + + system(R.string.c_var_system, 100){ + @Override + boolean isInCategory(@NotNull Var var) { + return var.isSystem(); + } + }, + + my(R.string.c_var_my, 0) { + @Override + boolean isInCategory(@NotNull Var var) { + return !var.isSystem(); + } + }; + + private final int captionId; + + private final int tabOrder; + + Category(int captionId, int tabOrder) { + this.captionId = captionId; + this.tabOrder = tabOrder; + } + + public int getCaptionId() { + return captionId; + } + + abstract boolean isInCategory(@NotNull Var var); + + @NotNull + public static List getCategoriesByTabOrder() { + final List result = CollectionsUtils.asList(Category.values()); + + Collections.sort(result, new Comparator() { + @Override + public int compare(Category category, Category category1) { + return category.tabOrder - category1.tabOrder; + } + }); + + return result; + } + } void load(@Nullable Context context, @Nullable SharedPreferences preferences); diff --git a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java index 89b901cb..c6267e4c 100644 --- a/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java +++ b/src/main/java/org/solovyev/android/calculator/model/AndroidVarsRegistryImpl.java @@ -234,4 +234,25 @@ class AndroidVarsRegistryImpl implements AndroidVarsRegistry { return null; } } + + @Override + public String getDescription(@NotNull Context context, @NotNull String mathEntityName) { + final Var var = get(mathEntityName); + if (var != null) { + return var.getDescription(); + } else { + return null; + } + } + + @Override + public String getCategory(@NotNull Var var) { + for (Category category : Category.values()) { + if ( category.isInCategory(var) ) { + return category.name(); + } + } + + return null; + } } diff --git a/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java b/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java new file mode 100644 index 00000000..2d369309 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/prefs/AndroidUtils.java @@ -0,0 +1,55 @@ +/* + * 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 android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TabHost; +import android.widget.TextView; +import org.jetbrains.annotations.NotNull; + +/** + * User: serso + * Date: 12/21/11 + * Time: 11:54 PM + */ +public final class AndroidUtils { + + // not intended for instantiation + private AndroidUtils() { + throw new AssertionError(); + } + + public static void centerAndWrapTabsFor(@NotNull TabHost tabHost) { + int tabCount = tabHost.getTabWidget().getTabCount(); + for (int i = 0; i < tabCount; i++) { + final View view = tabHost.getTabWidget().getChildTabViewAt(i); + if ( view != null ) { + if (view.getLayoutParams().height > 0) { + // reduce height of the tab + view.getLayoutParams().height *= 0.8; + } + + // get title text view + final View textView = view.findViewById(android.R.id.title); + if ( textView instanceof TextView) { + // just in case check the type + + // center text + ((TextView) textView).setGravity(Gravity.CENTER); + // wrap text + ((TextView) textView).setSingleLine(false); + + // explicitly set layout parameters + textView.getLayoutParams().height = ViewGroup.LayoutParams.FILL_PARENT; + textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; + } + } + } + } +}