diff options
author | Christine Franks <christyfranks@google.com> | 2016-11-14 14:00:36 -0800 |
---|---|---|
committer | Christine Franks <christyfranks@google.com> | 2016-11-23 10:10:47 -0800 |
commit | 1d99be1bad1f50255dc063593c6940c93f7ccbd6 (patch) | |
tree | 16ee346d13424f14df7f2d366dca4873a4c0c658 /src | |
parent | 37c33b66cd4511fd4972897020f55357188e4cbb (diff) | |
download | android_packages_apps_ExactCalculator-1d99be1bad1f50255dc063593c6940c93f7ccbd6.tar.gz android_packages_apps_ExactCalculator-1d99be1bad1f50255dc063593c6940c93f7ccbd6.tar.bz2 android_packages_apps_ExactCalculator-1d99be1bad1f50255dc063593c6940c93f7ccbd6.zip |
UI for memory and functionality for M+ and M-
Bug: 31686717
Test: manual - long-press on result and formula and proper context
menus appear, as well as on results in history.
Change-Id: I88b25ed9d0402e03b420ab984a6b086dff6859e5
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/calculator2/Calculator.java | 89 | ||||
-rw-r--r-- | src/com/android/calculator2/CalculatorFormula.java | 65 | ||||
-rw-r--r-- | src/com/android/calculator2/CalculatorResult.java | 36 | ||||
-rw-r--r-- | src/com/android/calculator2/Evaluator.java | 27 |
4 files changed, 155 insertions, 62 deletions
diff --git a/src/com/android/calculator2/Calculator.java b/src/com/android/calculator2/Calculator.java index f41d87e..ea1d445 100644 --- a/src/com/android/calculator2/Calculator.java +++ b/src/com/android/calculator2/Calculator.java @@ -80,8 +80,10 @@ import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; +import static com.android.calculator2.CalculatorFormula.OnFormulaContextMenuClickListener; + public class Calculator extends Activity - implements OnTextSizeChangeListener, OnLongClickListener, CalculatorFormula.OnPasteListener, + implements OnTextSizeChangeListener, OnLongClickListener, AlertDialogFragment.OnClickListener, Evaluator.EvaluationListener /* for main result */ { /** @@ -158,6 +160,48 @@ public class Calculator extends Activity } }; + public final OnDisplayMemoryOperationsListener mOnDisplayMemoryOperationsListener = + new OnDisplayMemoryOperationsListener() { + @Override + public boolean shouldDisplayMemory() { + return mEvaluator.getMemoryIndex() != 0; + } + }; + + public final OnFormulaContextMenuClickListener mOnFormulaContextMenuClickListener = + new OnFormulaContextMenuClickListener() { + @Override + public boolean onPaste(ClipData clip) { + final ClipData.Item item = clip.getItemCount() == 0 ? null : clip.getItemAt(0); + if (item == null) { + // nothing to paste, bail early... + return false; + } + + // Check if the item is a previously copied result, otherwise paste as raw text. + final Uri uri = item.getUri(); + if (uri != null && mEvaluator.isLastSaved(uri)) { + clearIfNotInputState(); + mEvaluator.appendExpr(mEvaluator.getSavedIndex()); + redisplayAfterFormulaChange(); + } else { + addChars(item.coerceToText(Calculator.this).toString(), false); + } + return true; + } + + @Override + public void onMemoryRecall() { + clearIfNotInputState(); + long memoryIndex = mEvaluator.getMemoryIndex(); + if (memoryIndex != 0) { + mEvaluator.appendExpr(mEvaluator.getMemoryIndex()); + redisplayAfterFormulaChange(); + } // FIXME: Avoid the 0 case, e.g. by graying out button when memory is unavailable. + } + }; + + private final TextWatcher mFormulaTextWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { @@ -340,8 +384,10 @@ public class Calculator extends Activity mEvaluator.clearMain(); } + mFormulaText.setOnContextMenuClickListener(mOnFormulaContextMenuClickListener); + mFormulaText.setOnDisplayMemoryOperationsListener(mOnDisplayMemoryOperationsListener); + mFormulaText.setOnTextSizeChangeListener(this); - mFormulaText.setOnPasteListener(this); mFormulaText.addTextChangedListener(mFormulaTextWatcher); mDeleteButton.setOnLongClickListener(this); @@ -765,12 +811,6 @@ public class Calculator extends Activity mEvaluator.evaluateAndNotify(mEvaluator.MAIN_INDEX, this, mResultText); } return; - case R.id.memory_store: - mResultText.onMemoryStore(); - return; - case R.id.memory_recall: - onMemoryRecall(); - return; default: cancelIfEvaluating(false); if (haveUnprocessed()) { @@ -920,15 +960,6 @@ public class Calculator extends Activity redisplayAfterFormulaChange(); } - private void onMemoryRecall() { - clearIfNotInputState(); - long memoryIndex = mEvaluator.getMemoryIndex(); - if (memoryIndex != 0) { - mEvaluator.appendExpr(mEvaluator.getMemoryIndex()); - redisplayAfterFormulaChange(); - } // FIXME: Avoid the 0 case, e.g. by graying out button when memory is unavailable. - } - private void reveal(View sourceView, int colorRes, AnimatorListener listener) { final ViewGroupOverlay groupOverlay = (ViewGroupOverlay) getWindow().getDecorView().getOverlay(); @@ -1319,26 +1350,6 @@ public class Calculator extends Activity return mHitRect.contains((int) event.getX(), (int) event.getY()); } - @Override - public boolean onPaste(ClipData clip) { - final ClipData.Item item = clip.getItemCount() == 0 ? null : clip.getItemAt(0); - if (item == null) { - // nothing to paste, bail early... - return false; - } - - // Check if the item is a previously copied result, otherwise paste as raw text. - final Uri uri = item.getUri(); - if (uri != null && mEvaluator.isLastSaved(uri)) { - clearIfNotInputState(); - mEvaluator.appendExpr(mEvaluator.getSavedIndex()); - redisplayAfterFormulaChange(); - } else { - addChars(item.coerceToText(this).toString(), false); - } - return true; - } - /** * Clean up animation for context menu. */ @@ -1346,4 +1357,8 @@ public class Calculator extends Activity public void onContextMenuClosed(Menu menu) { stopActionModeOrContextMenu(); } + + public interface OnDisplayMemoryOperationsListener { + boolean shouldDisplayMemory(); + } } diff --git a/src/com/android/calculator2/CalculatorFormula.java b/src/com/android/calculator2/CalculatorFormula.java index 8a7e4c5..210372c 100644 --- a/src/com/android/calculator2/CalculatorFormula.java +++ b/src/com/android/calculator2/CalculatorFormula.java @@ -58,8 +58,9 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen private ActionMode mActionMode; private ActionMode.Callback mPasteActionModeCallback; private ContextMenu mContextMenu; - private OnPasteListener mOnPasteListener; private OnTextSizeChangeListener mOnTextSizeChangeListener; + private OnFormulaContextMenuClickListener mOnContextMenuClickListener; + private Calculator.OnDisplayMemoryOperationsListener mOnDisplayMemoryOperationsListener; public CalculatorFormula(Context context) { this(context, null /* attrs */); @@ -243,8 +244,13 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen mOnTextSizeChangeListener = listener; } - public void setOnPasteListener(OnPasteListener listener) { - mOnPasteListener = listener; + public void setOnContextMenuClickListener(OnFormulaContextMenuClickListener listener) { + mOnContextMenuClickListener = listener; + } + + public void setOnDisplayMemoryOperationsListener( + Calculator.OnDisplayMemoryOperationsListener listener) { + mOnDisplayMemoryOperationsListener = listener; } /** @@ -268,7 +274,7 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.setTag(TAG_ACTION_MODE); final MenuInflater inflater = mode.getMenuInflater(); - return createPasteMenu(inflater, menu); + return createContextMenu(inflater, menu); } @Override @@ -309,7 +315,7 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { final MenuInflater inflater = new MenuInflater(getContext()); - createPasteMenu(inflater, contextMenu); + createContextMenu(inflater, contextMenu); mContextMenu = contextMenu; for(int i = 0; i < contextMenu.size(); i++) { contextMenu.getItem(i).setOnMenuItemClickListener(CalculatorFormula.this); @@ -324,41 +330,52 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen }); } - private boolean createPasteMenu(MenuInflater inflater, Menu menu) { + private boolean createContextMenu(MenuInflater inflater, Menu menu) { final ClipboardManager clipboard = (ClipboardManager) getContext() .getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard.hasPrimaryClip()) { - bringPointIntoView(length()); - inflater.inflate(R.menu.paste, menu); - return true; + final boolean isPasteEnabled = clipboard.hasPrimaryClip(); + final boolean isMemoryEnabled = isMemoryEnabled(); + if (!isPasteEnabled && !isMemoryEnabled) { + return false; } - // Prevents the selection action mode on double tap. - return false; + + bringPointIntoView(length()); + inflater.inflate(R.menu.menu_formula, menu); + final MenuItem pasteItem = menu.findItem(R.id.menu_paste); + final MenuItem memoryRecallItem = menu.findItem(R.id.memory_recall); + pasteItem.setEnabled(isPasteEnabled); + memoryRecallItem.setEnabled(isMemoryEnabled); + return true; } private void paste() { final ClipboardManager clipboard = (ClipboardManager) getContext() .getSystemService(Context.CLIPBOARD_SERVICE); final ClipData primaryClip = clipboard.getPrimaryClip(); - if (primaryClip != null && mOnPasteListener != null) { - mOnPasteListener.onPaste(primaryClip); + if (primaryClip != null && mOnContextMenuClickListener != null) { + mOnContextMenuClickListener.onPaste(primaryClip); } } @Override public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == R.id.menu_paste) { - paste(); - return true; + switch (item.getItemId()) { + case R.id.memory_recall: + mOnContextMenuClickListener.onMemoryRecall(); + return true; + case R.id.menu_paste: + paste(); + return true; + default: + return false; } - return false; } @Override public void onPrimaryClipChanged() { final ClipData clip = mClipboardManager.getPrimaryClip(); if (clip == null || clip.getItemCount() == 0) { - setLongClickable(false); + setLongClickable(isMemoryEnabled()); return; } CharSequence clipText = null; @@ -367,14 +384,20 @@ public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMen } catch (Exception e) { Log.i("Calculator", "Error reading clipboard:", e); } - setLongClickable(!TextUtils.isEmpty(clipText)); + setLongClickable(!TextUtils.isEmpty(clipText) || isMemoryEnabled()); + } + + private boolean isMemoryEnabled() { + return !(mOnDisplayMemoryOperationsListener == null || mOnContextMenuClickListener == null) + && mOnDisplayMemoryOperationsListener.shouldDisplayMemory(); } public interface OnTextSizeChangeListener { void onTextSizeChanged(TextView textView, float oldSize); } - public interface OnPasteListener { + public interface OnFormulaContextMenuClickListener { boolean onPaste(ClipData clip); + void onMemoryRecall(); } } diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java index e001bee..0b399c4 100644 --- a/src/com/android/calculator2/CalculatorResult.java +++ b/src/com/android/calculator2/CalculatorResult.java @@ -410,6 +410,20 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu } /** + * Add the result to the value currently in memory. + */ + public void onMemoryAdd() { + mEvaluator.addToMemory(Evaluator.MAIN_INDEX); + } + + /** + * Subtract the result from the value currently in memory. + */ + public void onMemorySubtract() { + mEvaluator.subtractFromMemory(Evaluator.MAIN_INDEX); + } + + /** * Set up scroll bounds (mMinPos, mMaxPos, etc.) and determine whether the result is * scrollable, based on the supplied information about the result. * This is unfortunately complicated because we need to predict whether trailing digits @@ -920,7 +934,7 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu } /** - * Use ActionMode for copy support on M and higher. + * Use ActionMode for copy/memory support on M and higher. */ @TargetApi(Build.VERSION_CODES.M) private void setupActionMode() { @@ -995,7 +1009,7 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu } /** - * Use ContextMenu for copy support on L and lower. + * Use ContextMenu for copy/memory support on L and lower. */ private void setupContextMenu() { setOnCreateContextMenuListener(new OnCreateContextMenuListener() { @@ -1022,7 +1036,12 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu } private boolean createCopyMenu(MenuInflater inflater, Menu menu) { - inflater.inflate(R.menu.copy, menu); + inflater.inflate(R.menu.menu_result, menu); + final boolean displayMemory = mEvaluator.getMemoryIndex() != 0; + final MenuItem memoryAddItem = menu.findItem(R.id.memory_add); + final MenuItem memorySubtractItem = menu.findItem(R.id.memory_subtract); + memoryAddItem.setEnabled(displayMemory); + memorySubtractItem.setEnabled(displayMemory); highlightResult(); return true; } @@ -1072,6 +1091,15 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { + case R.id.memory_add: + onMemoryAdd(); + return true; + case R.id.memory_subtract: + onMemorySubtract(); + return true; + case R.id.memory_store: + onMemoryStore(); + return true; case R.id.menu_copy: if (mEvaluator.evaluationInProgress(mIndex)) { // Refuse to copy placeholder characters. @@ -1085,4 +1113,4 @@ public class CalculatorResult extends AlignedTextView implements MenuItem.OnMenu return false; } } -} +}
\ No newline at end of file diff --git a/src/com/android/calculator2/Evaluator.java b/src/com/android/calculator2/Evaluator.java index 82a4d86..77c762d 100644 --- a/src/com/android/calculator2/Evaluator.java +++ b/src/com/android/calculator2/Evaluator.java @@ -1362,6 +1362,22 @@ public class Evaluator implements CalculatorExpr.ExprResolver { } /** + * Return an ExprInfo corresponding to the subtraction of the value at the subtrahend index + * from value at the minuend index (minuend - subtrahend = result). Both are presumed to have + * been previously evaluated. The result is unevaluated. + */ + private ExprInfo difference(long minuendIndex, long subtrahendIndex) { + final CalculatorExpr resultExpr = new CalculatorExpr(); + resultExpr.append(getCollapsedExpr(minuendIndex)); + resultExpr.add(R.id.op_sub); + resultExpr.append(getCollapsedExpr(subtrahendIndex)); + final ExprInfo result = new ExprInfo(resultExpr, false /* angular measure irrelevant */); + result.mLongTimeout = mExprs.get(minuendIndex).mLongTimeout + || mExprs.get(subtrahendIndex).mLongTimeout; + return result; + } + + /** * Add the expression described by the argument to the database. * Returns the new row id in the database. * If in_history is true, add it with a positive index, so it will appear in the history. @@ -1576,6 +1592,17 @@ public class Evaluator implements CalculatorExpr.ExprResolver { } /** + * Save an an expression representing the subtraction of the expression with the given index + * from "memory." Make mMemoryIndex point to it when we complete evaluating. + */ + public void subtractFromMemory(long index) { + ExprInfo newEi = difference(mMemoryIndex, index); + long newIndex = addToDB(false, newEi); + mMemoryIndex = 0; // Invalidate while we're evaluating. + setMemoryIndexWhenEvaluated(newIndex, true /* persist */); + } + + /** * Return index of "saved" expression, or 0. */ public long getSavedIndex() { |