summaryrefslogtreecommitdiff
path: root/src/com/android/calculator2/CalculatorFormula.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/calculator2/CalculatorFormula.java')
-rw-r--r--src/com/android/calculator2/CalculatorFormula.java392
1 files changed, 0 insertions, 392 deletions
diff --git a/src/com/android/calculator2/CalculatorFormula.java b/src/com/android/calculator2/CalculatorFormula.java
deleted file mode 100644
index 2911df8..0000000
--- a/src/com/android/calculator2/CalculatorFormula.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.calculator2;
-
-import android.annotation.TargetApi;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.os.Build;
-import android.text.Layout;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.ActionMode;
-import android.view.ContextMenu;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.TextView;
-
-/**
- * TextView adapted for displaying the formula and allowing pasting.
- */
-public class CalculatorFormula extends AlignedTextView implements MenuItem.OnMenuItemClickListener,
- ClipboardManager.OnPrimaryClipChangedListener {
-
- public static final String TAG_ACTION_MODE = "ACTION_MODE";
-
- // Temporary paint for use in layout methods.
- private final TextPaint mTempPaint = new TextPaint();
-
- private final float mMaximumTextSize;
- private final float mMinimumTextSize;
- private final float mStepTextSize;
-
- private final ClipboardManager mClipboardManager;
-
- private int mWidthConstraint = -1;
- private ActionMode mActionMode;
- private ActionMode.Callback mPasteActionModeCallback;
- private ContextMenu mContextMenu;
- private OnTextSizeChangeListener mOnTextSizeChangeListener;
- private OnFormulaContextMenuClickListener mOnContextMenuClickListener;
- private Calculator.OnDisplayMemoryOperationsListener mOnDisplayMemoryOperationsListener;
-
- public CalculatorFormula(Context context) {
- this(context, null /* attrs */);
- }
-
- public CalculatorFormula(Context context, AttributeSet attrs) {
- this(context, attrs, 0 /* defStyleAttr */);
- }
-
- public CalculatorFormula(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
-
- mClipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
-
- final TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.CalculatorFormula, defStyleAttr, 0);
- mMaximumTextSize = a.getDimension(
- R.styleable.CalculatorFormula_maxTextSize, getTextSize());
- mMinimumTextSize = a.getDimension(
- R.styleable.CalculatorFormula_minTextSize, getTextSize());
- mStepTextSize = a.getDimension(R.styleable.CalculatorFormula_stepTextSize,
- (mMaximumTextSize - mMinimumTextSize) / 3);
- a.recycle();
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- setupActionMode();
- } else {
- setupContextMenu();
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (!isLaidOut()) {
- // Prevent shrinking/resizing with our variable textSize.
- setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, mMaximumTextSize,
- false /* notifyListener */);
- setMinimumHeight(getLineHeight() + getCompoundPaddingBottom()
- + getCompoundPaddingTop());
- }
-
- // Ensure we are at least as big as our parent.
- final int width = MeasureSpec.getSize(widthMeasureSpec);
- if (getMinimumWidth() != width) {
- setMinimumWidth(width);
- }
-
- // Re-calculate our textSize based on new width.
- mWidthConstraint = MeasureSpec.getSize(widthMeasureSpec)
- - getPaddingLeft() - getPaddingRight();
- final float textSize = getVariableTextSize(getText());
- if (getTextSize() != textSize) {
- setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, textSize, false /* notifyListener */);
- }
-
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
-
- mClipboardManager.addPrimaryClipChangedListener(this);
- onPrimaryClipChanged();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- mClipboardManager.removePrimaryClipChangedListener(this);
- }
-
- @Override
- protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
- super.onTextChanged(text, start, lengthBefore, lengthAfter);
-
- setTextSize(TypedValue.COMPLEX_UNIT_PX, getVariableTextSize(text.toString()));
- }
-
- private void setTextSizeInternal(int unit, float size, boolean notifyListener) {
- final float oldTextSize = getTextSize();
- super.setTextSize(unit, size);
- if (notifyListener && mOnTextSizeChangeListener != null && getTextSize() != oldTextSize) {
- mOnTextSizeChangeListener.onTextSizeChanged(this, oldTextSize);
- }
- }
-
- @Override
- public void setTextSize(int unit, float size) {
- setTextSizeInternal(unit, size, true);
- }
-
- public float getMinimumTextSize() {
- return mMinimumTextSize;
- }
-
- public float getMaximumTextSize() {
- return mMaximumTextSize;
- }
-
- public float getVariableTextSize(CharSequence text) {
- if (mWidthConstraint < 0 || mMaximumTextSize <= mMinimumTextSize) {
- // Not measured, bail early.
- return getTextSize();
- }
-
- // Capture current paint state.
- mTempPaint.set(getPaint());
-
- // Step through increasing text sizes until the text would no longer fit.
- float lastFitTextSize = mMinimumTextSize;
- while (lastFitTextSize < mMaximumTextSize) {
- mTempPaint.setTextSize(Math.min(lastFitTextSize + mStepTextSize, mMaximumTextSize));
- if (Layout.getDesiredWidth(text, mTempPaint) > mWidthConstraint) {
- break;
- }
- lastFitTextSize = mTempPaint.getTextSize();
- }
-
- return lastFitTextSize;
- }
-
- /**
- * Functionally equivalent to setText(), but explicitly announce changes.
- * If the new text is an extension of the old one, announce the addition.
- * Otherwise, e.g. after deletion, announce the entire new text.
- */
- public void changeTextTo(CharSequence newText) {
- final CharSequence oldText = getText();
- final char separator = KeyMaps.translateResult(",").charAt(0);
- final CharSequence added = StringUtils.getExtensionIgnoring(newText, oldText, separator);
- if (added != null) {
- if (added.length() == 1) {
- // The algorithm for pronouncing a single character doesn't seem
- // to respect our hints. Don't give it the choice.
- final char c = added.charAt(0);
- final int id = KeyMaps.keyForChar(c);
- final String descr = KeyMaps.toDescriptiveString(getContext(), id);
- if (descr != null) {
- announceForAccessibility(descr);
- } else {
- announceForAccessibility(String.valueOf(c));
- }
- } else if (added.length() != 0) {
- announceForAccessibility(added);
- }
- } else {
- announceForAccessibility(newText);
- }
- setText(newText, BufferType.SPANNABLE);
- }
-
- public boolean stopActionModeOrContextMenu() {
- if (mActionMode != null) {
- mActionMode.finish();
- return true;
- }
- if (mContextMenu != null) {
- mContextMenu.close();
- return true;
- }
- return false;
- }
-
- public void setOnTextSizeChangeListener(OnTextSizeChangeListener listener) {
- mOnTextSizeChangeListener = listener;
- }
-
- public void setOnContextMenuClickListener(OnFormulaContextMenuClickListener listener) {
- mOnContextMenuClickListener = listener;
- }
-
- public void setOnDisplayMemoryOperationsListener(
- Calculator.OnDisplayMemoryOperationsListener listener) {
- mOnDisplayMemoryOperationsListener = listener;
- }
-
- /**
- * Use ActionMode for paste support on M and higher.
- */
- @TargetApi(Build.VERSION_CODES.M)
- private void setupActionMode() {
- mPasteActionModeCallback = new ActionMode.Callback2() {
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- if (onMenuItemClick(item)) {
- mode.finish();
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.setTag(TAG_ACTION_MODE);
- final MenuInflater inflater = mode.getMenuInflater();
- return createContextMenu(inflater, menu);
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- mActionMode = null;
- }
-
- @Override
- public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
- super.onGetContentRect(mode, view, outRect);
- outRect.top += getTotalPaddingTop();
- outRect.right -= getTotalPaddingRight();
- outRect.bottom -= getTotalPaddingBottom();
- // Encourage menu positioning over the rightmost 10% of the screen.
- outRect.left = (int) (outRect.right * 0.9f);
- }
- };
- setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- mActionMode = startActionMode(mPasteActionModeCallback, ActionMode.TYPE_FLOATING);
- return true;
- }
- });
- }
-
- /**
- * Use ContextMenu for paste support on L and lower.
- */
- private void setupContextMenu() {
- setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
- @Override
- public void onCreateContextMenu(ContextMenu contextMenu, View view,
- ContextMenu.ContextMenuInfo contextMenuInfo) {
- final MenuInflater inflater = new MenuInflater(getContext());
- createContextMenu(inflater, contextMenu);
- mContextMenu = contextMenu;
- for (int i = 0; i < contextMenu.size(); i++) {
- contextMenu.getItem(i).setOnMenuItemClickListener(CalculatorFormula.this);
- }
- }
- });
- setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- return showContextMenu();
- }
- });
- }
-
- private boolean createContextMenu(MenuInflater inflater, Menu menu) {
- final boolean isPasteEnabled = isPasteEnabled();
- final boolean isMemoryEnabled = isMemoryEnabled();
- if (!isPasteEnabled && !isMemoryEnabled) {
- 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 ClipData primaryClip = mClipboardManager.getPrimaryClip();
- if (primaryClip != null && mOnContextMenuClickListener != null) {
- mOnContextMenuClickListener.onPaste(primaryClip);
- }
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.memory_recall:
- mOnContextMenuClickListener.onMemoryRecall();
- return true;
- case R.id.menu_paste:
- paste();
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public void onPrimaryClipChanged() {
- setLongClickable(isPasteEnabled() || isMemoryEnabled());
- }
-
- public void onMemoryStateChanged() {
- setLongClickable(isPasteEnabled() || isMemoryEnabled());
- }
-
- private boolean isMemoryEnabled() {
- return mOnDisplayMemoryOperationsListener != null
- && mOnDisplayMemoryOperationsListener.shouldDisplayMemory();
- }
-
- private boolean isPasteEnabled() {
- final ClipData clip = mClipboardManager.getPrimaryClip();
- if (clip == null || clip.getItemCount() == 0) {
- return false;
- }
- CharSequence clipText = null;
- try {
- clipText = clip.getItemAt(0).coerceToText(getContext());
- } catch (Exception e) {
- Log.i("Calculator", "Error reading clipboard:", e);
- }
- return !TextUtils.isEmpty(clipText);
- }
-
- public interface OnTextSizeChangeListener {
- void onTextSizeChanged(TextView textView, float oldSize);
- }
-
- public interface OnFormulaContextMenuClickListener {
- boolean onPaste(ClipData clip);
- void onMemoryRecall();
- }
-}