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