1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.calculator2; 18 19 import android.content.Context; 20 import android.graphics.Rect; 21 import android.text.Editable; 22 import android.text.InputType; 23 import android.text.Spanned; 24 import android.text.method.NumberKeyListener; 25 import android.util.AttributeSet; 26 import android.view.animation.TranslateAnimation; 27 import android.widget.EditText; 28 import android.widget.ViewSwitcher; 29 30 /** 31 * Provides vertical scrolling for the input/result EditText. 32 */ 33 class CalculatorDisplay extends ViewSwitcher { 34 35 private static final String ATTR_MAX_DIGITS = "maxDigits"; 36 private static final int DEFAULT_MAX_DIGITS = 10; 37 38 // only these chars are accepted from keyboard 39 private static final char[] ACCEPTED_CHARS = 40 "0123456789.+-*/\u2212\u00d7\u00f7()!%^".toCharArray(); 41 42 private static final int ANIM_DURATION = 500; 43 44 enum Scroll { UP, DOWN, NONE } 45 46 TranslateAnimation inAnimUp; 47 TranslateAnimation outAnimUp; 48 TranslateAnimation inAnimDown; 49 TranslateAnimation outAnimDown; 50 51 private int mMaxDigits = DEFAULT_MAX_DIGITS; 52 53 public CalculatorDisplay(Context context, AttributeSet attrs) { 54 super(context, attrs); 55 mMaxDigits = attrs.getAttributeIntValue(null, ATTR_MAX_DIGITS, DEFAULT_MAX_DIGITS); 56 } 57 58 public int getMaxDigits() { 59 return mMaxDigits; 60 } 61 62 protected void setLogic(Logic logic) { 63 NumberKeyListener calculatorKeyListener = 64 new NumberKeyListener() { 65 public int getInputType() { 66 return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; 67 } 68 69 @Override 70 protected char[] getAcceptedChars() { 71 return ACCEPTED_CHARS; 72 } 73 74 @Override 75 public CharSequence filter(CharSequence source, int start, int end, 76 Spanned dest, int dstart, int dend) { 77 /* the EditText should still accept letters (eg. 'sin') 78 coming from the on-screen touch buttons, so don't filter anything. 79 */ 80 return null; 81 } 82 }; 83 84 Editable.Factory factory = new CalculatorEditable.Factory(logic); 85 for (int i = 0; i < 2; ++i) { 86 EditText text = (EditText) getChildAt(i); 87 text.setBackground(null); 88 text.setEditableFactory(factory); 89 text.setKeyListener(calculatorKeyListener); 90 text.setSingleLine(); 91 } 92 } 93 94 @Override 95 public void setOnKeyListener(OnKeyListener l) { 96 getChildAt(0).setOnKeyListener(l); 97 getChildAt(1).setOnKeyListener(l); 98 } 99 100 @Override 101 protected void onSizeChanged(int w, int h, int oldW, int oldH) { 102 inAnimUp = new TranslateAnimation(0, 0, h, 0); 103 inAnimUp.setDuration(ANIM_DURATION); 104 outAnimUp = new TranslateAnimation(0, 0, 0, -h); 105 outAnimUp.setDuration(ANIM_DURATION); 106 107 inAnimDown = new TranslateAnimation(0, 0, -h, 0); 108 inAnimDown.setDuration(ANIM_DURATION); 109 outAnimDown = new TranslateAnimation(0, 0, 0, h); 110 outAnimDown.setDuration(ANIM_DURATION); 111 } 112 113 void insert(String delta) { 114 EditText editor = (EditText) getCurrentView(); 115 int cursor = editor.getSelectionStart(); 116 editor.getText().insert(cursor, delta); 117 } 118 119 EditText getEditText() { 120 return (EditText) getCurrentView(); 121 } 122 123 Editable getText() { 124 EditText text = (EditText) getCurrentView(); 125 return text.getText(); 126 } 127 128 void setText(CharSequence text, Scroll dir) { 129 if (getText().length() == 0) { 130 dir = Scroll.NONE; 131 } 132 133 if (dir == Scroll.UP) { 134 setInAnimation(inAnimUp); 135 setOutAnimation(outAnimUp); 136 } else if (dir == Scroll.DOWN) { 137 setInAnimation(inAnimDown); 138 setOutAnimation(outAnimDown); 139 } else { // Scroll.NONE 140 setInAnimation(null); 141 setOutAnimation(null); 142 } 143 144 EditText editText = (EditText) getNextView(); 145 editText.setText(text); 146 //Calculator.log("selection to " + text.length() + "; " + text); 147 editText.setSelection(text.length()); 148 showNext(); 149 } 150 151 int getSelectionStart() { 152 EditText text = (EditText) getCurrentView(); 153 return text.getSelectionStart(); 154 } 155 156 @Override 157 protected void onFocusChanged(boolean gain, int direction, Rect prev) { 158 //Calculator.log("focus " + gain + "; " + direction + "; " + prev); 159 if (!gain) { 160 requestFocus(); 161 } 162 } 163 } 164