This commit is contained in:
serso 2011-10-09 20:22:44 +04:00
parent aee46bb4e3
commit aef150f173
23 changed files with 354 additions and 121 deletions

View File

@ -1,27 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:a="http://schemas.android.com/apk/res/android"
package="org.solovyev.android.calculator"
versionCode="1"
versionName="1.0">
package="org.solovyev.android.calculator"
versionCode="1"
versionName="1.0">
<uses-sdk a:minSdkVersion="8"/>
<application a:icon="@drawable/icon" a:label="@string/c_app_name">
<application a:icon="@drawable/icon" a:label="@string/c_app_name">
<activity a:name=".CalculatorActivity" a:label="@string/c_app_name">
<intent-filter>
<action a:name="android.intent.action.MAIN" />
<category a:name="android.intent.category.LAUNCHER" />
<activity a:name=".CalculatorActivity"
a:windowSoftInputMode="stateHidden"
a:label="@string/c_app_name">
<intent-filter>
<action a:name="android.intent.action.MAIN"/>
<category a:name="android.intent.category.LAUNCHER"/>
<action a:name="org.solovyev.android.calculator.CalculatorActivity.insertText"/>
</intent-filter>
</activity>
</intent-filter>
</activity>
<activity a:name=".CalculatorPreferencesActivity" a:label="@string/c_app_settings"/>
<activity a:name=".AboutActivity" a:label="@string/c_about"/>
<activity a:name=".CalculatorVarsActivity"
a:label="@string/c_vars_and_constants"
a:configChanges="orientation|keyboardHidden" />
<activity a:name=".CalculatorPreferencesActivity"
a:label="@string/c_app_settings"/>
</application>
<activity a:name=".AboutActivity"
a:label="@string/c_about"/>
<activity a:name=".CalculatorVarsActivity"
a:label="@string/c_vars_and_constants"
a:configChanges="orientation|keyboardHidden"/>
</application>
</manifest>

BIN
res/drawable/copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
res/drawable/heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -17,73 +17,68 @@
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/leftButton"
calc:textUp="↞"
a:text="←"
a:layout_weight="1.5"
style="@style/control_button_style"
a:onClick="moveLeftButtonClickHandler"/>
<include layout="@layout/calc_left_button"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1.5"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/eraseButton"
a:text="@string/c_erase"
a:layout_weight="1.5"
style="@style/control_button_style"
a:onClick="eraseButtonClickHandler"/>
<include layout="@layout/calc_display"/>
<include layout="@layout/calc_erase_button"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1.5"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/clearButton"
a:text="@string/c_clear"
a:layout_weight="1.5"
style="@style/control_button_style"
a:onClick="clearButtonClickHandler"/>
<include layout="@layout/calc_display"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:id="@+id/rightButton"
calc:textUp="↠"
a:text="→"
a:layout_weight="1.5"
style="@style/control_button_style"
a:onClick="moveRightButtonClickHandler"/>
<include layout="@layout/calc_clear_button"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1.5"/>
<include layout="@layout/calc_right_button"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1.5"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<include layout="@layout/calc_equals_button"/>
<include layout="@layout/calc_paste_button"/>
<include layout="@layout/calc_one_digit_button"/>
<include layout="@layout/calc_two_digit_button"/>
<include layout="@layout/calc_three_digit_button"/>
<include layout="@layout/calc_multiplication_button"/>
<include layout="@layout/calc_division_button"/>
<include layout="@layout/calc_equals_button"/>
<include layout="@layout/calc_paste_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<include layout="@layout/calc_history_button"/>
<include layout="@layout/calc_copy_button"/>
<include layout="@layout/calc_four_digit_button"/>
<include layout="@layout/calc_five_digit_button"/>
<include layout="@layout/calc_six_digit_button"/>
<include layout="@layout/calc_plus_button"/>
<include layout="@layout/calc_subtraction_button"/>
<include layout="@layout/calc_square_brackets_button"/>
<include layout="@layout/calc_history_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<include layout="@layout/calc_vars_button"/>
<include layout="@layout/calc_square_brackets_button"/>
<include layout="@layout/calc_seven_digit_button"/>
<include layout="@layout/calc_eight_digit_button"/>
<include layout="@layout/calc_nine_digit_button"/>
<include layout="@layout/calc_zero_digit_button"/>
<include layout="@layout/calc_round_brackets_button"/>
<include layout="@layout/calc_vars_button"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
</LinearLayout>

