math entities list activities refactored + categories added
This commit is contained in:
parent
2db82269b2
commit
5233ba9e18
@ -65,6 +65,10 @@
|
|||||||
a:label="@string/c_functions"
|
a:label="@string/c_functions"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
|
<activity a:name=".CalculatorFunctionsTabActivity"
|
||||||
|
a:label="@string/c_functions"
|
||||||
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name=".CalculatorOperatorsActivity"
|
<activity a:name=".CalculatorOperatorsActivity"
|
||||||
a:label="@string/c_operators"
|
a:label="@string/c_operators"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
@ -73,6 +77,10 @@
|
|||||||
a:label="@string/c_vars_and_constants"
|
a:label="@string/c_vars_and_constants"
|
||||||
a:configChanges="orientation|keyboardHidden"/>
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
|
<activity a:name=".CalculatorVarsTabActivity"
|
||||||
|
a:label="@string/c_vars_and_constants"
|
||||||
|
a:configChanges="orientation|keyboardHidden"/>
|
||||||
|
|
||||||
<activity a:name=".CalculatorPlotActivity"
|
<activity a:name=".CalculatorPlotActivity"
|
||||||
a:label="@string/c_plot_graph"/>
|
a:label="@string/c_plot_graph"/>
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
~ 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
|
|
||||||
-->
|
|
||||||
|
|
||||||
<TabHost xmlns:a="http://schemas.android.com/apk/res/android"
|
|
||||||
a:id="@android:id/tabhost"
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
a:orientation="vertical"
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<TabWidget
|
|
||||||
a:id="@android:id/tabs"
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
a:id="@android:id/tabcontent"
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="fill_parent"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</TabHost>
|
|
@ -16,18 +16,18 @@
|
|||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="fill_parent">
|
a:layout_height="fill_parent">
|
||||||
|
|
||||||
<TextView a:id="@+id/var_text"
|
<TextView a:id="@+id/math_entity_text"
|
||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="fill_parent"
|
a:layout_height="fill_parent"
|
||||||
style="@style/var_text">
|
style="@style/math_entity_text">
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView a:id="@+id/var_description"
|
<TextView a:id="@+id/math_entity_description"
|
||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="fill_parent"
|
a:layout_height="fill_parent"
|
||||||
style="@style/var_description">
|
style="@style/math_entity_description">
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
~ 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
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
|
|
||||||
a:orientation="vertical"
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<ListView
|
|
||||||
a:layout_width="fill_parent"
|
|
||||||
a:layout_height="fill_parent"
|
|
||||||
a:layout_weight="1"
|
|
||||||
a:id="@android:id/list"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
30
res/layout/tabs.xml
Normal file
30
res/layout/tabs.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
~ 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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<TabHost xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
a:id="@android:id/tabhost"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:orientation="vertical"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<TabWidget
|
||||||
|
a:id="@android:id/tabs"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
a:id="@android:id/tabcontent"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="fill_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</TabHost>
|
@ -30,11 +30,11 @@
|
|||||||
<item name="android:padding">5dp</item>
|
<item name="android:padding">5dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_text_parent">
|
<style name="math_entity_text_parent">
|
||||||
<item name="android:textSize">20dp</item>
|
<item name="android:textSize">20dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_description_parent">
|
<style name="math_entity_description_parent">
|
||||||
<item name="android:textSize">15dp</item>
|
<item name="android:textSize">15dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
<item name="android:padding">5dp</item>
|
<item name="android:padding">5dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_text_parent">
|
<style name="math_entity_text_parent">
|
||||||
<item name="android:textSize">20dp</item>
|
<item name="android:textSize">20dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_description_parent">
|
<style name="math_entity_description_parent">
|
||||||
<item name="android:textSize">15dp</item>
|
<item name="android:textSize">15dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
<item name="android:padding">5dp</item>
|
<item name="android:padding">5dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_text_parent">
|
<style name="math_entity_text_parent">
|
||||||
<item name="android:textSize">20dp</item>
|
<item name="android:textSize">20dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_description_parent">
|
<style name="math_entity_description_parent">
|
||||||
<item name="android:textSize">15dp</item>
|
<item name="android:textSize">15dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -321,4 +321,13 @@ Check the \'Round result\' preference in application settings - it should be tur
|
|||||||
<string name="c_history_was_removed">History was successfully removed!</string>
|
<string name="c_history_was_removed">History was successfully removed!</string>
|
||||||
<string name="c_history_saved">History was successfully saved!</string>
|
<string name="c_history_saved">History was successfully saved!</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="c_fun_category_trig">Trigonometric</string>
|
||||||
|
<string name="c_fun_category_hyper_trig">Hyperbolic trigonometric</string>
|
||||||
|
<string name="c_fun_category_comparison">Comparison</string>
|
||||||
|
<string name="c_fun_category_common">Common</string>
|
||||||
|
|
||||||
|
<string name="c_var_system">System</string>
|
||||||
|
<string name="c_var_my">My</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="history_time" parent="var_text"/>
|
<style name="history_time" parent="math_entity_text"/>
|
||||||
|
|
||||||
<style name="history_item" parent="var_description"/>
|
<style name="history_item" parent="math_entity_description"/>
|
||||||
<style name="history_item_label" parent="var_description">
|
<style name="history_item_label" parent="math_entity_description">
|
||||||
<item name="android:textStyle">bold</item>
|
<item name="android:textStyle">bold</item>
|
||||||
<item name="android:textColor">@android:color/white</item>
|
<item name="android:textColor">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="var_text" parent="var_text_parent">
|
<style name="math_entity_text" parent="math_entity_text_parent">
|
||||||
<item name="android:paddingTop">6dp</item>
|
<item name="android:paddingTop">6dp</item>
|
||||||
<item name="android:paddingLeft">6dp</item>
|
<item name="android:paddingLeft">6dp</item>
|
||||||
<item name="android:paddingRight">6dp</item>
|
<item name="android:paddingRight">6dp</item>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<item name="android:textColor">@android:color/white</item>
|
<item name="android:textColor">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_description" parent="var_description_parent">
|
<style name="math_entity_description" parent="math_entity_description_parent">
|
||||||
<item name="android:paddingTop">0dp</item>
|
<item name="android:paddingTop">0dp</item>
|
||||||
<item name="android:paddingLeft">6dp</item>
|
<item name="android:paddingLeft">6dp</item>
|
||||||
<item name="android:paddingRight">6dp</item>
|
<item name="android:paddingRight">6dp</item>
|
||||||
|
@ -44,11 +44,11 @@
|
|||||||
<item name="android:padding">5dp</item>
|
<item name="android:padding">5dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_text_parent">
|
<style name="math_entity_text_parent">
|
||||||
<item name="android:textSize">20dp</item>
|
<item name="android:textSize">20dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="var_description_parent">
|
<style name="math_entity_description_parent">
|
||||||
<item name="android:textSize">15dp</item>
|
<item name="android:textSize">15dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -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<T extends MathEntity> extends ListActivity {
|
||||||
|
|
||||||
|
public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category";
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private MathEntityArrayAdapter<T> adapter;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
static void createTab(@NotNull Context context,
|
||||||
|
@NotNull TabHost tabHost,
|
||||||
|
@NotNull String tabId,
|
||||||
|
@NotNull String categoryId,
|
||||||
|
int tabCaptionId,
|
||||||
|
@NotNull Class<? extends Activity> 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<T>(getDescriptionGetter(), this, R.layout.math_entity, R.id.math_entity_text, getMathEntitiesByCategory());
|
||||||
|
setListAdapter(adapter);
|
||||||
|
|
||||||
|
sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private List<T> getMathEntitiesByCategory() {
|
||||||
|
final List<T> result = getMathEntities();
|
||||||
|
|
||||||
|
new Filter<T>(new FilterRule<T>() {
|
||||||
|
@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<T> getAdapter() {
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract MathEntityDescriptionGetter getDescriptionGetter();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract List<T> getMathEntities();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected abstract String getMathEntityCategory(@NotNull T t);
|
||||||
|
|
||||||
|
protected void sort() {
|
||||||
|
AbstractMathEntityListActivity.this.adapter.sort(new Comparator<T>() {
|
||||||
|
@Override
|
||||||
|
public int compare(T function1, T function2) {
|
||||||
|
return function1.getName().compareTo(function2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AbstractMathEntityListActivity.this.adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class MathEntityArrayAdapter<T extends MathEntity> extends ArrayAdapter<T> {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final MathEntityDescriptionGetter descriptionGetter;
|
||||||
|
|
||||||
|
private MathEntityArrayAdapter(@NotNull MathEntityDescriptionGetter descriptionGetter, @NotNull Context context, int resource, int textViewResourceId, @NotNull List<T> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -58,9 +58,9 @@ public class CalculatorActivityLauncher {
|
|||||||
if (calculatorModel.getDisplay().isValid() ) {
|
if (calculatorModel.getDisplay().isValid() ) {
|
||||||
final String varValue = calculatorModel.getDisplay().getText().toString();
|
final String varValue = calculatorModel.getDisplay().getText().toString();
|
||||||
if (!StringUtils.isEmpty(varValue)) {
|
if (!StringUtils.isEmpty(varValue)) {
|
||||||
if (CalculatorVarsActivity.isValidValue(varValue)) {
|
if (CalculatorVarsTabActivity.isValidValue(varValue)) {
|
||||||
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
|
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);
|
context.startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.c_not_valid_result, Toast.LENGTH_SHORT).show();
|
||||||
|
@ -6,106 +6,33 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.ListActivity;
|
import android.app.TabActivity;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.widget.TabHost;
|
||||||
import android.view.View;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import android.view.ViewGroup;
|
import org.solovyev.android.calculator.model.AndroidFunctionsMathRegistry;
|
||||||
import android.widget.*;
|
import org.solovyev.android.view.prefs.AndroidUtils;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 10/29/11
|
* Date: 12/21/11
|
||||||
* Time: 4:55 PM
|
* Time: 10:33 PM
|
||||||
*/
|
*/
|
||||||
public class CalculatorFunctionsActivity extends ListActivity {
|
public class CalculatorFunctionsActivity extends TabActivity {
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private FunctionsArrayAdapter adapter;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.functions);
|
setContentView(R.layout.tabs);
|
||||||
|
|
||||||
adapter = new FunctionsArrayAdapter(this, R.layout.var, R.id.var_text, new ArrayList<Function>(CalculatorEngine.instance.getFunctionsRegistry().getEntities()));
|
final TabHost tabHost = getTabHost();
|
||||||
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();
|
|
||||||
|
|
||||||
|
for (AndroidFunctionsMathRegistry.Category category : AndroidFunctionsMathRegistry.Category.getCategoriesByTabOrder()) {
|
||||||
|
AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorFunctionsTabActivity.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sort() {
|
AndroidUtils.centerAndWrapTabsFor(tabHost);
|
||||||
CalculatorFunctionsActivity.this.adapter.sort(new Comparator<Function>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Function function1, Function function2) {
|
|
||||||
return function1.getName().compareTo(function2.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CalculatorFunctionsActivity.this.adapter.notifyDataSetChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FunctionsArrayAdapter extends ArrayAdapter<Function> {
|
|
||||||
|
|
||||||
private FunctionsArrayAdapter(Context context, int resource, int textViewResourceId, List<Function> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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<Function> {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected MathEntityDescriptionGetter getDescriptionGetter() {
|
||||||
|
return new MathEntityDescriptionGetterImpl(CalculatorEngine.instance.getFunctionsRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected List<Function> getMathEntities() {
|
||||||
|
return new ArrayList<Function>(CalculatorEngine.instance.getFunctionsRegistry().getEntities());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMathEntityCategory(@NotNull Function function) {
|
||||||
|
return CalculatorEngine.instance.getFunctionsRegistry().getCategory(function);
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,12 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Context;
|
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 jscl.math.operator.Operator;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
import org.solovyev.common.utils.StringUtils;
|
import org.solovyev.common.utils.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,92 +15,48 @@ import java.util.List;
|
|||||||
* Time: 1:53 PM
|
* Time: 1:53 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CalculatorOperatorsActivity extends ListActivity {
|
public class CalculatorOperatorsActivity extends AbstractMathEntityListActivity<Operator> {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private OperatorsArrayAdapter adapter;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected MathEntityDescriptionGetter getDescriptionGetter() {
|
||||||
super.onCreate(savedInstanceState);
|
return new OperatorDescriptionGetter();
|
||||||
|
|
||||||
setContentView(R.layout.operators);
|
|
||||||
|
|
||||||
List<Operator> elements = new ArrayList<Operator>();
|
|
||||||
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<Operator>() {
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public int compare(Operator operator1, Operator operator2) {
|
protected List<Operator> getMathEntities() {
|
||||||
return operator1.getName().compareTo(operator2.getName());
|
final List<Operator> result = new ArrayList<Operator>();
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CalculatorOperatorsActivity.this.adapter.notifyDataSetChanged();
|
result.addAll(CalculatorEngine.instance.getOperatorsRegistry().getEntities());
|
||||||
}
|
result.addAll(CalculatorEngine.instance.getPostfixFunctionsRegistry().getEntities());
|
||||||
|
|
||||||
private class OperatorsArrayAdapter extends ArrayAdapter<Operator> {
|
return result;
|
||||||
|
|
||||||
private OperatorsArrayAdapter(Context context, int resource, int textViewResourceId, List<Operator> objects) {
|
|
||||||
super(context, resource, textViewResourceId, objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
protected String getMathEntityCategory(@NotNull Operator operator) {
|
||||||
final ViewGroup result = (ViewGroup) super.getView(position, convertView, parent);
|
String result = CalculatorEngine.instance.getOperatorsRegistry().getCategory(operator);
|
||||||
|
if (result == null) {
|
||||||
final Operator operator = getItem(position);
|
result = CalculatorEngine.instance.getPostfixFunctionsRegistry().getCategory(operator);
|
||||||
|
|
||||||
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)) {
|
return result;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,415 +6,38 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.TabActivity;
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.widget.TabHost;
|
||||||
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 org.jetbrains.annotations.Nullable;
|
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.AndroidVarsRegistry;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.view.prefs.AndroidUtils;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 9/28/11
|
* Date: 12/21/11
|
||||||
* Time: 10:55 PM
|
* 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";
|
|
||||||
|
|
||||||
private final static List<Character> acceptableChars = Arrays.asList(StringUtils.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray()));
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private VarsArrayAdapter adapter;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.vars);
|
setContentView(R.layout.tabs);
|
||||||
|
|
||||||
final List<Var> vars = new ArrayList<Var>(CalculatorEngine.instance.getVarsRegister().getEntities());
|
final TabHost tabHost = getTabHost();
|
||||||
CollectionsUtils.removeAll(vars, new Finder<Var>() {
|
|
||||||
@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();
|
for (AndroidVarsRegistry.Category category : AndroidVarsRegistry.Category.getCategoriesByTabOrder()) {
|
||||||
lv.setTextFilterEnabled(true);
|
if (category == AndroidVarsRegistry.Category.my) {
|
||||||
|
AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, getIntent());
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
varBuilder = new Var.Builder();
|
AbstractMathEntityListActivity.createTab(this, tabHost, category.name(), category.name(), category.getCaptionId(), CalculatorVarsTabActivity.class, null);
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
tabHost.setCurrentTab(0);
|
||||||
|
AndroidUtils.centerAndWrapTabsFor(tabHost);
|
||||||
@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<Var>() {
|
|
||||||
@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<Var> {
|
|
||||||
|
|
||||||
private VarsArrayAdapter(Context context, int resource, int textViewResourceId, List<Var> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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<Var> {
|
||||||
|
|
||||||
|
public static final String CREATE_VAR_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_create_var";
|
||||||
|
|
||||||
|
private final static List<Character> 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<Var> getMathEntities() {
|
||||||
|
final List<Var> result = new ArrayList<Var>(CalculatorEngine.instance.getVarsRegister().getEntities());
|
||||||
|
|
||||||
|
CollectionsUtils.removeAll(result, new Finder<Var>() {
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import android.widget.TabHost;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
|
import org.solovyev.android.view.prefs.AndroidUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -26,7 +27,7 @@ public class CalculatorHistoryActivity extends TabActivity {
|
|||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.history_tabs);
|
setContentView(R.layout.tabs);
|
||||||
|
|
||||||
final TabHost tabHost = getTabHost();
|
final TabHost tabHost = getTabHost();
|
||||||
|
|
||||||
@ -34,6 +35,8 @@ public class CalculatorHistoryActivity extends TabActivity {
|
|||||||
createTab(tabHost, "history", R.string.c_history, HistoryActivityTab.class);
|
createTab(tabHost, "history", R.string.c_history, HistoryActivityTab.class);
|
||||||
|
|
||||||
tabHost.setCurrentTab(0);
|
tabHost.setCurrentTab(0);
|
||||||
|
|
||||||
|
AndroidUtils.centerAndWrapTabsFor(tabHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTab(@NotNull TabHost tabHost,
|
private void createTab(@NotNull TabHost tabHost,
|
||||||
@ -46,7 +49,7 @@ public class CalculatorHistoryActivity extends TabActivity {
|
|||||||
final Intent intent = new Intent().setClass(this, activityClass);
|
final Intent intent = new Intent().setClass(this, activityClass);
|
||||||
|
|
||||||
// Initialize a TabSpec for each tab and add it to the TabHost
|
// 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);
|
tabHost.addTab(spec);
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,16 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator.model;
|
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.jetbrains.annotations.NotNull;
|
||||||
|
import org.solovyev.android.calculator.R;
|
||||||
import org.solovyev.common.math.MathRegistry;
|
import org.solovyev.common.math.MathRegistry;
|
||||||
|
import org.solovyev.common.utils.CollectionsUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -19,6 +24,77 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl<jscl.math.function.Function> {
|
public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl<jscl.math.function.Function> {
|
||||||
|
|
||||||
|
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<String> 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<Category> getCategoriesByTabOrder() {
|
||||||
|
final List<Category> result = CollectionsUtils.asList(Category.values());
|
||||||
|
|
||||||
|
Collections.sort(result, new Comparator<Category>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Category category, Category category1) {
|
||||||
|
return category.tabOrder - category1.tabOrder;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final Map<String, String> substitutes = new HashMap<String, String>();
|
private static final Map<String, String> substitutes = new HashMap<String, String>();
|
||||||
static {
|
static {
|
||||||
@ -37,4 +113,15 @@ public class AndroidFunctionsMathRegistry extends AndroidMathRegistryImpl<jscl.m
|
|||||||
protected Map<String, String> getSubstitutes() {
|
protected Map<String, String> getSubstitutes() {
|
||||||
return substitutes;
|
return substitutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory(@NotNull Function function) {
|
||||||
|
for (Category category : Category.values()) {
|
||||||
|
if ( category.isInCategory(function) ) {
|
||||||
|
return category.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package org.solovyev.android.calculator.model;
|
package org.solovyev.android.calculator.model;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import jscl.math.function.Function;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.common.math.MathEntity;
|
import org.solovyev.common.math.MathEntity;
|
||||||
@ -21,5 +20,8 @@ import org.solovyev.common.math.MathRegistry;
|
|||||||
public interface AndroidMathRegistry<T extends MathEntity> extends MathRegistry<T> {
|
public interface AndroidMathRegistry<T extends MathEntity> extends MathRegistry<T> {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
String getDescription(@NotNull Context context, @NotNull String functionName);
|
String getDescription(@NotNull Context context, @NotNull String mathEntityName);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String getCategory(@NotNull T mathEntity);
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ public abstract class AndroidMathRegistryImpl<T extends MathEntity> implements A
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getDescription(@NotNull Context context, @NotNull String name) {
|
public String getDescription(@NotNull Context context, @NotNull String mathEntityName) {
|
||||||
final String stringName;
|
final String stringName;
|
||||||
|
|
||||||
final Map<String, String> substitutes = getSubstitutes();
|
final Map<String, String> substitutes = getSubstitutes();
|
||||||
final String substitute = substitutes.get(name);
|
final String substitute = substitutes.get(mathEntityName);
|
||||||
if (substitute == null) {
|
if (substitute == null) {
|
||||||
stringName = prefix + name;
|
stringName = prefix + mathEntityName;
|
||||||
} else {
|
} else {
|
||||||
stringName = prefix + substitute;
|
stringName = prefix + substitute;
|
||||||
}
|
}
|
||||||
|
@ -43,4 +43,9 @@ public class AndroidOperatorsMathRegistry extends AndroidMathRegistryImpl<Operat
|
|||||||
protected Map<String, String> getSubstitutes() {
|
protected Map<String, String> getSubstitutes() {
|
||||||
return substitutes;
|
return substitutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory(@NotNull Operator mathEntity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,4 +42,9 @@ public class AndroidPostfixFunctionsRegistry extends AndroidMathRegistryImpl<Ope
|
|||||||
protected Map<String, String> getSubstitutes() {
|
protected Map<String, String> getSubstitutes() {
|
||||||
return substitutes;
|
return substitutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory(@NotNull Operator mathEntity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,65 @@ import android.content.Context;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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
|
* User: serso
|
||||||
* Date: 10/6/11
|
* Date: 10/6/11
|
||||||
* Time: 9:31 PM
|
* Time: 9:31 PM
|
||||||
*/
|
*/
|
||||||
public interface AndroidVarsRegistry extends MathRegistry<Var>{
|
public interface AndroidVarsRegistry extends AndroidMathRegistry<Var>{
|
||||||
|
|
||||||
|
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<Category> getCategoriesByTabOrder() {
|
||||||
|
final List<Category> result = CollectionsUtils.asList(Category.values());
|
||||||
|
|
||||||
|
Collections.sort(result, new Comparator<Category>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Category category, Category category1) {
|
||||||
|
return category.tabOrder - category1.tabOrder;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void load(@Nullable Context context, @Nullable SharedPreferences preferences);
|
void load(@Nullable Context context, @Nullable SharedPreferences preferences);
|
||||||
|
|
||||||
|
@ -234,4 +234,25 @@ class AndroidVarsRegistryImpl implements AndroidVarsRegistry {
|
|||||||
return null;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user