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