View File

@ -17,15 +17,15 @@
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
<org.solovyev.android.view.widgets.DirectionDragButton
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/equalsButton"
a:text="="
a:layout_weight="4"
style="@style/control_button_style"
a:onClick="numericButtonClickHandler"/>
<include layout="@layout/calc_equals_button"
a:layout_weight="4"
a:layout_height="match_parent"
a:layout_width="match_parent" />
<include layout="@layout/calc_display"/>
<include layout="@layout/calc_display"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:layout_weight="1"/>
</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_history_button"/>
<include layout="@layout/calc_copy_button"/>
</LinearLayout>
@ -75,11 +75,8 @@
<include layout="@layout/calc_left_button"/>
<include layout="@layout/calc_right_button"/>
<include layout="@layout/calc_vars_button"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
<org.solovyev.android.view.widgets.DirectionDragButton a:text="" style="@style/control_button_style"/>
<include layout="@layout/calc_donate_button"/>
<include layout="@layout/calc_history_button"/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,15 @@
<?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
-->
<ImageButton 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:onClick="copyButtonClickHandler"/>

View File

@ -8,7 +8,7 @@
<org.solovyev.android.calculator.CalculatorDisplay
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/resultEditText"
a:id="@+id/calculatorDisplay"
style="@style/display_style"
a:layout_weight="1"
a:minLines="1"

View File

@ -0,0 +1,15 @@
<?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
-->
<ImageButton 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/heart"
style="@style/control_button_style"
a:padding="6dp"
a:onClick="donateButtonClickHandler"/>

View File

@ -12,7 +12,7 @@
a:layout_height="0dp">
<org.solovyev.android.calculator.CalculatorEditor
a:id="@+id/editText"
a:id="@+id/calculatorEditor"
style="@style/editor_style"
a:inputType="textMultiLine"
a:maxLines="4"

View File

@ -55,4 +55,5 @@
<string name="c_pi_description">Отношение длины окружности к диаметру</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_calc_editor_hint">Введите новое выражение</string>
</resources>

View File

@ -58,5 +58,6 @@
<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_calc_editor_hint"></string>
<string name="c_calc_editor_hint">Enter new expression</string>
<string name="c_press_to_copy">Press to copy</string>
</resources>

View File

