calculator refactor
This commit is contained in:
parent
ae848bafb2
commit
a58c37eb75
@ -1,59 +1,42 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.text.ClipboardManager;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.*;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import bsh.EvalError;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.view.*;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.InputType;
|
||||
import android.util.TypedValue;
|
||||
import android.view.*;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.view.*;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.MathEntityType;
|
||||
|
||||
import bsh.EvalError;
|
||||
import bsh.Interpreter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.EditText;
|
||||
import org.solovyev.util.math.MathUtils;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
|
||||
public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
|
||||
private static final int HVGA_WIDTH_PIXELS = 320;
|
||||
|
||||
@NotNull
|
||||
private EditText editText;
|
||||
|
||||
@NotNull
|
||||
private TextView resultEditText;
|
||||
|
||||
@NotNull
|
||||
private Interpreter interpreter;
|
||||
|
||||
@NotNull
|
||||
private HistoryHelper<CalculatorHistoryState> historyHelper;
|
||||
|
||||
@NotNull
|
||||
private BroadcastReceiver preferencesChangesReceiver;
|
||||
|
||||
@NotNull
|
||||
private List<SimpleOnDragListener> onDragListeners = new ArrayList<SimpleOnDragListener>();
|
||||
|
||||
@NotNull
|
||||
private CalculatorView view;
|
||||
|
||||
@NotNull
|
||||
private CalculatorModel calculator;
|
||||
|
||||
/**
|
||||
* Called when the activity is first created.
|
||||
*/
|
||||
@ -62,25 +45,14 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
this.editText = (EditText) findViewById(R.id.editText);
|
||||
this.editText.setInputType(InputType.TYPE_NULL);
|
||||
imm.hideSoftInputFromWindow(this.editText.getWindowToken(), 0);
|
||||
|
||||
this.resultEditText = (TextView) findViewById(R.id.resultEditText);
|
||||
this.resultEditText.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final CharSequence text = ((TextView) v).getText();
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
clipboard.setText(text);
|
||||
Toast.makeText(CalculatorActivity.this, "Result copied to clipboard!", Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
this.calculator = new CalculatorModel();
|
||||
} catch (EvalError evalError) {
|
||||
// todo serso: create serso runtime exception
|
||||
throw new RuntimeException("Could not initialize interpreter!");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.view = new CalculatorView(this, this.calculator);
|
||||
|
||||
final DragButtonCalibrationActivity.Preferences dragPreferences = DragButtonCalibrationActivity.getPreferences(this);
|
||||
|
||||
@ -88,7 +60,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
@Override
|
||||
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
|
||||
assert dragButton instanceof DirectionDragButton;
|
||||
processButtonAction(dragButton, getActionText((DirectionDragButton) dragButton, dragDirection));
|
||||
view.processButtonAction(getActionText((DirectionDragButton) dragButton, dragDirection));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -127,9 +99,9 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
if (dragButton instanceof DirectionDragButton) {
|
||||
String text = ((DirectionDragButton) dragButton).getText(dragDirection);
|
||||
if ("↞".equals(text)) {
|
||||
CalculatorActivity.this.editText.setSelection(0);
|
||||
CalculatorActivity.this.view.setCursorOnStart();
|
||||
} else if ("↠".equals(text)) {
|
||||
CalculatorActivity.this.editText.setSelection(CalculatorActivity.this.editText.getText().length());
|
||||
CalculatorActivity.this.view.setCursorOnEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,18 +112,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
|
||||
onDragListeners.add(toPositionOnDragListener);
|
||||
|
||||
this.interpreter = new Interpreter();
|
||||
|
||||
try {
|
||||
interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
|
||||
} catch (EvalError e) {
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
|
||||
this.historyHelper = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
saveHistoryState();
|
||||
|
||||
this.preferencesChangesReceiver = new BroadcastReceiver() {
|
||||
final BroadcastReceiver preferencesChangesReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
@ -164,94 +126,67 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
}
|
||||
};
|
||||
|
||||
registerReceiver(this.preferencesChangesReceiver, new IntentFilter(DragButtonCalibrationActivity.INTENT_ACTION));
|
||||
}
|
||||
|
||||
private void saveHistoryState() {
|
||||
historyHelper.addState(getCurrentHistoryState());
|
||||
registerReceiver(preferencesChangesReceiver, new IntentFilter(DragButtonCalibrationActivity.INTENT_ACTION));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void elementaryButtonClickHandler(@NotNull View v) {
|
||||
eval(JsclOperation.elementary, true);
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void numericButtonClickHandler(@NotNull View v) {
|
||||
eval(JsclOperation.numeric, true);
|
||||
this.view.evaluate();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void eraseButtonClickHandler(@NotNull View v) {
|
||||
if (editText.getSelectionStart() > 0) {
|
||||
editText.getText().delete(editText.getSelectionStart() - 1, editText.getSelectionStart());
|
||||
saveHistoryState();
|
||||
view.doTextOperation(new CalculatorView.TextOperation() {
|
||||
@Override
|
||||
public void doOperation(@NotNull EditText editor) {
|
||||
if (editor.getSelectionStart() > 0) {
|
||||
editor.getText().delete(editor.getSelectionStart() - 1, editor.getSelectionStart());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void simplifyButtonClickHandler(@NotNull View v) {
|
||||
eval(JsclOperation.simplify, true);
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void moveLeftButtonClickHandler(@NotNull View v) {
|
||||
if (editText.getSelectionStart() > 0) {
|
||||
editText.setSelection(editText.getSelectionStart() - 1);
|
||||
}
|
||||
view.moveCursorLeft();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void moveRightButtonClickHandler(@NotNull View v) {
|
||||
if (editText.getSelectionStart() < editText.getText().length()) {
|
||||
editText.setSelection(editText.getSelectionStart() + 1);
|
||||
}
|
||||
view.moveCursorRight();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void pasteButtonClickHandler(@NotNull View v) {
|
||||
view.doTextOperation(new CalculatorView.TextOperation() {
|
||||
@Override
|
||||
public void doOperation(@NotNull EditText editor) {
|
||||
final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
if (clipboard.hasText()) {
|
||||
editText.getText().insert(editText.getSelectionStart(), clipboard.getText());
|
||||
eval(JsclOperation.numeric, false);
|
||||
saveHistoryState();
|
||||
editor.getText().insert(editor.getSelectionStart(), clipboard.getText());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void clearButtonClickHandler(@NotNull View v) {
|
||||
if (!StringUtils.isEmpty(editText.getText()) || !StringUtils.isEmpty(resultEditText.getText())) {
|
||||
editText.getText().clear();
|
||||
resultEditText.setText("");
|
||||
saveHistoryState();
|
||||
}
|
||||
}
|
||||
|
||||
private void eval(@NotNull JsclOperation operation, boolean showError) {
|
||||
try {
|
||||
final String preprocessedString = Preprocessor.process(String.valueOf(editText.getText()));
|
||||
|
||||
String result = String.valueOf(interpreter.eval(Preprocessor.wrap(operation, preprocessedString))).trim();
|
||||
|
||||
try {
|
||||
final Double dResult = Double.valueOf(result);
|
||||
result = String.valueOf(MathUtils.round(dResult, 5));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
|
||||
resultEditText.setText(result);
|
||||
|
||||
// result editor might be changed (but main editor - no) => make undo and add new state with saved result
|
||||
CalculatorHistoryState currentHistoryState = getCurrentHistoryState();
|
||||
if (this.historyHelper.isUndoAvailable()) {
|
||||
this.historyHelper.undo(currentHistoryState);
|
||||
}
|
||||
|
||||
this.historyHelper.addState(currentHistoryState);
|
||||
|
||||
} catch (EvalError e) {
|
||||
if (showError) {
|
||||
Toast.makeText(CalculatorActivity.this, R.string.syntax_error, Toast.LENGTH_SHORT).show();
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
view.clear();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void digitButtonClickHandler(@NotNull View v) {
|
||||
processButtonAction(v, ((DirectionDragButton) v).getTextMiddle());
|
||||
view.processButtonAction(((DirectionDragButton) v).getTextMiddle());
|
||||
}
|
||||
|
||||
private final class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor {
|
||||
@ -269,7 +204,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
result = true;
|
||||
|
||||
final HistoryAction historyAction = HistoryAction.valueOf(actionText);
|
||||
doHistoryAction(historyAction);
|
||||
view.doHistoryAction(historyAction);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(String.valueOf(dragButton.getId()), "Unsupported history action: " + actionText);
|
||||
}
|
||||
@ -279,15 +214,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
}
|
||||
}
|
||||
|
||||
private void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||
if (historyHelper.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = historyHelper.doAction(historyAction, getCurrentHistoryState());
|
||||
if (newState != null) {
|
||||
setCurrentHistoryState(newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getActionText(@NotNull DirectionDragButton dragButton, @NotNull DragDirection direction) {
|
||||
final String result;
|
||||
@ -309,67 +235,10 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||
setValuesFromHistory(this.editText, editorHistoryState.getEditorState());
|
||||
setValuesFromHistory(this.resultEditText, editorHistoryState.getResultEditorState());
|
||||
}
|
||||
|
||||
private void setValuesFromHistory(@NotNull TextView editText, EditorHistoryState editorHistoryState) {
|
||||
editText.setText(editorHistoryState.getText());
|
||||
if (editText instanceof EditText) {
|
||||
((EditText) editText).setSelection(editorHistoryState.getCursorPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorHistoryState getCurrentHistoryState() {
|
||||
return new CalculatorHistoryState(getEditorHistoryState(this.editText), getEditorHistoryState(this.resultEditText));
|
||||
}
|
||||
|
||||
private EditorHistoryState getEditorHistoryState(@NotNull TextView textView) {
|
||||
final EditorHistoryState result = new EditorHistoryState();
|
||||
|
||||
result.setText(String.valueOf(textView.getText()));
|
||||
result.setCursorPosition(textView.getSelectionStart());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void processButtonAction(@NotNull View v, @Nullable String text) {
|
||||
//Toast.makeText(CalculatorActivity.this, text, Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final MathEntityType type = MathEntityType.getType(text);
|
||||
|
||||
int cursorPositionOffset = 0;
|
||||
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case function:
|
||||
text += "()";
|
||||
cursorPositionOffset = -1;
|
||||
break;
|
||||
case group_symbols:
|
||||
cursorPositionOffset = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.editText.getText().insert(this.editText.getSelectionStart(), text);
|
||||
this.editText.setSelection(this.editText.getSelectionStart() + cursorPositionOffset, this.editText.getSelectionEnd() + cursorPositionOffset);
|
||||
saveHistoryState();
|
||||
eval(JsclOperation.numeric, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
doHistoryAction(HistoryAction.undo);
|
||||
view.doHistoryAction(HistoryAction.undo);
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
@ -392,9 +261,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster {
|
||||
case R.id.menu_item_settings:
|
||||
showSettings();
|
||||
result = true;
|
||||
break;
|
||||
case R.id.menu_item_help:
|
||||
showHelp();
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
result = super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ public class CalculatorHistoryState {
|
||||
private EditorHistoryState editorState;
|
||||
|
||||
@NotNull
|
||||
private EditorHistoryState resultEditorState;
|
||||
private EditorHistoryState displayState;
|
||||
|
||||
public CalculatorHistoryState(@NotNull EditorHistoryState editorState, @NotNull EditorHistoryState resultEditorState) {
|
||||
public CalculatorHistoryState(@NotNull EditorHistoryState editorState, @NotNull EditorHistoryState displayState) {
|
||||
this.editorState = editorState;
|
||||
this.resultEditorState = resultEditorState;
|
||||
this.displayState = displayState;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -30,11 +30,11 @@ public class CalculatorHistoryState {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EditorHistoryState getResultEditorState() {
|
||||
return resultEditorState;
|
||||
public EditorHistoryState getDisplayState() {
|
||||
return displayState;
|
||||
}
|
||||
|
||||
public void setResultEditorState(@NotNull EditorHistoryState resultEditorState) {
|
||||
this.resultEditorState = resultEditorState;
|
||||
public void setDisplayState(@NotNull EditorHistoryState displayState) {
|
||||
this.displayState = displayState;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import bsh.EvalError;
|
||||
import bsh.Interpreter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.util.math.MathUtils;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/12/11
|
||||
* Time: 11:38 PM
|
||||
*/
|
||||
|
||||
public class CalculatorModel {
|
||||
|
||||
@NotNull
|
||||
private Interpreter interpreter;
|
||||
|
||||
private int NUMBER_OF_FRACTION_DIGITS = 5;
|
||||
|
||||
public CalculatorModel() throws EvalError {
|
||||
interpreter = new Interpreter();
|
||||
|
||||
interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
|
||||
}
|
||||
|
||||
public String evaluate(@NotNull JsclOperation operation, @NotNull String expression ) throws EvalError {
|
||||
|
||||
final String preprocessedString = Preprocessor.process(String.valueOf(expression));
|
||||
|
||||
String result = String.valueOf(interpreter.eval(Preprocessor.wrap(operation, preprocessedString))).trim();
|
||||
|
||||
try {
|
||||
final Double dResult = Double.valueOf(result);
|
||||
result = String.valueOf(MathUtils.round(dResult, NUMBER_OF_FRACTION_DIGITS));
|
||||
} catch (NumberFormatException e) {
|
||||
// do nothing => it's normal if sometimes we don't have doubles as result
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,206 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.InputType;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import bsh.EvalError;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.MathEntityType;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/12/11
|
||||
* Time: 11:15 PM
|
||||
*/
|
||||
public class CalculatorView implements CursorControl{
|
||||
|
||||
@NotNull
|
||||
private final EditText editor;
|
||||
|
||||
@NotNull
|
||||
private final TextView display;
|
||||
|
||||
@NotNull
|
||||
private final Activity activity;
|
||||
|
||||
@NotNull
|
||||
private final CalculatorModel calculator;
|
||||
|
||||
@NotNull
|
||||
private HistoryHelper<CalculatorHistoryState> history;
|
||||
|
||||
public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) {
|
||||
this.activity = activity;
|
||||
this.calculator = calculator;
|
||||
|
||||
final InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
this.editor = (EditText) activity.findViewById(R.id.editText);
|
||||
this.editor.setInputType(InputType.TYPE_NULL);
|
||||
imm.hideSoftInputFromWindow(this.editor.getWindowToken(), 0);
|
||||
|
||||
this.display = (TextView) activity.findViewById(R.id.resultEditText);
|
||||
this.display.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
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, "Result copied to clipboard!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||
saveHistoryState();
|
||||
}
|
||||
|
||||
private void saveHistoryState() {
|
||||
history.addState(getCurrentHistoryState());
|
||||
}
|
||||
|
||||
|
||||
public void setCursorOnStart() {
|
||||
editor.setSelection(0);
|
||||
}
|
||||
|
||||
public void setCursorOnEnd() {
|
||||
editor.setSelection(editor.getText().length());
|
||||
}
|
||||
|
||||
public void moveCursorLeft() {
|
||||
if (editor.getSelectionStart() > 0) {
|
||||
editor.setSelection(editor.getSelectionStart() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void moveCursorRight() {
|
||||
if (editor.getSelectionStart() < editor.getText().length()) {
|
||||
editor.setSelection(editor.getSelectionStart() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void doTextOperation(@NotNull TextOperation operation) {
|
||||
final String editorStateBefore = this.editor.getText().toString();
|
||||
|
||||
operation.doOperation(this.editor);
|
||||
|
||||
final String editorStateAfter = this.editor.getText().toString();
|
||||
if (!editorStateBefore.equals(editorStateAfter)) {
|
||||
try {
|
||||
evaluate(editorStateAfter);
|
||||
} catch (EvalError evalError) {
|
||||
// actually nothing shall be logged while text operations are done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void evaluate(@Nullable String expression) throws EvalError {
|
||||
if (!StringUtils.isEmpty(expression)) {
|
||||
display.setText(calculator.evaluate(JsclOperation.numeric, expression));
|
||||
saveHistoryState();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (!StringUtils.isEmpty(editor.getText()) || !StringUtils.isEmpty(editor.getText())) {
|
||||
editor.getText().clear();
|
||||
display.setText("");
|
||||
saveHistoryState();
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluate() {
|
||||
try {
|
||||
evaluate(editor.getText().toString());
|
||||
} catch (EvalError evalError) {
|
||||
Toast.makeText(this.activity, R.string.syntax_error, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void processButtonAction(@Nullable final String text) {
|
||||
//Toast.makeText(CalculatorActivity.this, text, Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
doTextOperation(new CalculatorView.TextOperation() {
|
||||
|
||||
@Override
|
||||
public void doOperation(@NotNull EditText editor) {
|
||||
|
||||
final MathEntityType type = MathEntityType.getType(text);
|
||||
|
||||
int cursorPositionOffset = 0;
|
||||
final StringBuilder textToBeInserted = new StringBuilder(text);
|
||||
if (type != null) {
|
||||
switch (type) {
|
||||
case function:
|
||||
textToBeInserted.append("()");
|
||||
cursorPositionOffset = -1;
|
||||
break;
|
||||
case group_symbols:
|
||||
cursorPositionOffset = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
editor.getText().insert(editor.getSelectionStart(), textToBeInserted.toString());
|
||||
editor.setSelection(editor.getSelectionStart() + cursorPositionOffset, editor.getSelectionEnd() + cursorPositionOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static interface TextOperation {
|
||||
|
||||
void doOperation(@NotNull EditText editor);
|
||||
|
||||
}
|
||||
|
||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||
if (history.isActionAvailable(historyAction)) {
|
||||
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
||||
if (newState != null) {
|
||||
setCurrentHistoryState(newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
|
||||
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
||||
}
|
||||
|
||||
private void setValuesFromHistory(@NotNull TextView editText, EditorHistoryState editorHistoryState) {
|
||||
editText.setText(editorHistoryState.getText());
|
||||
if (editText instanceof EditText) {
|
||||
((EditText) editText).setSelection(editorHistoryState.getCursorPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CalculatorHistoryState getCurrentHistoryState() {
|
||||
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getEditorHistoryState(this.display));
|
||||
}
|
||||
|
||||
private EditorHistoryState getEditorHistoryState(@NotNull TextView textView) {
|
||||
final EditorHistoryState result = new EditorHistoryState();
|
||||
|
||||
result.setText(String.valueOf(textView.getText()));
|
||||
result.setCursorPosition(textView.getSelectionStart());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/13/11
|
||||
* Time: 12:08 AM
|
||||
*/
|
||||
public interface CursorControl {
|
||||
|
||||
public void setCursorOnStart();
|
||||
|
||||
public void setCursorOnEnd();
|
||||
|
||||
public void moveCursorLeft();
|
||||
|
||||
public void moveCursorRight();
|
||||
}
|
Loading…
Reference in New Issue
Block a user