summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristine Franks <christyfranks@google.com>2016-11-14 14:00:36 -0800
committerChristine Franks <christyfranks@google.com>2016-11-23 10:10:47 -0800
commit1d99be1bad1f50255dc063593c6940c93f7ccbd6 (patch)
tree16ee346d13424f14df7f2d366dca4873a4c0c658 /src
parent37c33b66cd4511fd4972897020f55357188e4cbb (diff)
downloadandroid_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.java89
-rw-r--r--src/com/android/calculator2/CalculatorFormula.java65
-rw-r--r--src/com/android/calculator2/CalculatorResult.java36
-rw-r--r--src/com/android/calculator2/Evaluator.java27
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() {