diff --git a/res/layout-land/main.xml b/res/layout-land/main.xml index 52a4c9cb..d72988fb 100644 --- a/res/layout-land/main.xml +++ b/res/layout-land/main.xml @@ -15,7 +15,7 @@ - - onDragListeners = new ArrayList(); @NotNull - private CalculatorView view; + private CalculatorView calculatorView; @NotNull - private CalculatorModel calculator; + private CalculatorModel calculatorModel; @NotNull private BroadcastReceiver preferencesChangesReceiver; @@ -50,26 +53,17 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster { setContentView(R.layout.main); try { - this.calculator = new CalculatorModel(); + this.calculatorModel = 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); + this.calculatorView = new CalculatorView(this, this.calculatorModel); final DragButtonCalibrationActivity.Preferences dragPreferences = DragButtonCalibrationActivity.getPreferences(this); - final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new SimpleOnDragListener.DragProcessor() { - @Override - public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { - assert dragButton instanceof DirectionDragButton; - view.processButtonAction(getActionText((DirectionDragButton) dragButton, dragDirection)); - return true; - } - - }, dragPreferences); - + final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new DigitButtonDragProcessor(calculatorView), dragPreferences); onDragListeners.add(onDragListener); // todo serso: check if there is more convenient method for doing this @@ -90,27 +84,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster { } } - final SimpleOnDragListener historyOnDragListener = new SimpleOnDragListener(new HistoryDragProcessor(), dragPreferences); + final SimpleOnDragListener historyOnDragListener = new SimpleOnDragListener(new HistoryDragProcessor(this.calculatorView), dragPreferences); ((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener); onDragListeners.add(historyOnDragListener); - final SimpleOnDragListener toPositionOnDragListener = new SimpleOnDragListener(new SimpleOnDragListener.DragProcessor() { - @Override - public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { - boolean result = false; - - if (dragButton instanceof DirectionDragButton) { - String text = ((DirectionDragButton) dragButton).getText(dragDirection); - if ("↞".equals(text)) { - CalculatorActivity.this.view.setCursorOnStart(); - } else if ("↠".equals(text)) { - CalculatorActivity.this.view.setCursorOnEnd(); - } - } - - return result; - } - }, dragPreferences); + final SimpleOnDragListener toPositionOnDragListener = new SimpleOnDragListener(new CursorDragProcessor(calculatorView), dragPreferences); ((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener); ((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener); onDragListeners.add(toPositionOnDragListener); @@ -145,12 +123,12 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster { @SuppressWarnings({"UnusedDeclaration"}) public void numericButtonClickHandler(@NotNull View v) { - this.view.evaluate(); + this.calculatorView.evaluate(); } @SuppressWarnings({"UnusedDeclaration"}) public void eraseButtonClickHandler(@NotNull View v) { - view.doTextOperation(new CalculatorView.TextOperation() { + calculatorView.doTextOperation(new CalculatorView.TextOperation() { @Override public void doOperation(@NotNull EditText editor) { if (editor.getSelectionStart() > 0) { @@ -167,17 +145,17 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster { @SuppressWarnings({"UnusedDeclaration"}) public void moveLeftButtonClickHandler(@NotNull View v) { - view.moveCursorLeft(); + calculatorView.moveCursorLeft(); } @SuppressWarnings({"UnusedDeclaration"}) public void moveRightButtonClickHandler(@NotNull View v) { - view.moveCursorRight(); + calculatorView.moveCursorRight(); } @SuppressWarnings({"UnusedDeclaration"}) public void pasteButtonClickHandler(@NotNull View v) { - view.doTextOperation(new CalculatorView.TextOperation() { + calculatorView.doTextOperation(new CalculatorView.TextOperation() { @Override public void doOperation(@NotNull EditText editor) { final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); @@ -190,64 +168,19 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster { @SuppressWarnings({"UnusedDeclaration"}) public void clearButtonClickHandler(@NotNull View v) { - view.clear(); + calculatorView.clear(); } @SuppressWarnings({"UnusedDeclaration"}) public void digitButtonClickHandler(@NotNull View v) { - view.processButtonAction(((DirectionDragButton) v).getTextMiddle()); - } - - private final class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor { - - @Override - public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { - boolean result = false; - - Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + dragDirection); - - assert dragButton instanceof DirectionDragButton; - String actionText = getActionText((DirectionDragButton) dragButton, dragDirection); - if (!StringUtils.isEmpty(actionText)) { - try { - result = true; - - final HistoryAction historyAction = HistoryAction.valueOf(actionText); - view.doHistoryAction(historyAction); - } catch (IllegalArgumentException e) { - Log.e(String.valueOf(dragButton.getId()), "Unsupported history action: " + actionText); - } - } - - return result; - } - } - - @Nullable - private static String getActionText(@NotNull DirectionDragButton dragButton, @NotNull DragDirection direction) { - final String result; - - switch (direction) { - case up: - result = dragButton.getTextUp(); - break; - - case down: - result = dragButton.getTextDown(); - break; - - default: - result = null; - break; - } - - return result; + Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed()); + calculatorView.processDigitButtonAction(((DirectionDragButton) v).getTextMiddle()); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - view.doHistoryAction(HistoryAction.undo); + calculatorView.doHistoryAction(HistoryAction.undo); return true; } return super.onKeyDown(keyCode, event); diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorEditText.java b/src/main/java/org/solovyev/android/calculator/CalculatorEditText.java new file mode 100644 index 00000000..0bec6c7e --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/CalculatorEditText.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.text.Html; +import android.util.AttributeSet; +import android.widget.EditText; +import android.widget.TextView; +import org.solovyev.common.definitions.Pair; +import org.solovyev.common.exceptions.SersoException; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.util.math.MathEntityType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * User: serso + * Date: 9/17/11 + * Time: 12:25 AM + */ +public class CalculatorEditText extends EditText { + + + public CalculatorEditText(Context context) { + super(context); + } + + public CalculatorEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CalculatorEditText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void setTextColor(ColorStateList colors) { + super.setTextColor(colors); //To change body of overridden methods use File | Settings | File Templates. + } + + @Override + public void setText(CharSequence text, BufferType type) { + /*try { + final List> groupSymbols = new ArrayList>(); + + final Stack> groupSymbolsStack = new Stack>(); + for (int i = 0; i < text.length(); i++) { + char ch = text.charAt(i); + if (MathEntityType.openGroupSymbols.contains(ch)) { + groupSymbolsStack.push(new Pair(i, null)); + } else if (MathEntityType.closeGroupSymbols.contains(ch)) { + final Pair pair = groupSymbolsStack.pop(); + if (pair != null) { + pair.setSecond(i); + groupSymbols.add(0, pair); + } else { + throw new NoPairGroupSymbolException(); + } + } + } + + text = insertHtml(text, groupSymbols); + } catch (NoPairGroupSymbolException e) { + // do nothing + }*/ + + super.setText(text, type); + } + + private class NoPairGroupSymbolException extends SersoException { + + } +} diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorHistoryState.java b/src/main/java/org/solovyev/android/calculator/CalculatorHistoryState.java index 5cecd1d0..7478ce70 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorHistoryState.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorHistoryState.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index 345d606e..7a65f1be 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -1,8 +1,16 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; +import android.util.Log; import bsh.EvalError; import bsh.Interpreter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.common.exceptions.SersoException; import org.solovyev.common.utils.MathUtils; /** @@ -24,19 +32,28 @@ public class CalculatorModel { interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands")); } - public String evaluate(@NotNull JsclOperation operation, @NotNull String expression ) throws EvalError { + public String evaluate(@NotNull JsclOperation operation, @NotNull String expression ) throws EvalError, ParseException { - final String preprocessedString = Preprocessor.process(String.valueOf(expression)); + final String preprocessedExpression = Preprocessor.process(expression); - String result = String.valueOf(interpreter.eval(Preprocessor.wrap(operation, preprocessedString))).trim(); + Log.d(CalculatorModel.class.getName(), "Preprocessed expression: " + preprocessedExpression); + + Object evaluationObject = interpreter.eval(Preprocessor.wrap(operation, preprocessedExpression)); + String result = String.valueOf(evaluationObject).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 + throw new ParseException(e); } return result; } + + public static class ParseException extends SersoException { + public ParseException(Throwable cause) { + super(cause); + } + } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java index 436c889c..cc3d5532 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorPreferencesActivity.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import android.content.Intent; diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorView.java b/src/main/java/org/solovyev/android/calculator/CalculatorView.java index 877ed542..17b7725e 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorView.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorView.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import android.app.Activity; @@ -5,6 +10,7 @@ import android.content.Context; import android.os.Handler; import android.text.ClipboardManager; import android.text.InputType; +import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; @@ -13,6 +19,9 @@ import android.widget.Toast; import bsh.EvalError; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.solovyev.android.view.CursorControl; +import org.solovyev.android.view.HistoryControl; +import org.solovyev.common.math.calculators.Calculator; import org.solovyev.common.utils.MutableObject; import org.solovyev.common.utils.StringUtils; import org.solovyev.common.utils.history.HistoryAction; @@ -25,10 +34,13 @@ import org.solovyev.util.math.MathEntityType; * Date: 9/12/11 * Time: 11:15 PM */ -public class CalculatorView implements CursorControl{ +public class CalculatorView implements CursorControl, HistoryControl { + + // millis to wait before evaluation after user edit action + public static final int EVAL_DELAY_MILLIS = 1000; @NotNull - private final EditText editor; + private final CalculatorEditText editor; @NotNull private final TextView display; @@ -37,18 +49,18 @@ public class CalculatorView implements CursorControl{ private final Activity activity; @NotNull - private final CalculatorModel calculator; + private final CalculatorModel calculatorModel; @NotNull private HistoryHelper history; public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) { this.activity = activity; - this.calculator = calculator; + this.calculatorModel = calculator; final InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - this.editor = (EditText) activity.findViewById(R.id.editText); + this.editor = (CalculatorEditText) activity.findViewById(R.id.editText); this.editor.setInputType(InputType.TYPE_NULL); imm.hideSoftInputFromWindow(this.editor.getWindowToken(), 0); @@ -117,13 +129,14 @@ public class CalculatorView implements CursorControl{ if (history.isUndoAvailable()) { history.undo(getCurrentHistoryState()); } + saveHistoryState(); } } } }); - new Handler().postDelayed(currentRunner.getObject(), 500); + new Handler().postDelayed(currentRunner.getObject(), EVAL_DELAY_MILLIS); saveHistoryState(); } @@ -136,15 +149,24 @@ public class CalculatorView implements CursorControl{ final Activity localActivity = activity; try { - localDisplay.setText(calculator.evaluate(JsclOperation.numeric, expression)); - } catch (EvalError evalError) { - if (showError) { - Toast.makeText(localActivity, R.string.syntax_error, Toast.LENGTH_SHORT).show(); - } + Log.d(CalculatorView.class.getName(), "Trying to evaluate: " + expression); + localDisplay.setText(calculatorModel.evaluate(JsclOperation.numeric, expression)); + } catch (EvalError e) { + handleEvaluationException(expression, showError, localDisplay, localActivity, e); + } catch (CalculatorModel.ParseException e) { + handleEvaluationException(expression, showError, localDisplay, localActivity, e); } } } + private void handleEvaluationException(@NotNull String expression, boolean showError, @NotNull TextView localDisplay, @NotNull Activity localActivity, @NotNull Exception e) { + Log.d(CalculatorView.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e.getMessage()); + localDisplay.setText(""); + if (showError) { + Toast.makeText(localActivity, R.string.syntax_error, Toast.LENGTH_SHORT).show(); + } + } + public void clear() { if (!StringUtils.isEmpty(editor.getText()) || !StringUtils.isEmpty(editor.getText())) { editor.getText().clear(); @@ -157,7 +179,7 @@ public class CalculatorView implements CursorControl{ evaluate(editor.getText().toString(), true); } - public void processButtonAction(@Nullable final String text) { + public void processDigitButtonAction(@Nullable final String text) { //Toast.makeText(CalculatorActivity.this, text, Toast.LENGTH_SHORT).show(); if (!StringUtils.isEmpty(text)) { @@ -199,6 +221,7 @@ public class CalculatorView implements CursorControl{ } + @Override public void doHistoryAction(@NotNull HistoryAction historyAction) { if (history.isActionAvailable(historyAction)) { final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState()); @@ -208,6 +231,7 @@ public class CalculatorView implements CursorControl{ } } + @Override public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) { setValuesFromHistory(this.editor, editorHistoryState.getEditorState()); setValuesFromHistory(this.display, editorHistoryState.getDisplayState()); @@ -220,6 +244,7 @@ public class CalculatorView implements CursorControl{ } } + @Override @NotNull public CalculatorHistoryState getCurrentHistoryState() { return new CalculatorHistoryState(getEditorHistoryState(this.editor), getEditorHistoryState(this.display)); diff --git a/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java b/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java new file mode 100644 index 00000000..8cebcc7e --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/CursorDragProcessor.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator; + +import android.view.MotionEvent; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.view.*; +import org.solovyev.common.utils.Point2d; + +/** + * User: serso + * Date: 9/16/11 + * Time: 11:45 PM + */ +public class CursorDragProcessor implements SimpleOnDragListener.DragProcessor{ + + @NotNull + private final CursorControl cursorControl; + + public CursorDragProcessor(@NotNull CursorControl cursorControl) { + this.cursorControl = cursorControl; + } + + @Override + public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { + boolean result = false; + + if (dragButton instanceof DirectionDragButton) { + String text = ((DirectionDragButton) dragButton).getText(dragDirection); + if ("↞".equals(text)) { + cursorControl.setCursorOnStart(); + } else if ("↠".equals(text)) { + cursorControl.setCursorOnEnd(); + } + } + + return result; + } +} diff --git a/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java b/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java new file mode 100644 index 00000000..025a2b48 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/DigitButtonDragProcessor.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator; + +import android.view.MotionEvent; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.view.DirectionDragButton; +import org.solovyev.android.view.DragButton; +import org.solovyev.android.view.DragDirection; +import org.solovyev.android.view.SimpleOnDragListener; +import org.solovyev.common.utils.Point2d; + +/** + * User: serso + * Date: 9/16/11 + * Time: 11:48 PM + */ +public class DigitButtonDragProcessor implements SimpleOnDragListener.DragProcessor { + + @NotNull + private final CalculatorView calculatorView; + + public DigitButtonDragProcessor(@NotNull CalculatorView calculatorView) { + this.calculatorView = calculatorView; + } + + @Override + public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { + assert dragButton instanceof DirectionDragButton; + calculatorView.processDigitButtonAction(((DirectionDragButton) dragButton).getDirectionText(dragDirection)); + return true; + } + +} diff --git a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java index b6369016..20824ff8 100644 --- a/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java +++ b/src/main/java/org/solovyev/android/calculator/DragButtonCalibrationActivity.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import android.app.Activity; @@ -203,20 +208,20 @@ public class DragButtonCalibrationActivity extends Activity { case angle: switch (dragDirection) { case up: - defaultMin = 150f; + defaultMin = 130f; defaultMax = 180f; break; case down: defaultMin = 0f; - defaultMax = 30f; + defaultMax = 50f; break; default: - defaultMin = DEFAULT_VALUE; - defaultMax = DEFAULT_VALUE; + defaultMin = 0; + defaultMax = 0; } break; case distance: - defaultMin = 50f; + defaultMin = 10f; defaultMax = 150f; break; case duration: diff --git a/src/main/java/org/solovyev/android/calculator/EditorHistoryState.java b/src/main/java/org/solovyev/android/calculator/EditorHistoryState.java index 3afee4d5..a97dbc6a 100644 --- a/src/main/java/org/solovyev/android/calculator/EditorHistoryState.java +++ b/src/main/java/org/solovyev/android/calculator/EditorHistoryState.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/org/solovyev/android/calculator/HelpActivity.java b/src/main/java/org/solovyev/android/calculator/HelpActivity.java new file mode 100644 index 00000000..45d04900 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/HelpActivity.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator; + +import android.app.Activity; + +/** + * User: serso + * Date: 9/16/11 + * Time: 11:52 PM + */ +public class HelpActivity extends Activity { + // todo serso: implement +} diff --git a/src/main/java/org/solovyev/android/calculator/JsclOperation.java b/src/main/java/org/solovyev/android/calculator/JsclOperation.java index a92e7797..2bdfcd61 100644 --- a/src/main/java/org/solovyev/android/calculator/JsclOperation.java +++ b/src/main/java/org/solovyev/android/calculator/JsclOperation.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; public enum JsclOperation { diff --git a/src/main/java/org/solovyev/android/calculator/Preprocessor.java b/src/main/java/org/solovyev/android/calculator/Preprocessor.java index 60f57dee..de2fc6e0 100644 --- a/src/main/java/org/solovyev/android/calculator/Preprocessor.java +++ b/src/main/java/org/solovyev/android/calculator/Preprocessor.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; @@ -57,9 +62,12 @@ public class Preprocessor { if (mathTypeBefore != MathEntityType.binary_operation && mathTypeBefore != MathEntityType.unary_operation && - !MathEntityType.openGroupSymbols.contains(chBefore)) { + mathTypeBefore != MathEntityType.function && + !MathEntityType.openGroupSymbols.contains(chBefore)) { - if (mathType == MathEntityType.constant || MathEntityType.openGroupSymbols.contains(ch)) { + if (mathType == MathEntityType.constant ) { + sb.append("*"); + } else if ( MathEntityType.openGroupSymbols.contains(ch) && mathTypeBefore != null ) { sb.append("*"); } else if (mathType == MathEntityType.digit && mathTypeBefore != MathEntityType.digit && mathTypeBefore != MathEntityType.dot) { sb.append("*"); diff --git a/src/main/java/org/solovyev/android/view/ColorButton.java b/src/main/java/org/solovyev/android/view/ColorButton.java index 89ba575b..9b18d655 100644 --- a/src/main/java/org/solovyev/android/view/ColorButton.java +++ b/src/main/java/org/solovyev/android/view/ColorButton.java @@ -14,6 +14,11 @@ * limitations under the License. */ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.content.Context; @@ -102,7 +107,7 @@ public class ColorButton extends Button { measureText(); } - private void drawMagicFlame(int duration, Canvas canvas) { + public void drawMagicFlame(int duration, Canvas canvas) { int alpha = 255 - 255 * duration / CLICK_FEEDBACK_DURATION; int color = CLICK_FEEDBACK_COLOR | (alpha << 24); @@ -121,8 +126,6 @@ public class ColorButton extends Button { drawMagicFlame(animDuration, canvas); postInvalidateDelayed(CLICK_FEEDBACK_INTERVAL); } - } else if (isPressed()) { - drawMagicFlame(0, canvas); } CharSequence text = getText(); diff --git a/src/main/java/org/solovyev/android/calculator/CursorControl.java b/src/main/java/org/solovyev/android/view/CursorControl.java similarity index 57% rename from src/main/java/org/solovyev/android/calculator/CursorControl.java rename to src/main/java/org/solovyev/android/view/CursorControl.java index f5e8768f..7091930f 100644 --- a/src/main/java/org/solovyev/android/calculator/CursorControl.java +++ b/src/main/java/org/solovyev/android/view/CursorControl.java @@ -1,4 +1,9 @@ -package org.solovyev.android.calculator; +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.view; /** * User: serso diff --git a/src/main/java/org/solovyev/android/view/DirectionDragButton.java b/src/main/java/org/solovyev/android/view/DirectionDragButton.java index 64164605..022aba0b 100644 --- a/src/main/java/org/solovyev/android/view/DirectionDragButton.java +++ b/src/main/java/org/solovyev/android/view/DirectionDragButton.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.content.Context; @@ -41,6 +46,27 @@ public class DirectionDragButton extends DragButton { init(context, attrs); } + @Nullable + public String getDirectionText(@NotNull DragDirection direction) { + final String result; + + switch (direction) { + case up: + result = this.getTextUp(); + break; + + case down: + result = this.getTextDown(); + break; + + default: + result = null; + break; + } + + return result; + } + private void init(@NotNull Context context, @NotNull AttributeSet attrs) { diff --git a/src/main/java/org/solovyev/android/view/DragButton.java b/src/main/java/org/solovyev/android/view/DragButton.java index 65fabfe2..58b533f6 100644 --- a/src/main/java/org/solovyev/android/view/DragButton.java +++ b/src/main/java/org/solovyev/android/view/DragButton.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.content.Context; @@ -71,24 +76,24 @@ public class DragButton extends ColorButton { case MotionEvent.ACTION_UP: // stop tracking - + if (localStartPoint != null && localOnDragListener.onDrag(DragButton.this, new DragEvent(localStartPoint, event))) { if (localOnDragListener.isSuppressOnClickEvent()) { // prevent on click action setPressed(false); - } + // sometimes setPressed(false); doesn't work so to prevent onClick action button disables + if (v instanceof Button) { + final Button button = (Button) v; - if (v instanceof Button) { - final Button button = (Button)v; + button.setEnabled(false); - button.setEnabled(false); - - new Handler().postDelayed(new Runnable() { - public void run() { - button.setEnabled(true); - } - }, 500); + new Handler().postDelayed(new Runnable() { + public void run() { + button.setEnabled(true); + } + }, 300); + } } } diff --git a/src/main/java/org/solovyev/android/view/DragDirection.java b/src/main/java/org/solovyev/android/view/DragDirection.java index a45467b0..d7c261b1 100644 --- a/src/main/java/org/solovyev/android/view/DragDirection.java +++ b/src/main/java/org/solovyev/android/view/DragDirection.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; public enum DragDirection { diff --git a/src/main/java/org/solovyev/android/view/DragEvent.java b/src/main/java/org/solovyev/android/view/DragEvent.java index a293edb9..e1f6ddf2 100644 --- a/src/main/java/org/solovyev/android/view/DragEvent.java +++ b/src/main/java/org/solovyev/android/view/DragEvent.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.view.MotionEvent; diff --git a/src/main/java/org/solovyev/android/view/FontSizeAdjuster.java b/src/main/java/org/solovyev/android/view/FontSizeAdjuster.java index 932b6272..121651d9 100644 --- a/src/main/java/org/solovyev/android/view/FontSizeAdjuster.java +++ b/src/main/java/org/solovyev/android/view/FontSizeAdjuster.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.widget.TextView; diff --git a/src/main/java/org/solovyev/android/view/HistoryControl.java b/src/main/java/org/solovyev/android/view/HistoryControl.java new file mode 100644 index 00000000..7d642e36 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/HistoryControl.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.view; + +import org.jetbrains.annotations.NotNull; +import org.solovyev.common.utils.history.HistoryAction; + +/** + * User: serso + * Date: 9/16/11 + * Time: 11:42 PM + */ +public interface HistoryControl { + + void doHistoryAction(@NotNull HistoryAction historyAction); + + void setCurrentHistoryState(@NotNull T editorHistoryState); + + @NotNull + T getCurrentHistoryState(); +} diff --git a/src/main/java/org/solovyev/android/view/HistoryDragProcessor.java b/src/main/java/org/solovyev/android/view/HistoryDragProcessor.java new file mode 100644 index 00000000..4287be94 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/HistoryDragProcessor.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.view; + +import android.util.Log; +import android.view.MotionEvent; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.view.*; +import org.solovyev.common.utils.Point2d; +import org.solovyev.common.utils.StringUtils; +import org.solovyev.common.utils.history.HistoryAction; + +/** +* User: serso +* Date: 9/16/11 +* Time: 11:36 PM +*/ +public class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor { + + @NotNull + private final HistoryControl historyControl; + + public HistoryDragProcessor(@NotNull HistoryControl historyControl) { + this.historyControl = historyControl; + } + + @Override + public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { + boolean result = false; + + Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + dragDirection); + + assert dragButton instanceof DirectionDragButton; + String actionText = ((DirectionDragButton) dragButton).getDirectionText(dragDirection); + if (!StringUtils.isEmpty(actionText)) { + try { + result = true; + + final HistoryAction historyAction = HistoryAction.valueOf(actionText); + historyControl.doHistoryAction(historyAction); + } catch (IllegalArgumentException e) { + Log.e(String.valueOf(dragButton.getId()), "Unsupported history action: " + actionText); + } + } + + return result; + } +} diff --git a/src/main/java/org/solovyev/android/view/OnDragListener.java b/src/main/java/org/solovyev/android/view/OnDragListener.java index 0605f129..955d1c25 100644 --- a/src/main/java/org/solovyev/android/view/OnDragListener.java +++ b/src/main/java/org/solovyev/android/view/OnDragListener.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/org/solovyev/android/view/SimpleOnDragListener.java b/src/main/java/org/solovyev/android/view/SimpleOnDragListener.java index 26a664df..90ff38e1 100644 --- a/src/main/java/org/solovyev/android/view/SimpleOnDragListener.java +++ b/src/main/java/org/solovyev/android/view/SimpleOnDragListener.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.android.view; import android.util.Log; diff --git a/src/main/java/org/solovyev/util/math/MathEntity.java b/src/main/java/org/solovyev/util/math/MathEntity.java index b9170c81..4cce1a86 100644 --- a/src/main/java/org/solovyev/util/math/MathEntity.java +++ b/src/main/java/org/solovyev/util/math/MathEntity.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.util.math; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/org/solovyev/util/math/MathEntityType.java b/src/main/java/org/solovyev/util/math/MathEntityType.java index 757b34e7..c42ae38e 100644 --- a/src/main/java/org/solovyev/util/math/MathEntityType.java +++ b/src/main/java/org/solovyev/util/math/MathEntityType.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + package org.solovyev.util.math; import java.util.ArrayList; @@ -48,21 +53,7 @@ public enum MathEntityType { MathEntityType result = null; if ( s.length() == 1 ) { - char ch = s.charAt(0); - - if ( Character.isDigit(ch) ) { - result = MathEntityType.digit; - } else if ( unaryOperations.contains(ch) ) { - result = MathEntityType.unary_operation; - } else if ( binaryOperations.contains(ch) ) { - result = MathEntityType.binary_operation; - } else if ( singleGroupSymbols.contains(ch) ) { - result = MathEntityType.group_symbol; - } else if ( constants.contains(ch) ) { - result = MathEntityType.constant; - } else if ( dots.contains(ch) ) { - result = MathEntityType.dot; - } + result = getType(s.charAt(0)); } if ( result == null ) { @@ -76,4 +67,24 @@ public enum MathEntityType { return result; } + + @Nullable + public static MathEntityType getType(char ch) { + MathEntityType result = null; + + if ( Character.isDigit(ch) ) { + result = MathEntityType.digit; + } else if ( unaryOperations.contains(ch) ) { + result = MathEntityType.unary_operation; + } else if ( binaryOperations.contains(ch) ) { + result = MathEntityType.binary_operation; + } else if ( singleGroupSymbols.contains(ch) ) { + result = MathEntityType.group_symbol; + } else if ( constants.contains(ch) ) { + result = MathEntityType.constant; + } else if ( dots.contains(ch) ) { + result = MathEntityType.dot; + } + return result; + } }