@ -7,6 +7,7 @@ package org.solovyev.android.calculator;
import android.app.Activity;
import android.content.*;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.ClipboardManager;
@ -100,6 +101,9 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
}
private void init() {
calculatorView = new CalculatorView(this, CalculatorModel.instance);
insertTextReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@ -128,9 +132,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
// todo serso: create serso runtime exception
throw new RuntimeException("Could not initialize interpreter!");
}
this.calculatorView = new CalculatorView(this, CalculatorModel.instance);
initialized = true;
}
}
@ -191,6 +192,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
});
}
@SuppressWarnings({"UnusedDeclaration"})
public void copyButtonClickHandler(@NotNull View v) {
calculatorView.copyResult(this);
}
@SuppressWarnings({"UnusedDeclaration"})
public void clearButtonClickHandler(@NotNull View v) {
calculatorView.clear();
@ -207,6 +213,14 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
startActivity(new Intent(this, CalculatorVarsActivity.class));
}
@SuppressWarnings({"UnusedDeclaration"})
public void donateButtonClickHandler(@NotNull View v) {
final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=android%2ecalculator%40se%2esolovyev&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted";
final Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(paypalDonateUrl));
startActivity(i);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {

View File

@ -5,6 +5,7 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@ -12,19 +13,24 @@ import org.jetbrains.annotations.Nullable;
* Date: 9/17/11
* Time: 11:05 PM
*/
public class CalculatorDisplayHistoryState extends EditorHistoryState {
public class CalculatorDisplayHistoryState {
private boolean valid = true;
@NotNull
private final EditorHistoryState editorHistoryState;
public CalculatorDisplayHistoryState() {
this.editorHistoryState = new EditorHistoryState();
}
public CalculatorDisplayHistoryState(boolean valid) {
this.editorHistoryState = new EditorHistoryState();
this.valid = valid;
}
public CalculatorDisplayHistoryState(int cursorPosition, @Nullable String text, boolean valid) {
super(cursorPosition, text);
this.editorHistoryState = new EditorHistoryState(cursorPosition, text);
this.valid = valid;
}
@ -35,4 +41,29 @@ public class CalculatorDisplayHistoryState extends EditorHistoryState {
public void setValid(boolean valid) {
this.valid = valid;
}
public EditorHistoryState getEditorHistoryState() {
return editorHistoryState;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CalculatorDisplayHistoryState)) return false;
CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o;
if (valid != that.valid) return false;
if (editorHistoryState != null ? !editorHistoryState.equals(that.editorHistoryState) : that.editorHistoryState != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = (valid ? 1 : 0);
result = 31 * result + (editorHistoryState != null ? editorHistoryState.hashCode() : 0);
return result;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.common.utils.history.HistoryAction;
import org.solovyev.common.utils.history.HistoryHelper;
import org.solovyev.common.utils.history.SimpleHistoryHelper;
/**
* User: serso
* Date: 10/9/11
* Time: 6:35 PM
*/
public enum CalculatorHistory implements HistoryHelper<CalculatorHistoryState> {
instance;
private final HistoryHelper<CalculatorHistoryState> historyHelper = new SimpleHistoryHelper<CalculatorHistoryState>();
@Override
public boolean isEmpty() {
return this.historyHelper.isEmpty();
}
@Override
public CalculatorHistoryState getLastHistoryState() {
return this.historyHelper.getLastHistoryState();
}
@Override
public boolean isUndoAvailable() {
return historyHelper.isUndoAvailable();
}
@Override
public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) {
return historyHelper.undo(currentState);
}
@Override
public boolean isRedoAvailable() {
return historyHelper.isRedoAvailable();
}
@Override
public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) {
return historyHelper.redo(currentState);
}
@Override
public boolean isActionAvailable(@NotNull HistoryAction historyAction) {
return historyHelper.isActionAvailable(historyAction);
}
@Override
public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) {
return historyHelper.doAction(historyAction, currentState);
}
@Override
public void addState(@Nullable CalculatorHistoryState currentState) {
historyHelper.addState(currentState);
}
}

View File

@ -6,6 +6,7 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.text.ClipboardManager;
import android.util.Log;
@ -21,11 +22,10 @@ import org.solovyev.android.calculator.model.CalculatorModel;
import org.solovyev.android.calculator.model.ParseException;
import org.solovyev.android.view.CursorControl;
import org.solovyev.android.view.HistoryControl;
import org.solovyev.android.view.widgets.SoftKeyboardDisabler;
import org.solovyev.common.utils.MutableObject;
import org.solovyev.common.utils.StringUtils;
import org.solovyev.common.utils.history.HistoryAction;
import org.solovyev.common.utils.history.HistoryHelper;
import org.solovyev.common.utils.history.SimpleHistoryHelper;
/**
* User: serso
@ -46,35 +46,43 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
@NotNull
private final CalculatorModel calculatorModel;
@NotNull
private final HistoryHelper<CalculatorHistoryState> history;
public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) {
this.calculatorModel = calculator;
this.editor = (CalculatorEditor) activity.findViewById(R.id.editText);
this.editor = (CalculatorEditor) activity.findViewById(R.id.calculatorEditor);
this.editor.setOnTouchListener(new SoftKeyboardDisabler());
this.display = (CalculatorDisplay) activity.findViewById(R.id.resultEditText);
this.display = (CalculatorDisplay) activity.findViewById(R.id.calculatorDisplay);
this.display.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (((CalculatorDisplay) v).isValid()) {
final CharSequence text = ((TextView) v).getText();
if (!StringUtils.isEmpty(text)) {
final ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
clipboard.setText(text);
Toast.makeText(activity, activity.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
}
}
copyResult(activity);
}
});
this.history = new SimpleHistoryHelper<CalculatorHistoryState>();
saveHistoryState();
final CalculatorHistoryState lastState = CalculatorHistory.instance.getLastHistoryState();
if ( lastState == null ) {
saveHistoryState();
} else {
setCurrentHistoryState(lastState);
}
}
public void copyResult(@NotNull Context context) {
if (display.isValid()) {
final CharSequence text = display.getText();
if (!StringUtils.isEmpty(text)) {
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
clipboard.setText(text);
Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show();
}
}
}
private void saveHistoryState() {
history.addState(getCurrentHistoryState());
CalculatorHistory.instance.addState(getCurrentHistoryState());
}
@ -117,14 +125,14 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
// allow only one runner at one time
synchronized (currentRunner) {
//lock all operations with history
synchronized (history) {
synchronized (CalculatorHistory.instance) {
// do only if nothing was post delayed before current instance was posted
if (currentRunner.getObject() == this) {
// actually nothing shall be logged while text operations are done
evaluate(editorStateAfter);
if (history.isUndoAvailable()) {
history.undo(getCurrentHistoryState());
if (CalculatorHistory.instance.isUndoAvailable()) {
CalculatorHistory.instance.undo(getCurrentHistoryState());
}
saveHistoryState();
@ -212,9 +220,9 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
@Override
public void doHistoryAction(@NotNull HistoryAction historyAction) {
synchronized (history) {
if (history.isActionAvailable(historyAction)) {
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
synchronized (CalculatorHistory.instance) {
if (CalculatorHistory.instance.isActionAvailable(historyAction)) {
final CalculatorHistoryState newState = CalculatorHistory.instance.doAction(historyAction, getCurrentHistoryState());
if (newState != null) {
setCurrentHistoryState(newState);
}
@ -224,7 +232,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
@Override
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
synchronized (history) {
synchronized (CalculatorHistory.instance) {
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
@ -233,7 +241,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
}
private void setValuesFromHistory(@NotNull CalculatorDisplay display, CalculatorDisplayHistoryState editorHistoryState) {
setValuesFromHistory(display, (EditorHistoryState)editorHistoryState);
setValuesFromHistory(display, editorHistoryState.getEditorHistoryState());
display.setValid(editorHistoryState.isValid());
}
@ -247,7 +255,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
@Override
@NotNull
public CalculatorHistoryState getCurrentHistoryState() {
synchronized (history) {
synchronized (CalculatorHistory.instance) {
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getCalculatorDisplayHistoryState(this.display));
}
}
@ -264,8 +272,8 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
private CalculatorDisplayHistoryState getCalculatorDisplayHistoryState(@NotNull CalculatorDisplay display) {
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
result.setText(String.valueOf(display.getText()));
result.setCursorPosition(display.getSelectionStart());
result.getEditorHistoryState().setText(String.valueOf(display.getText()));
result.getEditorHistoryState().setCursorPosition(display.getSelectionStart());
result.setValid(display.isValid());
return result;

View File

@ -39,5 +39,23 @@ public class EditorHistoryState {
return cursorPosition;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EditorHistoryState)) return false;
EditorHistoryState that = (EditorHistoryState) o;
if (cursorPosition != that.cursorPosition) return false;
if (text != null ? !text.equals(that.text) : that.text != null) return false;
return true;
}
@Override
public int hashCode() {
int result = cursorPosition;
result = 31 * result + (text != null ? text.hashCode() : 0);
return result;
}
}

View File

@ -37,11 +37,13 @@ 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^";
public static final List<String> allPrefix;
static {
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP));
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP, E));
Collections.sort(functions, new MathEntityComparator());
allPrefix = functions;
}

View File

@ -39,10 +39,10 @@ class ToJsclTextProcessor implements TextProcessor {
sb.append(')');
} else if (ch == '×' || ch == '∙') {
sb.append("*");
} else if ( mathType == MathType.function ){
} else if (mathType == MathType.function) {
sb.append(toJsclFunction(mathTypeResult.getMatch()));
i += mathTypeResult.getMatch().length() - 1;
} else if ( mathType == MathType.constant ) {
} else if (mathType == MathType.constant) {
sb.append(mathTypeResult.getMatch());
i += mathTypeResult.getMatch().length() - 1;
} else {
@ -148,6 +148,8 @@ class ToJsclTextProcessor implements TextProcessor {
result = Functions.LOG;
} else if (function.equals(Functions.SQRT_SIGN)) {
result = Functions.SQRT;
} else if (function.equals(Functions.E)) {
result = Functions.E_POWER;
} else {
result = function;
}
@ -178,9 +180,9 @@ class ToJsclTextProcessor implements TextProcessor {
@NotNull
private static MathType.Result checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb,
@NotNull String s,
int i,
@Nullable MathType.Result mathTypeBeforeResult) {
@NotNull String s,
int i,
@Nullable MathType.Result mathTypeBeforeResult) {
MathType.Result result = MathType.getType(s, i);
if (i > 0) {

View File

@ -13,8 +13,6 @@ import android.text.TextPaint;
import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.view.widgets.DragButton;
import org.solovyev.android.view.widgets.DragDirection;
import org.solovyev.common.utils.Point2d;
import org.solovyev.common.utils.StringUtils;
@ -101,11 +99,11 @@ public class DirectionDragButton extends DragButton {
initUpDownTextPaint(basePaint);
if (textUp != null) {
textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, 1);
textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, getText(), 1, getWidth(), getHeight());
}
if (textDown != null) {
textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, -1);
textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, getText(), -1, getWidth(), getHeight());
}
if ( textDownPosition != null && textUpPosition != null ) {
@ -118,21 +116,21 @@ public class DirectionDragButton extends DragButton {
}
private Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, float direction) {
public static Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, CharSequence baseText, float direction, int w, int h) {
final Point2d result = new Point2d();
float width = paint.measureText(text.toString() + " ");
result.setX(getWidth() - width);
result.setX(w - width);
float selfHeight = paint.ascent() + paint.descent();
basePaint.measureText(StringUtils.getNotEmpty(getText(), "|"));
basePaint.measureText(StringUtils.getNotEmpty(baseText, "|"));
float height = getHeight() - basePaint.ascent() - basePaint.descent();
float height = h - basePaint.ascent() - basePaint.descent();
if (direction < 0) {
result.setY(height / 2 - direction * height / 3 + selfHeight);
result.setY(height / 2 + height / 3 + selfHeight);
} else {
result.setY(height / 2 - direction * height / 3);
result.setY(height / 2 - height / 3);
}
return result;

View File

@ -0,0 +1,50 @@
/*
* 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.widgets;
import android.text.InputType;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
/**
* User: serso
* Date: 10/9/11
* Time: 4:27 PM
*/
public class SoftKeyboardDisabler implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean result;
Log.d(this.getClass().getName(), "org.solovyev.android.view.widgets.SoftKeyboardDisabler.onTouch(): action=" + event.getAction() + ", event=" + event);
if (v instanceof EditText) {
final EditText editText = (EditText) v;
int inputType = editText.getInputType();
int selectionStart = editText.getSelectionStart();
int selectionEnd = editText.getSelectionEnd();
// disable soft input
editText.setInputType(InputType.TYPE_NULL);
editText.onTouchEvent(event);
// restore input type
editText.setInputType(inputType);
editText.setSelection(selectionStart, selectionEnd);
result = true;
} else {
result = false;
}
return result;
}
}

View File

@ -7,6 +7,7 @@
package org.solovyev.android.calculator.model;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
@ -16,16 +17,23 @@ import org.junit.Test;
*/
public class ToJsclPreprocessorTest {
@BeforeClass
public static void setUp() throws Exception {
CalculatorModel.instance.init(null);
}
@Test
public void testProcess() throws Exception {
final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor();
Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)"));
Assert.assertEquals( "pi*sin(4)*pi*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))"));
Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))"));
Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))"));
Assert.assertEquals( "pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))"));
Assert.assertEquals( "exp(1)^pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))"));
Assert.assertEquals( "3.141592653589793*sin(4)*3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))"));
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))"));
Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))"));
Assert.assertEquals( "3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))"));
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))"));
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2"));
Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2"));
}
@Test
@ -44,7 +52,7 @@ public class ToJsclPreprocessorTest {
Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+(5.4434234*sin(5.1+1))!", 26));
Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5)!", 5));
Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5sin(5sin(5)))!", 17));
Assert.assertEquals(1, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19));
Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29));
Assert.assertEquals(2, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19));
Assert.assertEquals(5, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29));
}
}