• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.text.Editable;
21 import android.text.Spanned;
22 import android.text.method.NumberKeyListener;
23 import android.util.AttributeSet;
24 import android.view.animation.TranslateAnimation;
25 import android.text.InputType;
26 import android.widget.EditText;
27 import android.widget.TextView;
28 import android.widget.ViewSwitcher;
29 import android.graphics.Rect;
30 import android.graphics.Paint;
31 
32 /**
33  * Provides vertical scrolling for the input/result EditText.
34  */
35 class CalculatorDisplay extends ViewSwitcher {
36     // only these chars are accepted from keyboard
37     private static final char[] ACCEPTED_CHARS =
38         "0123456789.+-*/\u2212\u00d7\u00f7()!%^".toCharArray();
39 
40     private static final int ANIM_DURATION = 500;
41     enum Scroll { UP, DOWN, NONE }
42 
43     TranslateAnimation inAnimUp;
44     TranslateAnimation outAnimUp;
45     TranslateAnimation inAnimDown;
46     TranslateAnimation outAnimDown;
47 
48     private Logic mLogic;
49     private boolean mComputedLineLength = false;
50 
CalculatorDisplay(Context context, AttributeSet attrs)51     public CalculatorDisplay(Context context, AttributeSet attrs) {
52         super(context, attrs);
53     }
54 
55     @Override
onFinishInflate()56     protected void onFinishInflate() {
57         super.onFinishInflate();
58         Calculator calc = (Calculator) getContext();
59         calc.adjustFontSize((TextView)getChildAt(0));
60         calc.adjustFontSize((TextView)getChildAt(1));
61     }
62 
63     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)64     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
65         super.onLayout(changed, left, top, right, bottom);
66         if (!mComputedLineLength) {
67             mLogic.setLineLength(getNumberFittingDigits((TextView) getCurrentView()));
68             mComputedLineLength = true;
69         }
70     }
71 
72     // compute the maximum number of digits that fit in the
73     // calculator display without scrolling.
getNumberFittingDigits(TextView display)74     private int getNumberFittingDigits(TextView display) {
75         int available = display.getWidth()
76             - display.getTotalPaddingLeft() - display.getTotalPaddingRight();
77         Paint paint = display.getPaint();
78         float digitWidth = paint.measureText("2222222222") / 10f;
79         return (int) (available / digitWidth);
80     }
81 
setLogic(Logic logic)82     protected void setLogic(Logic logic) {
83         mLogic = logic;
84         NumberKeyListener calculatorKeyListener =
85             new NumberKeyListener() {
86                 public int getInputType() {
87                     // Don't display soft keyboard.
88                     return InputType.TYPE_NULL;
89                 }
90 
91                 protected char[] getAcceptedChars() {
92                     return ACCEPTED_CHARS;
93                 }
94 
95                 public CharSequence filter(CharSequence source, int start, int end,
96                                            Spanned dest, int dstart, int dend) {
97                     /* the EditText should still accept letters (eg. 'sin')
98                        coming from the on-screen touch buttons, so don't filter anything.
99                     */
100                     return null;
101                 }
102             };
103 
104         Editable.Factory factory = new CalculatorEditable.Factory(logic);
105         for (int i = 0; i < 2; ++i) {
106             EditText text = (EditText) getChildAt(i);
107             text.setBackgroundDrawable(null);
108             text.setEditableFactory(factory);
109             text.setKeyListener(calculatorKeyListener);
110         }
111     }
112 
113     @Override
setOnKeyListener(OnKeyListener l)114     public void setOnKeyListener(OnKeyListener l) {
115         getChildAt(0).setOnKeyListener(l);
116         getChildAt(1).setOnKeyListener(l);
117     }
118 
119     @Override
onSizeChanged(int w, int h, int oldW, int oldH)120     protected void onSizeChanged(int w, int h, int oldW, int oldH) {
121         inAnimUp = new TranslateAnimation(0, 0, h, 0);
122         inAnimUp.setDuration(ANIM_DURATION);
123         outAnimUp = new TranslateAnimation(0, 0, 0, -h);
124         outAnimUp.setDuration(ANIM_DURATION);
125 
126         inAnimDown = new TranslateAnimation(0, 0, -h, 0);
127         inAnimDown.setDuration(ANIM_DURATION);
128         outAnimDown = new TranslateAnimation(0, 0, 0, h);
129         outAnimDown.setDuration(ANIM_DURATION);
130     }
131 
insert(String delta)132     void insert(String delta) {
133         EditText editor = (EditText) getCurrentView();
134         int cursor = editor.getSelectionStart();
135         editor.getText().insert(cursor, delta);
136     }
137 
getEditText()138     EditText getEditText() {
139         return (EditText) getCurrentView();
140     }
141 
getText()142     Editable getText() {
143         EditText text = (EditText) getCurrentView();
144         return text.getText();
145     }
146 
setText(CharSequence text, Scroll dir)147     void setText(CharSequence text, Scroll dir) {
148         if (getText().length() == 0) {
149             dir = Scroll.NONE;
150         }
151 
152         if (dir == Scroll.UP) {
153             setInAnimation(inAnimUp);
154             setOutAnimation(outAnimUp);
155         } else if (dir == Scroll.DOWN) {
156             setInAnimation(inAnimDown);
157             setOutAnimation(outAnimDown);
158         } else { // Scroll.NONE
159             setInAnimation(null);
160             setOutAnimation(null);
161         }
162 
163         EditText editText = (EditText) getNextView();
164         editText.setText(text);
165         //Calculator.log("selection to " + text.length() + "; " + text);
166         editText.setSelection(text.length());
167         showNext();
168     }
169 
setSelection(int i)170     void setSelection(int i) {
171         EditText text = (EditText) getCurrentView();
172         text.setSelection(i);
173     }
174 
getSelectionStart()175     int getSelectionStart() {
176         EditText text = (EditText) getCurrentView();
177         return text.getSelectionStart();
178     }
179 
180     @Override
onFocusChanged(boolean gain, int direction, Rect prev)181     protected void onFocusChanged(boolean gain, int direction, Rect prev) {
182         //Calculator.log("focus " + gain + "; " + direction + "; " + prev);
183         if (!gain) {
184             requestFocus();
185         }
186     }
187 }
188