changes, changes, changes
This commit is contained in:
parent
c2e15ee08c
commit
5b074bdf85
@ -55,7 +55,7 @@
|
||||
<include layout="@layout/calc_eight_digit_button"/>
|
||||
<include layout="@layout/calc_nine_digit_button"/>
|
||||
<include layout="@layout/calc_plus_button"/>
|
||||
<include layout="@layout/calc_paste_button"/>
|
||||
<include layout="@layout/calc_copy_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -65,7 +65,7 @@
|
||||
<include layout="@layout/calc_zero_digit_button"/>
|
||||
<include layout="@layout/calc_square_brackets_button"/>
|
||||
<include layout="@layout/calc_subtraction_button"/>
|
||||
<include layout="@layout/calc_copy_button"/>
|
||||
<include layout="@layout/calc_paste_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -6,9 +6,9 @@
|
||||
~ or visit http://se.solovyev.org
|
||||
-->
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
<org.solovyev.android.view.widgets.ColorButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/clearButton"
|
||||
a:text="@string/c_clear"
|
||||
style="@style/control_button_style"
|
||||
a:drawableTop="@drawable/ic_delete"
|
||||
style="@style/control_image_button_style"
|
||||
a:onClick="clearButtonClickHandler"/>
|
@ -6,10 +6,9 @@
|
||||
~ or visit http://se.solovyev.org
|
||||
-->
|
||||
|
||||
<ImageButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
<org.solovyev.android.view.widgets.ColorButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/pasteButton"
|
||||
a:src="@drawable/copy"
|
||||
style="@style/control_button_style"
|
||||
a:padding="6dp"
|
||||
a:drawableTop="@drawable/copy"
|
||||
style="@style/control_image_button_style"
|
||||
a:onClick="copyButtonClickHandler"/>
|
@ -10,6 +10,5 @@
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/pasteButton"
|
||||
a:src="@drawable/heart"
|
||||
style="@style/control_button_style"
|
||||
a:padding="6dp"
|
||||
style="@style/control_image_button_style"
|
||||
a:onClick="donateButtonClickHandler"/>
|
@ -6,9 +6,9 @@
|
||||
~ or visit http://se.solovyev.org
|
||||
-->
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
<org.solovyev.android.view.widgets.ColorButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/eraseButton"
|
||||
a:text="@string/c_erase"
|
||||
style="@style/control_button_style"
|
||||
a:drawableTop="@drawable/sym_keyboard_delete"
|
||||
style="@style/control_image_button_style"
|
||||
a:onClick="eraseButtonClickHandler"/>
|
@ -6,10 +6,9 @@
|
||||
~ or visit http://se.solovyev.org
|
||||
-->
|
||||
|
||||
<ImageButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
<org.solovyev.android.view.widgets.ColorButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/pasteButton"
|
||||
a:src="@drawable/paste"
|
||||
style="@style/control_button_style"
|
||||
a:padding="6dp"
|
||||
a:drawableTop="@drawable/paste"
|
||||
style="@style/control_image_button_style"
|
||||
a:onClick="pasteButtonClickHandler"/>
|
@ -10,5 +10,6 @@
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/roundBracketsButton" a:text="()"
|
||||
calc:textUp="("
|
||||
calc:textDown=")" style="@style/digit_button_style"
|
||||
calc:textDown=")"
|
||||
style="@style/digit_button_style"
|
||||
a:onClick="digitButtonClickHandler"/>
|
@ -10,5 +10,6 @@
|
||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||
a:id="@+id/squareBracketsButton" a:text="[]"
|
||||
calc:textUp="["
|
||||
calc:textDown="]" style="@style/digit_button_style"
|
||||
calc:textDown="]"
|
||||
style="@style/digit_button_style"
|
||||
a:onClick="digitButtonClickHandler"/>
|
@ -8,7 +8,7 @@
|
||||
|
||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||
a:id="@+id/varsButton"
|
||||
a:text="π,e,…"
|
||||
a:text="π,…"
|
||||
a:textStyle="italic"
|
||||
a:onClick="varsButtonClickHandler"
|
||||
style="@style/control_button_style"/>
|
29
res/layout/vars.xml
Normal file
29
res/layout/vars.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?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="match_parent"
|
||||
a:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
a:layout_width="match_parent"
|
||||
a:layout_height="match_parent"
|
||||
a:layout_weight="1"
|
||||
a:id="@android:id/list"/>
|
||||
|
||||
<Button
|
||||
a:layout_width="wrap_content"
|
||||
a:layout_height="wrap_content"
|
||||
a:layout_gravity="center_horizontal"
|
||||
a:text="@string/c_add"
|
||||
a:paddingLeft="40dp"
|
||||
a:paddingRight="40dp"
|
||||
a:onClick="addVarButtonClickHandler"/>
|
||||
|
||||
</LinearLayout>
|
@ -20,7 +20,7 @@
|
||||
|
||||
<!--ABOUT ACTIVITY-->
|
||||
<string name="c_copyright">Copyright (c) 2009-2011\n\n<b>Программа создана\nserso aka se.solovyev</b>\n\n
|
||||
Эта программа бесплатна и открыта.\nИсходный код может быть найден на \n<a href="https://github.com/serso/android_calculator">http://github.com</a>\n\n
|
||||
Эта программа с открытыми исходным кодом:\nон может быть найден на \n<a href="https://github.com/serso/android_calculator">http://github.com</a>\n\n
|
||||
За подробной информацией, пожалуйста,\nобращайтесь на почту\n<a href="mailto:se.solovyev@gmail.com">se.solovyev@gmail.com</a>\n
|
||||
или посетите сайт \n<a href="http://se.solovyev.org">http://se.solovyev.org</a>\n\n
|
||||
Если вы хотите поддержать проект материально\nвы можете сделать это через \n<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted">http://paypal.com</a>
|
||||
@ -55,9 +55,10 @@
|
||||
<string name="c_sys.var.cannot.be.changed">Системная переменная не может быть изменена!</string>
|
||||
|
||||
<string name="c_pi_description">Отношение длины окружности к диаметру</string>
|
||||
<string name="c_e_description">Вещесвтенное число, такое что производная функции f(x) = e^x в точке x = 0 равно 1
|
||||
</string>
|
||||
<string name="c_e_description">Вещесвтенное число, такое что производная функции f(x) = e^x в точке x = 0 равно 1</string>
|
||||
<string name="c_i_description">Мнимая единица, определённая как i^2 = −1</string>
|
||||
<string name="c_nan_description">Не число</string>
|
||||
<string name="c_infinity_description">Бесконечность</string>
|
||||
<string name="c_calc_editor_hint">Введите новое выражение</string>
|
||||
<string name="c_continue">Продолжить</string>
|
||||
<string name="c_press_to_copy">Нажмите для копирования</string>
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
<!--ABOUT ACTIVITY-->
|
||||
<string name="c_copyright">Copyright (c) 2009-2011\n\n<b>Created by serso aka se.solovyev</b>\n\n
|
||||
This program is free and open source.\nSource code can be found on\n<a href="https://github.com/serso/android_calculator">http://github.com</a>\n\n
|
||||
This program is open source:\nall source code can be found on\n<a href="https://github.com/serso/android_calculator">http://github.com</a>\n\n
|
||||
For more information please\ncontact the author by email\n<a href="mailto:se.solovyev@gmail.com">se.solovyev@gmail.com</a>
|
||||
\nor visit\n<a href="http://se.solovyev.org">http://se.solovyev.org</a>\n\n
|
||||
If you want to support the project\nyou can donate money via\n<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted">http://paypal.com</a>
|
||||
@ -29,8 +29,8 @@
|
||||
|
||||
<string name="c_undo">undo</string>
|
||||
<string name="c_redo">redo</string>
|
||||
<string name="c_clear">CE</string>
|
||||
<string name="c_erase">C</string>
|
||||
<string name="c_clear">clear all</string>
|
||||
<string name="c_erase">clear</string>
|
||||
<string name="c_paste">paste</string>
|
||||
<string name="c_vars">vars</string>
|
||||
|
||||
@ -60,6 +60,9 @@
|
||||
<string name="c_pi_description">Ratio of any circle\'s circumference to its diameter</string>
|
||||
<string name="c_e_description">Unique real number such that the value of the derivative (slope of the tangent line) of the function f(x) = e^x at the point x = 0 is equal to 1</string>
|
||||
<string name="c_i_description">Imaginary unit, defined such that i^2 = −1</string>
|
||||
<string name="c_nan_description">Not a number</string>
|
||||
<string name="c_infinity_description">Infinity</string>
|
||||
|
||||
<string name="c_calc_editor_hint">Enter new expression</string>
|
||||
<string name="c_press_to_copy">Press to copy</string>
|
||||
<string name="c_continue">Continue</string>
|
||||
|
@ -12,6 +12,7 @@
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:focusable">true</item>
|
||||
<item name="android:textSize">20dp</item>
|
||||
<item name="android:background">@drawable/button</item>
|
||||
<item name="android:layout_marginLeft">1dp</item>
|
||||
</style>
|
||||
@ -21,9 +22,8 @@
|
||||
</style>
|
||||
|
||||
<style name="control_button_style" parent="button_style"/>
|
||||
|
||||
<style name="button_small_style" parent="button_style">
|
||||
<item name="android:textSize">30dp</item>
|
||||
<style name="control_image_button_style" parent="control_button_style">
|
||||
<item name="android:padding">6dp</item>
|
||||
</style>
|
||||
|
||||
<style name="editor_style">
|
||||
|
@ -13,7 +13,8 @@ import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.widget.EditText;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.ParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
@ -24,10 +25,8 @@ public class CalculatorEditor extends EditText {
|
||||
|
||||
private boolean highlightText = true;
|
||||
|
||||
private final static int BASE_COLOUR = Color.WHITE;
|
||||
private final static int BASE_COLOUR_RED_COMPONENT = Color.red(BASE_COLOUR);
|
||||
private final static int BASE_COLOUR_GREEN_COMPONENT = Color.green(BASE_COLOUR);
|
||||
private final static int BASE_COLOUR_BLUE_COMPONENT = Color.blue(BASE_COLOUR);
|
||||
@NotNull
|
||||
private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE);
|
||||
|
||||
public CalculatorEditor(Context context) {
|
||||
super(context);
|
||||
@ -54,9 +53,7 @@ public class CalculatorEditor extends EditText {
|
||||
menu.removeItem(android.R.id.startSelectingText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void redraw() {
|
||||
public synchronized void redraw() {
|
||||
String text = getText().toString();
|
||||
|
||||
int selectionStart = getSelectionStart();
|
||||
@ -64,107 +61,24 @@ public class CalculatorEditor extends EditText {
|
||||
|
||||
if (highlightText) {
|
||||
|
||||
text = highlightText(text);
|
||||
Log.d(this.getClass().getName(), text);
|
||||
|
||||
try {
|
||||
text = textHighlighter.process(text);
|
||||
} catch (ParseException e) {
|
||||
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Log.d(this.getClass().getName(), text);
|
||||
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
||||
} else {
|
||||
super.setText(text, BufferType.EDITABLE);
|
||||
}
|
||||
|
||||
Log.d(this.getClass().getName(), getText().toString());
|
||||
setSelection(selectionStart, selectionEnd);
|
||||
}
|
||||
|
||||
private String highlightText(@NotNull final String text) {
|
||||
final String result;
|
||||
|
||||
int maxNumberOfOpenGroupSymbols = 0;
|
||||
int numberOfOpenGroupSymbols = 0;
|
||||
|
||||
final StringBuilder text1 = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
final MathType.Result mathType = MathType.getType(text, i);
|
||||
|
||||
switch (mathType.getMathType()) {
|
||||
case open_group_symbol:
|
||||
numberOfOpenGroupSymbols++;
|
||||
maxNumberOfOpenGroupSymbols = Math.max(maxNumberOfOpenGroupSymbols, numberOfOpenGroupSymbols);
|
||||
text1.append(text.charAt(i));
|
||||
break;
|
||||
case close_group_symbol:
|
||||
numberOfOpenGroupSymbols--;
|
||||
text1.append(text.charAt(i));
|
||||
break;
|
||||
case function:
|
||||
i = processHighlightedText(text1, i, mathType.getMatch(), "i");
|
||||
break;
|
||||
case constant:
|
||||
i = processHighlightedText(text1, i, mathType.getMatch(), "b");
|
||||
break;
|
||||
default:
|
||||
text1.append(text.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (maxNumberOfOpenGroupSymbols > 0) {
|
||||
|
||||
final StringBuilder text2 = new StringBuilder();
|
||||
|
||||
processBracketGroup(text2, text1.toString(), 0, 0, maxNumberOfOpenGroupSymbols);
|
||||
|
||||
Log.d(CalculatorEditor.class.getName(), text2.toString());
|
||||
|
||||
result = text2.toString();
|
||||
} else {
|
||||
result = text1.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String functionName, @NotNull String tag) {
|
||||
result.append("<").append(tag).append(">").append(functionName).append("</").append(tag).append(">");
|
||||
return i + functionName.length() - 1;
|
||||
}
|
||||
|
||||
private int processBracketGroup(@NotNull StringBuilder result, @NotNull String s, int i, int numberOfOpenings, int maxNumberOfGroups) {
|
||||
|
||||
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
||||
|
||||
for (; i < s.length(); i++) {
|
||||
char ch = s.charAt(i);
|
||||
|
||||
if (MathType.openGroupSymbols.contains(ch)) {
|
||||
result.append(ch);
|
||||
result.append("</font>");
|
||||
i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups);
|
||||
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
||||
if (i < s.length() && MathType.closeGroupSymbols.contains(s.charAt(i))) {
|
||||
result.append(s.charAt(i));
|
||||
}
|
||||
} else if (MathType.closeGroupSymbols.contains(ch)) {
|
||||
break;
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
result.append("</font>");
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private String getColor(int numberOfOpenGroupSymbols, int numberOfOpenings) {
|
||||
double c = 0.7;
|
||||
|
||||
int offset = ((int) (255 * c)) * numberOfOpenings / (numberOfOpenGroupSymbols + 1);
|
||||
|
||||
int result = Color.rgb(BASE_COLOUR_RED_COMPONENT - offset, BASE_COLOUR_GREEN_COMPONENT - offset, BASE_COLOUR_BLUE_COMPONENT - offset);
|
||||
|
||||
return "#" + Integer.toHexString(result).substring(2);
|
||||
}
|
||||
|
||||
public boolean isHighlightText() {
|
||||
return highlightText;
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ public class CalculatorVarsActivity extends ListActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.vars);
|
||||
|
||||
adapter = new VarsArrayAdapter(this, R.layout.var, R.id.var_text, new ArrayList<Var>(CalculatorModel.instance.getVarsRegister().getVars()));
|
||||
setListAdapter(adapter);
|
||||
|
||||
@ -68,6 +70,12 @@ public class CalculatorVarsActivity extends ListActivity {
|
||||
|
||||
}
|
||||
|
||||
@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()) {
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
||||
@NotNull
|
||||
private final MutableObject<Runnable> currentRunner = new MutableObject<Runnable>();
|
||||
|
||||
public void doTextOperation(@NotNull TextOperation operation) {
|
||||
public synchronized void doTextOperation(@NotNull TextOperation operation) {
|
||||
final String editorStateBefore = this.editor.getText().toString();
|
||||
|
||||
operation.doOperation(this.editor);
|
||||
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.graphics.Color;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.math.MathType;
|
||||
import org.solovyev.android.calculator.model.ParseException;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/12/11
|
||||
* Time: 9:47 PM
|
||||
*/
|
||||
public class TextHighlighter implements TextProcessor {
|
||||
|
||||
private final int color;
|
||||
private final int colorRed;
|
||||
private final int colorGreen;
|
||||
private final int colorBlue;
|
||||
|
||||
public TextHighlighter(int baseColor) {
|
||||
this.color = baseColor;
|
||||
this.colorRed = Color.red(baseColor);
|
||||
this.colorGreen = Color.green(baseColor);
|
||||
this.colorBlue = Color.blue(baseColor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String process(@NotNull String text) throws ParseException {
|
||||
final String result;
|
||||
|
||||
int maxNumberOfOpenGroupSymbols = 0;
|
||||
int numberOfOpenGroupSymbols = 0;
|
||||
|
||||
final StringBuilder text1 = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
final MathType.Result mathType = MathType.getType(text, i);
|
||||
|
||||
switch (mathType.getMathType()) {
|
||||
case open_group_symbol:
|
||||
numberOfOpenGroupSymbols++;
|
||||
maxNumberOfOpenGroupSymbols = Math.max(maxNumberOfOpenGroupSymbols, numberOfOpenGroupSymbols);
|
||||
text1.append(text.charAt(i));
|
||||
break;
|
||||
case close_group_symbol:
|
||||
numberOfOpenGroupSymbols--;
|
||||
text1.append(text.charAt(i));
|
||||
break;
|
||||
case function:
|
||||
i = processHighlightedText(text1, i, mathType.getMatch(), "i");
|
||||
break;
|
||||
case constant:
|
||||
i = processHighlightedText(text1, i, mathType.getMatch(), "b");
|
||||
break;
|
||||
default:
|
||||
text1.append(text.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (maxNumberOfOpenGroupSymbols > 0) {
|
||||
|
||||
final StringBuilder text2 = new StringBuilder();
|
||||
|
||||
String s = text1.toString();
|
||||
int i = processBracketGroup(text2, s, 0, 0, maxNumberOfOpenGroupSymbols);
|
||||
for (; i < s.length(); i++) {
|
||||
text2.append(s.charAt(i));
|
||||
}
|
||||
|
||||
//Log.d(CalculatorEditor.class.getName(), text2.toString());
|
||||
|
||||
result = text2.toString();
|
||||
} else {
|
||||
result = text1.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int processHighlightedText(@NotNull StringBuilder result, int i, @NotNull String functionName, @NotNull String tag) {
|
||||
result.append("<").append(tag).append(">").append(functionName).append("</").append(tag).append(">");
|
||||
return i + functionName.length() - 1;
|
||||
}
|
||||
|
||||
private int processBracketGroup(@NotNull StringBuilder result, @NotNull String s, int i, int numberOfOpenings, int maxNumberOfGroups) {
|
||||
|
||||
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
||||
|
||||
for (; i < s.length(); i++) {
|
||||
char ch = s.charAt(i);
|
||||
|
||||
if (MathType.openGroupSymbols.contains(ch)) {
|
||||
result.append(ch);
|
||||
result.append("</font>");
|
||||
i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups);
|
||||
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
||||
if (i < s.length() && MathType.closeGroupSymbols.contains(s.charAt(i))) {
|
||||
result.append(s.charAt(i));
|
||||
}
|
||||
} else if (MathType.closeGroupSymbols.contains(ch)) {
|
||||
break;
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
result.append("</font>");
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private String getColor(int totalNumberOfOpenings, int numberOfOpenings) {
|
||||
double c = 0.8;
|
||||
|
||||
int offset = ((int) (255 * c)) * numberOfOpenings / (totalNumberOfOpenings + 1);
|
||||
|
||||
// for tests:
|
||||
// innt result = Color.rgb(BASE_COLOUR_RED_COMPONENT - offset, BASE_COLOUR_GREEN_COMPONENT - offset, BASE_COLOUR_BLUE_COMPONENT - offset);
|
||||
int result = (0xFF << 24) | ((colorRed - offset) << 16) | ((colorGreen - offset) << 8) | (colorBlue - offset);
|
||||
|
||||
return "#" + Integer.toHexString(result).substring(2);
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ public class Functions {
|
||||
public final static String EXP = "exp";
|
||||
public final static String SQRT_SIGN = "√";
|
||||
public final static String SQRT = "sqrt";
|
||||
|
||||
public final static String E = "E";
|
||||
public final static String E_POWER = "10^";
|
||||
|
||||
|
@ -34,8 +34,11 @@ public enum MathType {
|
||||
public static final String IMAGINARY_NUMBER_DEF = "sqrt(-1)";
|
||||
public static final String PI = "π";
|
||||
public static final String E = "e";
|
||||
public final static String NAN = "NaN";
|
||||
public final static String INFINITY = "∞";
|
||||
public final static String INFINITY_DEF = "Infinity";
|
||||
|
||||
public static final List<String> constants = Arrays.asList(E, PI, IMAGINARY_NUMBER);
|
||||
public static final List<String> constants = Arrays.asList(E, PI, IMAGINARY_NUMBER, NAN, INFINITY);
|
||||
|
||||
public static final List<String> digits = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
|
||||
|
||||
|
@ -22,7 +22,12 @@ class FromJsclTextProcessor implements TextProcessor {
|
||||
@Override
|
||||
public String process(@NotNull String result) throws ParseException {
|
||||
try {
|
||||
result = String.valueOf(round(result));
|
||||
final Double roundedValue = round(result);
|
||||
if ( roundedValue.isInfinite() ) {
|
||||
result = MathType.INFINITY;
|
||||
} else {
|
||||
result = String.valueOf(roundedValue);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
if (result.contains(MathType.IMAGINARY_NUMBER_DEF)) {
|
||||
try {
|
||||
|
@ -144,7 +144,7 @@ class VarsRegisterImpl implements VarsRegister {
|
||||
final Var.Builder builder;
|
||||
final Integer varDescription;
|
||||
|
||||
if ( systemVarName.equals(MathType.E) ){
|
||||
if (systemVarName.equals(MathType.E)) {
|
||||
builder = new Var.Builder(systemVarName, Math.E);
|
||||
varDescription = R.string.c_e_description;
|
||||
} else if (systemVarName.equals(MathType.PI)) {
|
||||
@ -153,6 +153,12 @@ class VarsRegisterImpl implements VarsRegister {
|
||||
} else if (systemVarName.equals(MathType.IMAGINARY_NUMBER)) {
|
||||
builder = new Var.Builder(systemVarName, MathType.IMAGINARY_NUMBER_DEF);
|
||||
varDescription = R.string.c_i_description;
|
||||
} else if (systemVarName.equals(MathType.NAN)) {
|
||||
builder = new Var.Builder(systemVarName, MathType.NAN);
|
||||
varDescription = R.string.c_nan_description;
|
||||
} else if (systemVarName.equals(MathType.INFINITY)) {
|
||||
builder = new Var.Builder(systemVarName, MathType.INFINITY_DEF);
|
||||
varDescription = R.string.c_infinity_description;
|
||||
} else {
|
||||
throw new IllegalArgumentException(systemVarName + " is not supported yet!");
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.Button;
|
||||
@ -33,6 +34,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.view.FontSizeAdjuster;
|
||||
import org.solovyev.common.utils.Point2d;
|
||||
import org.solovyev.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* NOTE: copied from com.android.calculator2.ColorButton
|
||||
@ -42,14 +44,15 @@ import org.solovyev.common.utils.Point2d;
|
||||
* Button with click-animation effect.
|
||||
*/
|
||||
public class ColorButton extends Button {
|
||||
int CLICK_FEEDBACK_COLOR;
|
||||
static final int CLICK_FEEDBACK_INTERVAL = 10;
|
||||
static final int CLICK_FEEDBACK_DURATION = 350;
|
||||
|
||||
private int CLICK_FEEDBACK_COLOR;
|
||||
private static final int CLICK_FEEDBACK_INTERVAL = 10;
|
||||
private static final int CLICK_FEEDBACK_DURATION = 350;
|
||||
|
||||
@NotNull
|
||||
private Point2d textPosition;
|
||||
private long mAnimStart;
|
||||
private Paint mFeedbackPaint;
|
||||
private long animationStart;
|
||||
private Paint feedbackPaint;
|
||||
|
||||
public ColorButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, true);
|
||||
@ -66,12 +69,12 @@ public class ColorButton extends Button {
|
||||
Resources res = getResources();
|
||||
|
||||
CLICK_FEEDBACK_COLOR = res.getColor(org.solovyev.android.calculator.R.color.magic_flame);
|
||||
mFeedbackPaint = new Paint();
|
||||
mFeedbackPaint.setStyle(Style.STROKE);
|
||||
mFeedbackPaint.setStrokeWidth(2);
|
||||
feedbackPaint = new Paint();
|
||||
feedbackPaint.setStyle(Style.STROKE);
|
||||
feedbackPaint.setStrokeWidth(2);
|
||||
getPaint().setColor(res.getColor(R.color.button_text_color));
|
||||
|
||||
mAnimStart = -1;
|
||||
animationStart = -1;
|
||||
|
||||
if (context instanceof FontSizeAdjuster) {
|
||||
((FontSizeAdjuster) context).adjustFontSize(this);
|
||||
@ -113,17 +116,17 @@ public class ColorButton extends Button {
|
||||
int alpha = 255 - 255 * duration / CLICK_FEEDBACK_DURATION;
|
||||
int color = CLICK_FEEDBACK_COLOR | (alpha << 24);
|
||||
|
||||
mFeedbackPaint.setColor(color);
|
||||
canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, mFeedbackPaint);
|
||||
feedbackPaint.setColor(color);
|
||||
canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, feedbackPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
if (mAnimStart != -1) {
|
||||
int animDuration = (int) (System.currentTimeMillis() - mAnimStart);
|
||||
if (animationStart != -1) {
|
||||
int animDuration = (int) (System.currentTimeMillis() - animationStart);
|
||||
|
||||
if (animDuration >= CLICK_FEEDBACK_DURATION) {
|
||||
mAnimStart = -1;
|
||||
animationStart = -1;
|
||||
} else {
|
||||
drawMagicFlame(animDuration, canvas);
|
||||
postInvalidateDelayed(CLICK_FEEDBACK_INTERVAL);
|
||||
@ -131,13 +134,48 @@ public class ColorButton extends Button {
|
||||
}
|
||||
|
||||
CharSequence text = getText();
|
||||
if (text != null && textPosition != null) {
|
||||
if (!StringUtils.isEmpty(text) && textPosition != null) {
|
||||
canvas.drawText(text, 0, text.length(), textPosition.getX(), textPosition.getY(), getPaint());
|
||||
} else {
|
||||
drawDrawables(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDrawables(Canvas canvas) {
|
||||
final int compoundPaddingLeft = getCompoundPaddingLeft();
|
||||
final int compoundPaddingTop = getCompoundPaddingTop();
|
||||
final int compoundPaddingRight = getCompoundPaddingRight();
|
||||
final int compoundPaddingBottom = getCompoundPaddingBottom();
|
||||
|
||||
final int scrollX = getScrollX();
|
||||
final int scrollY = getScrollY();
|
||||
|
||||
final int right = getRight();
|
||||
final int left = getLeft();
|
||||
final int bottom = getBottom();
|
||||
final int top = getTop();
|
||||
|
||||
final Drawable[] drawables = getCompoundDrawables();
|
||||
if (drawables != null) {
|
||||
|
||||
int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop;
|
||||
int hspace = right - left - compoundPaddingRight - compoundPaddingLeft;
|
||||
|
||||
Drawable topDr = drawables[1];
|
||||
// IMPORTANT: The coordinates computed are also used in invalidateDrawable()
|
||||
// Make sure to update invalidateDrawable() when changing this code.
|
||||
if (topDr != null) {
|
||||
canvas.save();
|
||||
canvas.translate(scrollX + compoundPaddingLeft + (hspace - topDr.getBounds().width()) / 2,
|
||||
scrollY + getPaddingTop() + vspace / 2);
|
||||
topDr.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void animateClickFeedback() {
|
||||
mAnimStart = System.currentTimeMillis();
|
||||
animationStart = System.currentTimeMillis();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
@ -126,11 +126,10 @@ public class DirectionDragButton extends DragButton {
|
||||
|
||||
basePaint.measureText(StringUtils.getNotEmpty(baseText, "|"));
|
||||
|
||||
float height = h - basePaint.ascent() - basePaint.descent();
|
||||
if (direction < 0) {
|
||||
result.setY(height / 2 + height / 3 + selfHeight);
|
||||
result.setY(h / 2 + h / 3 - selfHeight / 2);
|
||||
} else {
|
||||
result.setY(height / 2 - height / 3);
|
||||
result.setY(h / 2 - h / 3 - selfHeight / 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -158,7 +157,7 @@ public class DirectionDragButton extends DragButton {
|
||||
|
||||
upDownTextPaint = new TextPaint(paint);
|
||||
upDownTextPaint.setAlpha(150);
|
||||
upDownTextPaint.setTextSize(paint.getTextSize() / 2);
|
||||
upDownTextPaint.setTextSize(paint.getTextSize() / 3);
|
||||
}
|
||||
|
||||
private String getStyledUpDownText(@Nullable String text) {
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
import org.solovyev.android.calculator.model.TextProcessor;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 10/12/11
|
||||
* Time: 10:07 PM
|
||||
*/
|
||||
public class TextHighlighterTest {
|
||||
|
||||
@Test
|
||||
public void testProcess() throws Exception {
|
||||
final TextProcessor textHighlighter = new TextHighlighter(0);
|
||||
|
||||
final Random random = new Random(new Date().getTime());
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int j = 0; j < 1000; j++) {
|
||||
sb.append(random.nextBoolean() ? "(" : ")");
|
||||
}
|
||||
try {
|
||||
textHighlighter.process(sb.toString());
|
||||
} catch (Exception e) {
|
||||
System.out.println(sb.toString());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals("<font color=\"#000000\"></font>)(((())())", textHighlighter.process(")(((())())"));
|
||||
Assert.assertEquals(")", textHighlighter.process(")"));
|
||||
Assert.assertEquals(")()(", textHighlighter.process(")()("));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user