/* * 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.content.res.Resources; import android.content.Context; import android.app.Activity; import android.util.Log; import android.view.View; import android.widget.Button; import java.text.DecimalFormatSymbols; import java.util.HashMap; import java.util.Locale; /** * Collection of mapping functions between key ids, characters, internationalized * and non-internationalized characters, etc. *
* KeyMap instances are not meaningful; everything here is static. * All functions are either pure, or are assumed to be called only from a single UI thread. */ public class KeyMaps { /** * Map key id to corresponding (internationalized) display string. * Pure function. */ public static String toString(Context context, int id) { switch(id) { case R.id.const_pi: return context.getString(R.string.const_pi); case R.id.const_e: return context.getString(R.string.const_e); case R.id.op_sqrt: return context.getString(R.string.op_sqrt); case R.id.op_fact: return context.getString(R.string.op_fact); case R.id.op_pct: return context.getString(R.string.op_pct); case R.id.fun_sin: return context.getString(R.string.fun_sin) + context.getString(R.string.lparen); case R.id.fun_cos: return context.getString(R.string.fun_cos) + context.getString(R.string.lparen); case R.id.fun_tan: return context.getString(R.string.fun_tan) + context.getString(R.string.lparen); case R.id.fun_arcsin: return context.getString(R.string.fun_arcsin) + context.getString(R.string.lparen); case R.id.fun_arccos: return context.getString(R.string.fun_arccos) + context.getString(R.string.lparen); case R.id.fun_arctan: return context.getString(R.string.fun_arctan) + context.getString(R.string.lparen); case R.id.fun_ln: return context.getString(R.string.fun_ln) + context.getString(R.string.lparen); case R.id.fun_log: return context.getString(R.string.fun_log) + context.getString(R.string.lparen); case R.id.fun_exp: // Button label doesn't work. return context.getString(R.string.exponential) + context.getString(R.string.lparen); case R.id.lparen: return context.getString(R.string.lparen); case R.id.rparen: return context.getString(R.string.rparen); case R.id.op_pow: return context.getString(R.string.op_pow); case R.id.op_mul: return context.getString(R.string.op_mul); case R.id.op_div: return context.getString(R.string.op_div); case R.id.op_add: return context.getString(R.string.op_add); case R.id.op_sqr: // Button label doesn't work. return context.getString(R.string.squared); case R.id.op_sub: return context.getString(R.string.op_sub); case R.id.dec_point: return context.getString(R.string.dec_point); case R.id.digit_0: return context.getString(R.string.digit_0); case R.id.digit_1: return context.getString(R.string.digit_1); case R.id.digit_2: return context.getString(R.string.digit_2); case R.id.digit_3: return context.getString(R.string.digit_3); case R.id.digit_4: return context.getString(R.string.digit_4); case R.id.digit_5: return context.getString(R.string.digit_5); case R.id.digit_6: return context.getString(R.string.digit_6); case R.id.digit_7: return context.getString(R.string.digit_7); case R.id.digit_8: return context.getString(R.string.digit_8); case R.id.digit_9: return context.getString(R.string.digit_9); default: return ""; } } /** * Map key id to corresponding (internationalized) descriptive string that can be used * to correctly read back a formula. * Only used for operators and individual characters; not used inside constants. * Returns null when we don't need a descriptive string. * Pure function. */ public static String toDescriptiveString(Context context, int id) { switch(id) { case R.id.op_fact: return context.getString(R.string.desc_op_fact); case R.id.fun_sin: return context.getString(R.string.desc_fun_sin) + " " + context.getString(R.string.desc_lparen); case R.id.fun_cos: return context.getString(R.string.desc_fun_cos) + " " + context.getString(R.string.desc_lparen); case R.id.fun_tan: return context.getString(R.string.desc_fun_tan) + " " + context.getString(R.string.desc_lparen); case R.id.fun_arcsin: return context.getString(R.string.desc_fun_arcsin) + " " + context.getString(R.string.desc_lparen); case R.id.fun_arccos: return context.getString(R.string.desc_fun_arccos) + " " + context.getString(R.string.desc_lparen); case R.id.fun_arctan: return context.getString(R.string.desc_fun_arctan) + " " + context.getString(R.string.desc_lparen); case R.id.fun_ln: return context.getString(R.string.desc_fun_ln) + " " + context.getString(R.string.desc_lparen); case R.id.fun_log: return context.getString(R.string.desc_fun_log) + " " + context.getString(R.string.desc_lparen); case R.id.fun_exp: return context.getString(R.string.desc_fun_exp) + " " + context.getString(R.string.desc_lparen); case R.id.lparen: return context.getString(R.string.desc_lparen); case R.id.rparen: return context.getString(R.string.desc_rparen); case R.id.op_pow: return context.getString(R.string.desc_op_pow); case R.id.dec_point: return context.getString(R.string.desc_dec_point); default: return null; } } /** * Does a button id correspond to a binary operator? * Pure function. */ public static boolean isBinary(int id) { switch(id) { case R.id.op_pow: case R.id.op_mul: case R.id.op_div: case R.id.op_add: case R.id.op_sub: return true; default: return false; } } /** * Does a button id correspond to a function that introduces an implicit lparen? * Pure function. */ public static boolean isFunc(int id) { switch(id) { case R.id.fun_sin: case R.id.fun_cos: case R.id.fun_tan: case R.id.fun_arcsin: case R.id.fun_arccos: case R.id.fun_arctan: case R.id.fun_ln: case R.id.fun_log: case R.id.fun_exp: return true; default: return false; } } /** * Does a button id correspond to a prefix operator? * Pure function. */ public static boolean isPrefix(int id) { switch(id) { case R.id.op_sqrt: case R.id.op_sub: return true; default: return false; } } /** * Does a button id correspond to a suffix operator? */ public static boolean isSuffix(int id) { switch (id) { case R.id.op_fact: case R.id.op_pct: case R.id.op_sqr: return true; default: return false; } } public static final int NOT_DIGIT = 10; public static final String ELLIPSIS = "\u2026"; public static final char MINUS_SIGN = '\u2212'; /** * Map key id to digit or NOT_DIGIT * Pure function. */ public static int digVal(int id) { switch (id) { case R.id.digit_0: return 0; case R.id.digit_1: return 1; case R.id.digit_2: return 2; case R.id.digit_3: return 3; case R.id.digit_4: return 4; case R.id.digit_5: return 5; case R.id.digit_6: return 6; case R.id.digit_7: return 7; case R.id.digit_8: return 8; case R.id.digit_9: return 9; default: return NOT_DIGIT; } } /** * Map digit to corresponding key. Inverse of above. * Pure function. */ public static int keyForDigVal(int v) { switch(v) { case 0: return R.id.digit_0; case 1: return R.id.digit_1; case 2: return R.id.digit_2; case 3: return R.id.digit_3; case 4: return R.id.digit_4; case 5: return R.id.digit_5; case 6: return R.id.digit_6; case 7: return R.id.digit_7; case 8: return R.id.digit_8; case 9: return R.id.digit_9; default: return View.NO_ID; } } // The following two are only used for recognizing additional // input characters from a physical keyboard. They are not used // for output internationalization. private static char mDecimalPt; private static char mPiChar; /** * Character used as a placeholder for digits that are currently unknown in a result that * is being computed. We initially generate blanks, and then use this as a replacement * during final translation. *
* Note: the character must correspond closely to the width of a digit, * otherwise the UI will visibly shift once the computation is finished. */ private static final char CHAR_DIGIT_UNKNOWN = '\u2007'; /** * Map typed function name strings to corresponding button ids. * We (now redundantly?) include both localized and English names. */ private static HashMap