diff --git a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml index 5a91dbeb0b2d1902a99608102303d17508897351..0b8229ca5f79fa6142641d4e61e8477eb49b3bdd 100644 --- a/java/res/layout-xlarge/keyboard_popup_honeycomb.xml +++ b/java/res/layout-xlarge/keyboard_popup_honeycomb.xml @@ -26,9 +26,9 @@ android:paddingLeft="40dip" android:paddingRight="40dip" > - <com.android.inputmethod.latin.BaseKeyboardView + <com.android.inputmethod.keyboard.KeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/BaseKeyboardView" + android:id="@+id/KeyboardView" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/java/res/layout/input_basic.xml b/java/res/layout/input_basic.xml index 168eba69194095bda17565fe34119dd1dd2c336a..7b85bae944152afaca3758c62db38ea06b9782fc 100644 --- a/java/res/layout/input_basic.xml +++ b/java/res/layout/input_basic.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" android:id="@+id/LatinkeyboardBaseView" diff --git a/java/res/layout/input_basic_highcontrast.xml b/java/res/layout/input_basic_highcontrast.xml index 19ff1db112d02983a7596a997e99d5e35c5e2c78..d9200fd5e8f6c8ff80dbcbd57fa60d142ce24044 100644 --- a/java/res/layout/input_basic_highcontrast.xml +++ b/java/res/layout/input_basic_highcontrast.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" diff --git a/java/res/layout/input_gingerbread.xml b/java/res/layout/input_gingerbread.xml index fe31321f1a8fde4881a531817e8d8e60f20a8447..6233e6dc67f308291af71ba98aa5521a56dc495e 100644 --- a/java/res/layout/input_gingerbread.xml +++ b/java/res/layout/input_gingerbread.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" android:id="@+id/LatinkeyboardBaseView" diff --git a/java/res/layout/input_honeycomb.xml b/java/res/layout/input_honeycomb.xml index 079e70c651fa58d410764001677165d66e5b6eee..b39387481dd07dc90cded3380a7b886b1420ce81 100644 --- a/java/res/layout/input_honeycomb.xml +++ b/java/res/layout/input_honeycomb.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" android:id="@+id/LatinkeyboardBaseView" diff --git a/java/res/layout/input_stone_bold.xml b/java/res/layout/input_stone_bold.xml index 5fb439acbc4ff07b2ffdbb844d9d36df815c7ea3..bf25e159769e69a3f71c4f19e436a1b026900631 100644 --- a/java/res/layout/input_stone_bold.xml +++ b/java/res/layout/input_stone_bold.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" android:id="@+id/LatinkeyboardBaseView" diff --git a/java/res/layout/input_stone_normal.xml b/java/res/layout/input_stone_normal.xml index 7a7b36894977b996aea5ef2cb1fa4679f887e481..cf47086120ff533c54e67f90f8f07551a55f6246 100644 --- a/java/res/layout/input_stone_normal.xml +++ b/java/res/layout/input_stone_normal.xml @@ -18,7 +18,7 @@ */ --> -<com.android.inputmethod.latin.LatinKeyboardView +<com.android.inputmethod.keyboard.LatinKeyboardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" android:id="@+id/LatinkeyboardBaseView" diff --git a/java/res/layout/input_stone_popup.xml b/java/res/layout/input_stone_popup.xml index 3a7b5b9ab4bd14c4432bdd99d34118f14370536a..b4da0453672107073bdd5ceaacdd5f2226b911b0 100644 --- a/java/res/layout/input_stone_popup.xml +++ b/java/res/layout/input_stone_popup.xml @@ -25,9 +25,9 @@ android:orientation="horizontal" android:background="@drawable/keyboard_popup_panel_background" > - <com.android.inputmethod.latin.BaseKeyboardView + <com.android.inputmethod.keyboard.KeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/BaseKeyboardView" + android:id="@+id/KeyboardView" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/java/res/layout/keyboard_popup.xml b/java/res/layout/keyboard_popup.xml index 929e17111f10a9f89addb02b60461cd77fa3bdfb..ac8134bfb1d3e18321dbbf38bfbf94248dcec74a 100644 --- a/java/res/layout/keyboard_popup.xml +++ b/java/res/layout/keyboard_popup.xml @@ -26,9 +26,9 @@ android:paddingLeft="16dip" android:paddingRight="16dip" > - <com.android.inputmethod.latin.BaseKeyboardView + <com.android.inputmethod.keyboard.KeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/BaseKeyboardView" + android:id="@+id/KeyboardView" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/java/res/layout/keyboard_popup_honeycomb.xml b/java/res/layout/keyboard_popup_honeycomb.xml index 63b5353813bc1cffaf9197e4b03dd9b301c50470..e5fcbd44c27728f84b7bc8ae639158288a3dd5fb 100644 --- a/java/res/layout/keyboard_popup_honeycomb.xml +++ b/java/res/layout/keyboard_popup_honeycomb.xml @@ -26,9 +26,9 @@ android:paddingLeft="24dip" android:paddingRight="24dip" > - <com.android.inputmethod.latin.BaseKeyboardView + <com.android.inputmethod.keyboard.KeyboardView xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" - android:id="@+id/BaseKeyboardView" + android:id="@+id/KeyboardView" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index ef7a968c980420521fbf9e6eb218e969f6630122..4fc5351bfc9100e8a425e76d092dfb253556e98a 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -16,7 +16,7 @@ <resources> - <declare-styleable name="BaseKeyboardView"> + <declare-styleable name="KeyboardView"> <!-- Default KeyboardView style. --> <attr name="keyboardViewStyle" format="reference" /> @@ -68,14 +68,14 @@ </attr> <attr name="colorScheme"> - <!-- This should be aligned with BaseKeyboardView.COLOR_SCHEME_* --> + <!-- This should be aligned with KeyboardView.COLOR_SCHEME_* --> <enum name="white" value="0" /> <enum name="black" value="1" /> </attr> </declare-styleable> - <declare-styleable name="BaseKeyboard"> + <declare-styleable name="Keyboard"> <!-- Default width of a key, in pixels or percentage of display width. --> <attr name="keyWidth" format="dimension|fraction" /> <!-- Default height of a key, in pixels or percentage of display width. --> @@ -86,7 +86,7 @@ <attr name="verticalGap" format="dimension|fraction" /> </declare-styleable> - <declare-styleable name="BaseKeyboard_Key"> + <declare-styleable name="Keyboard_Key"> <!-- The unicode value or comma-separated values that this key outputs. --> <attr name="codes" format="integer|string" /> <!-- The XML keyboard layout of any popup keyboard. --> @@ -114,7 +114,7 @@ <attr name="keyLabel" format="string" /> <!-- The key label option --> <attr name="keyLabelOption"> - <!-- This should be aligned with BaseKeyboardView.KEY_LABEL_OPTION_* --> + <!-- This should be aligned with KeyboardView.KEY_LABEL_OPTION_* --> <flag name="alignLeft" value="1" /> <flag name="alignRight" value="2" /> <flag name="alignBottom" value="8" /> @@ -135,7 +135,7 @@ <attr name="shiftedIcon" format="reference" /> </declare-styleable> - <declare-styleable name="BaseKeyboard_Row"> + <declare-styleable name="Keyboard_Row"> <!-- Row edge flags. --> <attr name="rowEdgeFlags"> <!-- Row is anchored to the top of the keyboard. --> @@ -145,12 +145,12 @@ </attr> </declare-styleable> - <declare-styleable name="BaseKeyboard_Include"> + <declare-styleable name="Keyboard_Include"> <attr name="keyboardLayout" format="reference" /> </declare-styleable> - <declare-styleable name="BaseKeyboard_Case"> - <!-- This should be aligned with KeyboardSwitcher.MODE_* --> + <declare-styleable name="Keyboard_Case"> + <!-- This should be aligned with KeyboardId.MODE_* --> <attr name="mode"> <enum name="text" value="0" /> <enum name="url" value="1" /> @@ -175,7 +175,7 @@ </attr> </declare-styleable> - <declare-styleable name="BaseKeyboard_KeyStyle"> + <declare-styleable name="Keyboard_KeyStyle"> <attr name="styleName" format="string" /> <attr name="parentStyle" format="string" /> </declare-styleable> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 02d21b43ba3e7a5d83437b9edd484ce0a850178e..130714fd39990e1105a0317f7b2b7f1ff676a41d 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -15,7 +15,7 @@ --> <resources> - <style name="BaseKeyboardView"> + <style name="KeyboardView"> <item name="android:background">@drawable/keyboard_background</item> <item name="keyBackground">@drawable/btn_keyboard_key</item> diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java new file mode 100644 index 0000000000000000000000000000000000000000..9b7937618178ab46a63636ed33b2411efbf9d937 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.keyboard.KeyboardParser.ParseException; +import com.android.inputmethod.keyboard.KeyStyles.KeyStyle; +import com.android.inputmethod.latin.R; + +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.Xml; + +/** + * Class for describing the position and characteristics of a single key in the keyboard. + */ +public class Key { + /** + * All the key codes (unicode or custom code) that this key could generate, zero'th + * being the most important. + */ + public int[] codes; + /** The unicode that this key generates in manual temporary upper case mode. */ + public int manualTemporaryUpperCaseCode; + + /** Label to display */ + public CharSequence label; + /** Option of the label */ + public int labelOption; + + /** Icon to display instead of a label. Icon takes precedence over a label */ + public Drawable icon; + /** Hint icon to display on the key in conjunction with the label */ + public Drawable hintIcon; + /** Preview version of the icon, for the preview popup */ + /** + * The hint icon to display on the key when keyboard is in manual temporary upper case + * mode. + */ + public Drawable manualTemporaryUpperCaseHintIcon; + + public Drawable iconPreview; + /** Width of the key, not including the gap */ + public int width; + /** Height of the key, not including the gap */ + public int height; + /** The horizontal gap before this key */ + public int gap; + /** Whether this key is sticky, i.e., a toggle key */ + public boolean sticky; + /** X coordinate of the key in the keyboard layout */ + public int x; + /** Y coordinate of the key in the keyboard layout */ + public int y; + /** The current pressed state of this key */ + public boolean pressed; + /** If this is a sticky key, is it on? */ + public boolean on; + /** Text to output when pressed. This can be multiple characters, like ".com" */ + public CharSequence text; + /** Popup characters */ + public CharSequence popupCharacters; + + /** + * Flags that specify the anchoring to edges of the keyboard for detecting touch events + * that are just out of the boundary of the key. This is a bit mask of + * {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT}, + * {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}. + */ + public int edgeFlags; + /** Whether this is a modifier key, such as Shift or Alt */ + public boolean modifier; + /** The Keyboard that this key belongs to */ + protected final Keyboard keyboard; + /** + * If this key pops up a mini keyboard, this is the resource id for the XML layout for that + * keyboard. + */ + public int popupResId; + /** Whether this key repeats itself when held down */ + public boolean repeatable; + + + private final static int[] KEY_STATE_NORMAL_ON = { + android.R.attr.state_checkable, + android.R.attr.state_checked + }; + + private final static int[] KEY_STATE_PRESSED_ON = { + android.R.attr.state_pressed, + android.R.attr.state_checkable, + android.R.attr.state_checked + }; + + private final static int[] KEY_STATE_NORMAL_OFF = { + android.R.attr.state_checkable + }; + + private final static int[] KEY_STATE_PRESSED_OFF = { + android.R.attr.state_pressed, + android.R.attr.state_checkable + }; + + private final static int[] KEY_STATE_NORMAL = { + }; + + private final static int[] KEY_STATE_PRESSED = { + android.R.attr.state_pressed + }; + + /** Create an empty key with no attributes. */ + public Key(Row parent) { + keyboard = parent.parent; + height = parent.defaultHeight; + gap = parent.defaultHorizontalGap; + width = parent.defaultWidth - gap; + edgeFlags = parent.rowEdgeFlags; + } + + /** Create a key with the given top-left coordinate and extract its attributes from + * the XML parser. + * @param res resources associated with the caller's context + * @param parent the row that this key belongs to. The row must already be attached to + * a {@link Keyboard}. + * @param x the x coordinate of the top-left + * @param y the y coordinate of the top-left + * @param parser the XML parser containing the attributes for this key + */ + public Key(Resources res, Row parent, int x, int y, XmlResourceParser parser, + KeyStyles keyStyles) { + this(parent); + + TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.Keyboard); + height = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_keyHeight, + keyboard.mDisplayHeight, parent.defaultHeight); + gap = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_horizontalGap, + keyboard.mDisplayWidth, parent.defaultHorizontalGap); + width = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_keyWidth, + keyboard.mDisplayWidth, parent.defaultWidth) - gap; + a.recycle(); + + a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); + + final KeyStyle style; + if (a.hasValue(R.styleable.Keyboard_Key_keyStyle)) { + String styleName = a.getString(R.styleable.Keyboard_Key_keyStyle); + style = keyStyles.getKeyStyle(styleName); + if (style == null) + throw new ParseException("Unknown key style: " + styleName, parser); + } else { + style = keyStyles.getEmptyKeyStyle(); + } + + // Horizontal gap is divided equally to both sides of the key. + this.x = x + gap / 2; + this.y = y; + + codes = style.getIntArray(a, R.styleable.Keyboard_Key_codes); + iconPreview = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview); + Keyboard.setDefaultBounds(iconPreview); + popupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters); + popupResId = style.getResourceId(a, R.styleable.Keyboard_Key_popupKeyboard, 0); + repeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false); + modifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false); + sticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false); + edgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0); + edgeFlags |= parent.rowEdgeFlags; + + icon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon); + Keyboard.setDefaultBounds(icon); + hintIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyHintIcon); + Keyboard.setDefaultBounds(hintIcon); + manualTemporaryUpperCaseHintIcon = style.getDrawable(a, + R.styleable.Keyboard_Key_manualTemporaryUpperCaseHintIcon); + Keyboard.setDefaultBounds(manualTemporaryUpperCaseHintIcon); + + label = style.getText(a, R.styleable.Keyboard_Key_keyLabel); + labelOption = style.getFlag(a, R.styleable.Keyboard_Key_keyLabelOption, 0); + manualTemporaryUpperCaseCode = style.getInt(a, + R.styleable.Keyboard_Key_manualTemporaryUpperCaseCode, 0); + text = style.getText(a, R.styleable.Keyboard_Key_keyOutputText); + final Drawable shiftedIcon = style.getDrawable(a, + R.styleable.Keyboard_Key_shiftedIcon); + if (shiftedIcon != null) + keyboard.getShiftedIcons().put(this, shiftedIcon); + + if (codes == null && !TextUtils.isEmpty(label)) { + codes = new int[] { label.charAt(0) }; + } + a.recycle(); + } + + /** + * Informs the key that it has been pressed, in case it needs to change its appearance or + * state. + * @see #onReleased(boolean) + */ + public void onPressed() { + pressed = !pressed; + } + + /** + * Changes the pressed state of the key. If it is a sticky key, it will also change the + * toggled state of the key if the finger was release inside. + * @param inside whether the finger was released inside the key + * @see #onPressed() + */ + public void onReleased(boolean inside) { + pressed = !pressed; + if (sticky) { + on = !on; + } + } + + /** + * Detects if a point falls inside this key. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return whether or not the point falls inside the key. If the key is attached to an + * edge, it will assume that all points between the key and the edge are considered to be + * inside the key. + */ + public boolean isInside(int x, int y) { + boolean leftEdge = (edgeFlags & Keyboard.EDGE_LEFT) > 0; + boolean rightEdge = (edgeFlags & Keyboard.EDGE_RIGHT) > 0; + boolean topEdge = (edgeFlags & Keyboard.EDGE_TOP) > 0; + boolean bottomEdge = (edgeFlags & Keyboard.EDGE_BOTTOM) > 0; + if ((x >= this.x || (leftEdge && x <= this.x + this.width)) + && (x < this.x + this.width || (rightEdge && x >= this.x)) + && (y >= this.y || (topEdge && y <= this.y + this.height)) + && (y < this.y + this.height || (bottomEdge && y >= this.y))) { + return true; + } else { + return false; + } + } + + /** + * Returns the square of the distance to the nearest edge of the key and the given point. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return the square of the distance of the point from the nearest edge of the key + */ + public int squaredDistanceToEdge(int x, int y) { + final int left = this.x; + final int right = left + this.width; + final int top = this.y; + final int bottom = top + this.height; + final int edgeX = x < left ? left : (x > right ? right : x); + final int edgeY = y < top ? top : (y > bottom ? bottom : y); + final int dx = x - edgeX; + final int dy = y - edgeY; + return dx * dx + dy * dy; + } + + /** + * Returns the drawable state for the key, based on the current state and type of the key. + * @return the drawable state of the key. + * @see android.graphics.drawable.StateListDrawable#setState(int[]) + */ + public int[] getCurrentDrawableState() { + int[] states = KEY_STATE_NORMAL; + + if (on) { + if (pressed) { + states = KEY_STATE_PRESSED_ON; + } else { + states = KEY_STATE_NORMAL_ON; + } + } else { + if (sticky) { + if (pressed) { + states = KEY_STATE_PRESSED_OFF; + } else { + states = KEY_STATE_NORMAL_OFF; + } + } else { + if (pressed) { + states = KEY_STATE_PRESSED; + } + } + } + return states; + } +} diff --git a/java/src/com/android/inputmethod/latin/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java similarity index 91% rename from java/src/com/android/inputmethod/latin/KeyDetector.java rename to java/src/com/android/inputmethod/keyboard/KeyDetector.java index 600a12fe52e75480c538c84e14f26ae778cea5aa..777a7952096965ca5e688679052609d7a2f5726c 100644 --- a/java/src/com/android/inputmethod/latin/KeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java @@ -14,15 +14,15 @@ * the License. */ -package com.android.inputmethod.latin; - -import com.android.inputmethod.latin.BaseKeyboard.Key; +package com.android.inputmethod.keyboard; import java.util.Arrays; import java.util.List; -abstract class KeyDetector { - protected BaseKeyboard mKeyboard; +public abstract class KeyDetector { + public static final int NOT_A_KEY = -1; + + protected Keyboard mKeyboard; private Key[] mKeys; @@ -34,7 +34,7 @@ abstract class KeyDetector { protected int mProximityThresholdSquare; - public Key[] setKeyboard(BaseKeyboard keyboard, float correctionX, float correctionY) { + public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { if (keyboard == null) throw new NullPointerException(); mCorrectionX = (int)correctionX; @@ -84,7 +84,7 @@ abstract class KeyDetector { */ public int[] newCodeArray() { int[] codes = new int[getMaxNearbyKeys()]; - Arrays.fill(codes, BaseKeyboardView.NOT_A_KEY); + Arrays.fill(codes, NOT_A_KEY); return codes; } diff --git a/java/src/com/android/inputmethod/latin/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/KeyStyles.java similarity index 86% rename from java/src/com/android/inputmethod/latin/KeyStyles.java rename to java/src/com/android/inputmethod/keyboard/KeyStyles.java index fceede7c3dc8d49a2d18900e1a146cae7edba509..daa9c86d11a7ab491f2390dc969d5d2a9534b20a 100644 --- a/java/src/com/android/inputmethod/latin/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/KeyStyles.java @@ -14,9 +14,10 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboardParser.ParseException; +import com.android.inputmethod.keyboard.KeyboardParser.ParseException; +import com.android.inputmethod.latin.R; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; @@ -48,30 +49,37 @@ public class KeyStyles { private EmptyKeyStyle() { } + @Override public int[] getIntArray(TypedArray a, int index) { return parseIntArray(a, index); } + @Override public Drawable getDrawable(TypedArray a, int index) { return a.getDrawable(index); } + @Override public CharSequence getText(TypedArray a, int index) { return a.getText(index); } + @Override public int getResourceId(TypedArray a, int index, int defaultValue) { return a.getResourceId(index, defaultValue); } + @Override public int getInt(TypedArray a, int index, int defaultValue) { return a.getInt(index, defaultValue); } + @Override public int getFlag(TypedArray a, int index, int defaultValue) { return a.getInt(index, defaultValue); } + @Override public boolean getBoolean(TypedArray a, int index, boolean defaultValue) { return a.getBoolean(index, defaultValue); } @@ -156,18 +164,18 @@ public class KeyStyles { private void parseKeyStyleAttributes(TypedArray a) { // TODO: Currently not all Key attributes can be declared as style. - readIntArray(a, R.styleable.BaseKeyboard_Key_codes); - readText(a, R.styleable.BaseKeyboard_Key_keyLabel); - readFlag(a, R.styleable.BaseKeyboard_Key_keyLabelOption); - readText(a, R.styleable.BaseKeyboard_Key_keyOutputText); - readDrawable(a, R.styleable.BaseKeyboard_Key_keyIcon); - readDrawable(a, R.styleable.BaseKeyboard_Key_iconPreview); - readDrawable(a, R.styleable.BaseKeyboard_Key_keyHintIcon); - readDrawable(a, R.styleable.BaseKeyboard_Key_shiftedIcon); - readResourceId(a, R.styleable.BaseKeyboard_Key_popupKeyboard); - readBoolean(a, R.styleable.BaseKeyboard_Key_isModifier); - readBoolean(a, R.styleable.BaseKeyboard_Key_isSticky); - readBoolean(a, R.styleable.BaseKeyboard_Key_isRepeatable); + readIntArray(a, R.styleable.Keyboard_Key_codes); + readText(a, R.styleable.Keyboard_Key_keyLabel); + readFlag(a, R.styleable.Keyboard_Key_keyLabelOption); + readText(a, R.styleable.Keyboard_Key_keyOutputText); + readDrawable(a, R.styleable.Keyboard_Key_keyIcon); + readDrawable(a, R.styleable.Keyboard_Key_iconPreview); + readDrawable(a, R.styleable.Keyboard_Key_keyHintIcon); + readDrawable(a, R.styleable.Keyboard_Key_shiftedIcon); + readResourceId(a, R.styleable.Keyboard_Key_popupKeyboard); + readBoolean(a, R.styleable.Keyboard_Key_isModifier); + readBoolean(a, R.styleable.Keyboard_Key_isSticky); + readBoolean(a, R.styleable.Keyboard_Key_isRepeatable); } private void readDrawable(TypedArray a, int index) { @@ -211,14 +219,14 @@ public class KeyStyles { public void parseKeyStyleAttributes(TypedArray a, TypedArray keyAttrs, XmlResourceParser parser) { - String styleName = a.getString(R.styleable.BaseKeyboard_KeyStyle_styleName); + String styleName = a.getString(R.styleable.Keyboard_KeyStyle_styleName); if (mStyles.containsKey(styleName)) throw new ParseException("duplicate key style declared: " + styleName, parser); final DeclaredKeyStyle style = new DeclaredKeyStyle(); - if (a.hasValue(R.styleable.BaseKeyboard_KeyStyle_parentStyle)) { + if (a.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) { String parentStyle = a.getString( - R.styleable.BaseKeyboard_KeyStyle_parentStyle); + R.styleable.Keyboard_KeyStyle_parentStyle); final DeclaredKeyStyle parent = mStyles.get(parentStyle); if (parent == null) throw new ParseException("Unknown parentStyle " + parent, parser); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java new file mode 100644 index 0000000000000000000000000000000000000000..b7541557990e9abc1f410907c928984f672a3c15 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.latin.R; + +import org.xmlpull.v1.XmlPullParserException; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.graphics.drawable.Drawable; +import android.util.Log; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard + * consists of rows of keys. + * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p> + * <pre> + * <Keyboard + * latin:keyWidth="%10p" + * latin:keyHeight="50px" + * latin:horizontalGap="2px" + * latin:verticalGap="2px" > + * <Row latin:keyWidth="32px" > + * <Key latin:keyLabel="A" /> + * ... + * </Row> + * ... + * </Keyboard> + * </pre> + */ +public class Keyboard { + + static final String TAG = "Keyboard"; + + public static final int EDGE_LEFT = 0x01; + public static final int EDGE_RIGHT = 0x02; + public static final int EDGE_TOP = 0x04; + public static final int EDGE_BOTTOM = 0x08; + + public static final int KEYCODE_SHIFT = -1; + public static final int KEYCODE_MODE_CHANGE = -2; + public static final int KEYCODE_CANCEL = -3; + public static final int KEYCODE_DONE = -4; + public static final int KEYCODE_DELETE = -5; + public static final int KEYCODE_ALT = -6; + + /** Horizontal gap default for all rows */ + int mDefaultHorizontalGap; + + /** Default key width */ + int mDefaultWidth; + + /** Default key height */ + int mDefaultHeight; + + /** Default gap between rows */ + int mDefaultVerticalGap; + + /** Is the keyboard in the shifted state */ + private boolean mShifted; + + /** List of shift keys in this keyboard */ + private final List<Key> mShiftKeys = new ArrayList<Key>(); + + /** List of shift keys and its shifted state icon */ + private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>(); + + /** Total height of the keyboard, including the padding and keys */ + private int mTotalHeight; + + /** + * Total width of the keyboard, including left side gaps and keys, but not any gaps on the + * right side. + */ + private int mTotalWidth; + + /** List of keys in this keyboard */ + private final List<Key> mKeys = new ArrayList<Key>(); + + /** Width of the screen available to fit the keyboard */ + final int mDisplayWidth; + + /** Height of the screen */ + final int mDisplayHeight; + + protected final KeyboardId mId; + + // Variables for pre-computing nearest keys. + + public final int GRID_WIDTH; + public final int GRID_HEIGHT; + private final int GRID_SIZE; + private int mCellWidth; + private int mCellHeight; + private int[][] mGridNeighbors; + private int mProximityThreshold; + private static int[] EMPTY_INT_ARRAY = new int[0]; + /** Number of key widths from current touch point to search for nearest keys. */ + private static float SEARCH_DISTANCE = 1.2f; + + /** + * Creates a keyboard from the given xml key layout file. + * @param context the application or service context + * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. + */ + public Keyboard(Context context, int xmlLayoutResId) { + this(context, xmlLayoutResId, null); + } + + /** + * Creates a keyboard from the given keyboard identifier. + * @param context the application or service context + * @param id keyboard identifier + */ + public Keyboard(Context context, KeyboardId id) { + this(context, id.getXmlId(), id); + } + + /** + * Creates a keyboard from the given xml key layout file. + * @param context the application or service context + * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. + * @param id keyboard identifier + */ + private Keyboard(Context context, int xmlLayoutResId, KeyboardId id) { + this(context, xmlLayoutResId, id, + context.getResources().getDisplayMetrics().widthPixels, + context.getResources().getDisplayMetrics().heightPixels); + } + + private Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width, + int height) { + Resources res = context.getResources(); + GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width); + GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height); + GRID_SIZE = GRID_WIDTH * GRID_HEIGHT; + + mDisplayWidth = width; + mDisplayHeight = height; + + mDefaultHorizontalGap = 0; + setKeyWidth(mDisplayWidth / 10); + mDefaultVerticalGap = 0; + mDefaultHeight = mDefaultWidth; + mId = id; + loadKeyboard(context, xmlLayoutResId); + } + + /** + * <p>Creates a blank keyboard from the given resource file and populates it with the specified + * characters in left-to-right, top-to-bottom fashion, using the specified number of columns. + * </p> + * <p>If the specified number of columns is -1, then the keyboard will fit as many keys as + * possible in each row.</p> + * @param context the application or service context + * @param layoutTemplateResId the layout template file, containing no keys. + * @param characters the list of characters to display on the keyboard. One key will be created + * for each character. + * @param columns the number of columns of keys to display. If this number is greater than the + * number of keys that can fit in a row, it will be ignored. If this number is -1, the + * keyboard will fit as many keys as possible in each row. + */ + public Keyboard(Context context, int layoutTemplateResId, + CharSequence characters, int columns, int horizontalPadding) { + this(context, layoutTemplateResId); + int x = 0; + int y = 0; + int column = 0; + mTotalWidth = 0; + + Row row = new Row(this); + row.defaultHeight = mDefaultHeight; + row.defaultWidth = mDefaultWidth; + row.defaultHorizontalGap = mDefaultHorizontalGap; + row.verticalGap = mDefaultVerticalGap; + row.rowEdgeFlags = EDGE_TOP | EDGE_BOTTOM; + final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns; + for (int i = 0; i < characters.length(); i++) { + char c = characters.charAt(i); + if (column >= maxColumns + || x + mDefaultWidth + horizontalPadding > mDisplayWidth) { + x = 0; + y += mDefaultVerticalGap + mDefaultHeight; + column = 0; + } + final Key key = new Key(row); + // Horizontal gap is divided equally to both sides of the key. + key.x = x + key.gap / 2; + key.y = y; + key.label = String.valueOf(c); + key.codes = new int[] { c }; + column++; + x += key.width + key.gap; + mKeys.add(key); + if (x > mTotalWidth) { + mTotalWidth = x; + } + } + mTotalHeight = y + mDefaultHeight; + } + + public KeyboardId getKeyboardId() { + return mId; + } + + public List<Key> getKeys() { + return mKeys; + } + + protected int getHorizontalGap() { + return mDefaultHorizontalGap; + } + + protected void setHorizontalGap(int gap) { + mDefaultHorizontalGap = gap; + } + + protected int getVerticalGap() { + return mDefaultVerticalGap; + } + + protected void setVerticalGap(int gap) { + mDefaultVerticalGap = gap; + } + + protected int getKeyHeight() { + return mDefaultHeight; + } + + protected void setKeyHeight(int height) { + mDefaultHeight = height; + } + + protected int getKeyWidth() { + return mDefaultWidth; + } + + protected void setKeyWidth(int width) { + mDefaultWidth = width; + final int threshold = (int) (width * SEARCH_DISTANCE); + mProximityThreshold = threshold * threshold; + } + + /** + * Returns the total height of the keyboard + * @return the total height of the keyboard + */ + public int getHeight() { + return mTotalHeight; + } + + public int getMinWidth() { + return mTotalWidth; + } + + public int getKeyboardHeight() { + return mDisplayHeight; + } + + public int getKeyboardWidth() { + return mDisplayWidth; + } + + public boolean setShifted(boolean shiftState) { + for (final Key key : mShiftKeys) { + key.on = shiftState; + } + if (mShifted != shiftState) { + mShifted = shiftState; + return true; + } + return false; + } + + public boolean isShiftedOrShiftLocked() { + return mShifted; + } + + public List<Key> getShiftKeys() { + return mShiftKeys; + } + + public Map<Key, Drawable> getShiftedIcons() { + return mShiftedIcons; + } + + private void computeNearestNeighbors() { + // Round-up so we don't have any pixels outside the grid + mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; + mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT; + mGridNeighbors = new int[GRID_SIZE][]; + final int[] indices = new int[mKeys.size()]; + final int gridWidth = GRID_WIDTH * mCellWidth; + final int gridHeight = GRID_HEIGHT * mCellHeight; + final int threshold = mProximityThreshold; + for (int x = 0; x < gridWidth; x += mCellWidth) { + for (int y = 0; y < gridHeight; y += mCellHeight) { + final int centerX = x + mCellWidth / 2; + final int centerY = y + mCellHeight / 2; + int count = 0; + for (int i = 0; i < mKeys.size(); i++) { + final Key key = mKeys.get(i); + if (key.squaredDistanceToEdge(centerX, centerY) < threshold) + indices[count++] = i; + } + final int[] cell = new int[count]; + System.arraycopy(indices, 0, cell, 0, count); + mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell; + } + } + } + + /** + * Returns the indices of the keys that are closest to the given point. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return the array of integer indices for the nearest keys to the given point. If the given + * point is out of range, then an array of size zero is returned. + */ + public int[] getNearestKeys(int x, int y) { + if (mGridNeighbors == null) computeNearestNeighbors(); + if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) { + int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth); + if (index < GRID_SIZE) { + return mGridNeighbors[index]; + } + } + return EMPTY_INT_ARRAY; + } + + // TODO should be private + protected Row createRowFromXml(Resources res, XmlResourceParser parser) { + return new Row(res, this, parser); + } + + // TODO should be private + protected Key createKeyFromXml(Resources res, Row parent, int x, int y, + XmlResourceParser parser, KeyStyles keyStyles) { + return new Key(res, parent, x, y, parser, keyStyles); + } + + private void loadKeyboard(Context context, int xmlLayoutResId) { + try { + final Resources res = context.getResources(); + KeyboardParser parser = new KeyboardParser(this, res); + parser.parseKeyboard(res.getXml(xmlLayoutResId)); + // mTotalWidth is the width of this keyboard which is maximum width of row. + mTotalWidth = parser.getMaxRowWidth(); + mTotalHeight = parser.getTotalHeight(); + } catch (XmlPullParserException e) { + Log.w(TAG, "keyboard XML parse error: " + e); + throw new IllegalArgumentException(e); + } catch (IOException e) { + Log.w(TAG, "keyboard XML parse error: " + e); + throw new RuntimeException(e); + } + } + + protected static void setDefaultBounds(Drawable drawable) { + if (drawable != null) + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight()); + } +} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java new file mode 100644 index 0000000000000000000000000000000000000000..e52db295709a721a228910162e7af74a23dbdca0 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +public interface KeyboardActionListener { + + /** + * Called when the user presses a key. This is sent before the + * {@link #onKey} is called. For keys that repeat, this is only + * called once. + * + * @param primaryCode + * the unicode of the key being pressed. If the touch is + * not on a valid key, the value will be zero. + */ + void onPress(int primaryCode); + + /** + * Called when the user releases a key. This is sent after the + * {@link #onKey} is called. For keys that repeat, this is only + * called once. + * + * @param primaryCode + * the code of the key that was released + */ + void onRelease(int primaryCode); + + /** + * Send a key press to the listener. + * + * @param primaryCode + * this is the key that was pressed + * @param keyCodes + * the codes for all the possible alternative keys with + * the primary code being the first. If the primary key + * code is a single character such as an alphabet or + * number or symbol, the alternatives will include other + * characters that may be on the same key or adjacent + * keys. These codes are useful to correct for + * accidental presses of a key adjacent to the intended + * key. + * @param x + * x-coordinate pixel of touched event. If onKey is not called by onTouchEvent, + * the value should be NOT_A_TOUCH_COORDINATE. + * @param y + * y-coordinate pixel of touched event. If onKey is not called by onTouchEvent, + * the value should be NOT_A_TOUCH_COORDINATE. + */ + void onKey(int primaryCode, int[] keyCodes, int x, int y); + + /** + * Sends a sequence of characters to the listener. + * + * @param text + * the sequence of characters to be displayed. + */ + void onText(CharSequence text); + + /** + * Called when user released a finger outside any key. + */ + void onCancel(); + + /** + * Called when the user quickly moves the finger from right to + * left. + */ + void swipeLeft(); + + /** + * Called when the user quickly moves the finger from left to + * right. + */ + void swipeRight(); + + /** + * Called when the user quickly moves the finger from up to down. + */ + void swipeDown(); + + /** + * Called when the user quickly moves the finger from down to up. + */ + void swipeUp(); +} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java new file mode 100644 index 0000000000000000000000000000000000000000..289e4c0e815d56c5a34213a2a691e182f7fb949c --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.latin.R; + +import android.view.inputmethod.EditorInfo; + +import java.util.Arrays; +import java.util.Locale; + +/** + * Represents the parameters necessary to construct a new LatinKeyboard, + * which also serve as a unique identifier for each keyboard type. + */ +public class KeyboardId { + public static final int MODE_TEXT = 0; + public static final int MODE_URL = 1; + public static final int MODE_EMAIL = 2; + public static final int MODE_IM = 3; + public static final int MODE_WEB = 4; + public static final int MODE_PHONE = 5; + public static final int MODE_NUMBER = 6; + + public final Locale mLocale; + public final int mOrientation; + public final int mMode; + public final int mXmlId; + public final int mColorScheme; + public final boolean mHasSettingsKey; + public final boolean mVoiceKeyEnabled; + public final boolean mHasVoiceKey; + public final int mImeOptions; + public final boolean mEnableShiftLock; + + private final int mHashCode; + + public KeyboardId(Locale locale, int orientation, int mode, + int xmlId, int colorScheme, boolean hasSettingsKey, boolean voiceKeyEnabled, + boolean hasVoiceKey, int imeOptions, boolean enableShiftLock) { + this.mLocale = locale; + this.mOrientation = orientation; + this.mMode = mode; + this.mXmlId = xmlId; + this.mColorScheme = colorScheme; + this.mHasSettingsKey = hasSettingsKey; + this.mVoiceKeyEnabled = voiceKeyEnabled; + this.mHasVoiceKey = hasVoiceKey; + // We are interested only in IME_MASK_ACTION enum value and IME_FLAG_NO_ENTER_ACTION. + this.mImeOptions = imeOptions + & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION); + this.mEnableShiftLock = enableShiftLock; + + this.mHashCode = Arrays.hashCode(new Object[] { + locale, + orientation, + mode, + xmlId, + colorScheme, + hasSettingsKey, + voiceKeyEnabled, + hasVoiceKey, + imeOptions, + enableShiftLock, + }); + } + + public int getXmlId() { + return mXmlId; + } + + public boolean isAlphabetMode() { + return mXmlId == R.xml.kbd_qwerty; + } + + @Override + public boolean equals(Object other) { + return other instanceof KeyboardId && equals((KeyboardId) other); + } + + boolean equals(KeyboardId other) { + return other.mLocale.equals(this.mLocale) + && other.mOrientation == this.mOrientation + && other.mMode == this.mMode + && other.mXmlId == this.mXmlId + && other.mColorScheme == this.mColorScheme + && other.mHasSettingsKey == this.mHasSettingsKey + && other.mVoiceKeyEnabled == this.mVoiceKeyEnabled + && other.mHasVoiceKey == this.mHasVoiceKey + && other.mImeOptions == this.mImeOptions + && other.mEnableShiftLock == this.mEnableShiftLock; + } + + @Override + public int hashCode() { + return mHashCode; + } + + @Override + public String toString() { + return String.format("[%s %s %5s imeOptions=0x%08x xml=0x%08x %s%s%s%s%s]", + mLocale, + (mOrientation == 1 ? "port" : "land"), + modeName(mMode), + mImeOptions, + mXmlId, + colorSchemeName(mColorScheme), + (mHasSettingsKey ? " hasSettingsKey" : ""), + (mVoiceKeyEnabled ? " voiceKeyEnabled" : ""), + (mHasVoiceKey ? " hasVoiceKey" : ""), + (mEnableShiftLock ? " enableShiftLock" : "")); + } + + private static String modeName(int mode) { + switch (mode) { + case MODE_TEXT: return "text"; + case MODE_URL: return "url"; + case MODE_EMAIL: return "email"; + case MODE_IM: return "im"; + case MODE_WEB: return "web"; + case MODE_PHONE: return "phone"; + case MODE_NUMBER: return "number"; + } + return null; + } + + private static String colorSchemeName(int colorScheme) { + switch (colorScheme) { + case KeyboardView.COLOR_SCHEME_WHITE: return "white"; + case KeyboardView.COLOR_SCHEME_BLACK: return "black"; + } + return null; + } +} diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java similarity index 89% rename from java/src/com/android/inputmethod/latin/BaseKeyboardParser.java rename to java/src/com/android/inputmethod/keyboard/KeyboardParser.java index 38b2a1b57cec8b7f132b321ab2cfb109d468c3d3..2147ee2891e3ea20fee282114860b887fce66082 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java @@ -14,11 +14,9 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboard.Key; -import com.android.inputmethod.latin.BaseKeyboard.Row; -import com.android.inputmethod.latin.KeyboardSwitcher.KeyboardId; +import com.android.inputmethod.latin.R; import org.xmlpull.v1.XmlPullParserException; @@ -36,7 +34,7 @@ import java.util.List; /** * Parser for BaseKeyboard. * - * This class parses Keyboard XML file and fill out keys in BaseKeyboard. + * This class parses Keyboard XML file and fill out keys in Keyboard. * The Keyboard XML file looks like: * <pre> * >!-- xml/keyboard.xml --< @@ -102,8 +100,8 @@ import java.util.List; * </pre> */ -public class BaseKeyboardParser { - private static final String TAG = "BaseKeyboardParser"; +public class KeyboardParser { + private static final String TAG = "KeyboardParser"; private static final boolean DEBUG_TAG = false; // Keyboard XML Tags @@ -118,7 +116,7 @@ public class BaseKeyboardParser { private static final String TAG_DEFAULT = "default"; private static final String TAG_KEY_STYLE = "key-style"; - private final BaseKeyboard mKeyboard; + private final Keyboard mKeyboard; private final Resources mResources; private int mCurrentX = 0; @@ -128,7 +126,7 @@ public class BaseKeyboardParser { private Row mCurrentRow = null; private final KeyStyles mKeyStyles = new KeyStyles(); - public BaseKeyboardParser(BaseKeyboard keyboard, Resources res) { + public KeyboardParser(Keyboard keyboard, Resources res) { mKeyboard = keyboard; mResources = res; } @@ -160,19 +158,19 @@ public class BaseKeyboardParser { } private void parseKeyboardAttributes(XmlResourceParser parser) { - final BaseKeyboard keyboard = mKeyboard; + final Keyboard keyboard = mKeyboard; final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard); + R.styleable.Keyboard); final int width = keyboard.getKeyboardWidth(); final int height = keyboard.getKeyboardHeight(); keyboard.setKeyWidth(getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyWidth, width, width / 10)); + R.styleable.Keyboard_keyWidth, width, width / 10)); keyboard.setKeyHeight(getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyHeight, height, 50)); + R.styleable.Keyboard_keyHeight, height, 50)); keyboard.setHorizontalGap(getDimensionOrFraction(a, - R.styleable.BaseKeyboard_horizontalGap, width, 0)); + R.styleable.Keyboard_horizontalGap, width, 0)); keyboard.setVerticalGap(getDimensionOrFraction(a, - R.styleable.BaseKeyboard_verticalGap, height, 0)); + R.styleable.Keyboard_verticalGap, height, 0)); a.recycle(); if (DEBUG_TAG) Log.d(TAG, "id=" + keyboard.mId); } @@ -266,7 +264,7 @@ public class BaseKeyboardParser { mKeyStyles); checkEndTag(TAG_KEY, parser); keys.add(key); - if (key.codes[0] == BaseKeyboard.KEYCODE_SHIFT) + if (key.codes[0] == Keyboard.KEYCODE_SHIFT) mKeyboard.getShiftKeys().add(key); endKey(key); } @@ -278,8 +276,8 @@ public class BaseKeyboardParser { checkEndTag(TAG_SPACER, parser); } else { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard); - final int gap = getDimensionOrFraction(a, R.styleable.BaseKeyboard_horizontalGap, + R.styleable.Keyboard); + final int gap = getDimensionOrFraction(a, R.styleable.Keyboard_horizontalGap, mKeyboard.getKeyboardWidth(), 0); a.recycle(); checkEndTag(TAG_SPACER, parser); @@ -303,9 +301,9 @@ public class BaseKeyboardParser { checkEndTag(TAG_INCLUDE, parser); } else { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard_Include); + R.styleable.Keyboard_Include); final int keyboardLayout = a.getResourceId( - R.styleable.BaseKeyboard_Include_keyboardLayout, 0); + R.styleable.Keyboard_Include_keyboardLayout, 0); a.recycle(); checkEndTag(TAG_INCLUDE, parser); @@ -395,25 +393,25 @@ public class BaseKeyboardParser { return true; final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard_Case); + R.styleable.Keyboard_Case); final TypedArray viewAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboardView); + R.styleable.KeyboardView); try { final boolean modeMatched = matchInteger(a, - R.styleable.BaseKeyboard_Case_mode, id.mMode); + R.styleable.Keyboard_Case_mode, id.mMode); final boolean settingsKeyMatched = matchBoolean(a, - R.styleable.BaseKeyboard_Case_hasSettingsKey, id.mHasSettingsKey); + R.styleable.Keyboard_Case_hasSettingsKey, id.mHasSettingsKey); final boolean voiceEnabledMatched = matchBoolean(a, - R.styleable.BaseKeyboard_Case_voiceKeyEnabled, id.mVoiceKeyEnabled); + R.styleable.Keyboard_Case_voiceKeyEnabled, id.mVoiceKeyEnabled); final boolean voiceKeyMatched = matchBoolean(a, - R.styleable.BaseKeyboard_Case_hasVoiceKey, id.mHasVoiceKey); + R.styleable.Keyboard_Case_hasVoiceKey, id.mHasVoiceKey); final boolean colorSchemeMatched = matchInteger(viewAttr, - R.styleable.BaseKeyboardView_colorScheme, id.mColorScheme); + R.styleable.KeyboardView_colorScheme, id.mColorScheme); // As noted at KeyboardSwitcher.KeyboardId class, we are interested only in // enum value masked by IME_MASK_ACTION and IME_FLAG_NO_ENTER_ACTION. So matching // this attribute with id.mImeOptions as integer value is enough for our purpose. final boolean imeOptionsMatched = matchInteger(a, - R.styleable.BaseKeyboard_Case_imeOptions, id.mImeOptions); + R.styleable.Keyboard_Case_imeOptions, id.mImeOptions); final boolean selected = modeMatched && settingsKeyMatched && voiceEnabledMatched && voiceKeyMatched && colorSchemeMatched && imeOptionsMatched; @@ -421,15 +419,15 @@ public class BaseKeyboardParser { Log.d(TAG, String.format( "parseCaseCondition: %s%s%s%s%s%s%s", Boolean.toString(selected).toUpperCase(), - debugInteger(a, R.styleable.BaseKeyboard_Case_mode, "mode"), - debugBoolean(a, R.styleable.BaseKeyboard_Case_hasSettingsKey, + debugInteger(a, R.styleable.Keyboard_Case_mode, "mode"), + debugBoolean(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"), - debugBoolean(a, R.styleable.BaseKeyboard_Case_voiceKeyEnabled, + debugBoolean(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"), - debugBoolean(a, R.styleable.BaseKeyboard_Case_hasVoiceKey, "hasVoiceKey"), - debugInteger(viewAttr, R.styleable.BaseKeyboardView_colorScheme, + debugBoolean(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"), + debugInteger(viewAttr, R.styleable.KeyboardView_colorScheme, "colorScheme"), - debugInteger(a, R.styleable.BaseKeyboard_Case_imeOptions, "imeOptions"))); + debugInteger(a, R.styleable.Keyboard_Case_imeOptions, "imeOptions"))); } return selected; @@ -464,11 +462,11 @@ public class BaseKeyboardParser { private void parseKeyStyle(XmlResourceParser parser, List<Key> keys) throws XmlPullParserException, IOException { TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard_KeyStyle); + R.styleable.Keyboard_KeyStyle); TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard_Key); + R.styleable.Keyboard_Key); try { - if (!a.hasValue(R.styleable.BaseKeyboard_KeyStyle_styleName)) + if (!a.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) throw new ParseException("<" + TAG_KEY_STYLE + "/> needs styleName attribute", parser); if (keys != null) diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java similarity index 87% rename from java/src/com/android/inputmethod/latin/BaseKeyboardView.java rename to java/src/com/android/inputmethod/keyboard/KeyboardView.java index 3193cd46e2225f075442068b2d2a65762945bd35..ae6d097169e2304a3113aaa7ffdd47c569169e01 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboard.Key; +import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; import android.content.Context; import android.content.pm.PackageManager; @@ -49,27 +51,26 @@ import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.WeakHashMap; /** - * A view that renders a virtual {@link LatinKeyboard}. It handles rendering of keys and - * detecting key presses and touch movements. + * A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key + * presses and touch movements. * * TODO: References to LatinKeyboard in this class should be replaced with ones to its base class. * - * @attr ref R.styleable#BaseKeyboardView_keyBackground - * @attr ref R.styleable#BaseKeyboardView_keyPreviewLayout - * @attr ref R.styleable#BaseKeyboardView_keyPreviewOffset - * @attr ref R.styleable#BaseKeyboardView_labelTextSize - * @attr ref R.styleable#BaseKeyboardView_keyTextSize - * @attr ref R.styleable#BaseKeyboardView_keyTextColor - * @attr ref R.styleable#BaseKeyboardView_verticalCorrection - * @attr ref R.styleable#BaseKeyboardView_popupLayout + * @attr ref R.styleable#KeyboardView_keyBackground + * @attr ref R.styleable#KeyboardView_keyPreviewLayout + * @attr ref R.styleable#KeyboardView_keyPreviewOffset + * @attr ref R.styleable#KeyboardView_labelTextSize + * @attr ref R.styleable#KeyboardView_keyTextSize + * @attr ref R.styleable#KeyboardView_keyTextColor + * @attr ref R.styleable#KeyboardView_verticalCorrection + * @attr ref R.styleable#KeyboardView_popupLayout */ -public class BaseKeyboardView extends View implements PointerTracker.UIProxy { - private static final String TAG = "BaseKeyboardView"; +public class KeyboardView extends View implements PointerTracker.UIProxy { + private static final String TAG = "KeyboardView"; private static final boolean DEBUG = false; private static final boolean DEBUG_SHOW_ALIGN = false; private static final boolean DEBUG_KEYBOARD_GRID = false; @@ -79,93 +80,10 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { public static final int NOT_A_TOUCH_COORDINATE = -1; - public interface OnKeyboardActionListener { - - /** - * Called when the user presses a key. This is sent before the - * {@link #onKey} is called. For keys that repeat, this is only - * called once. - * - * @param primaryCode - * the unicode of the key being pressed. If the touch is - * not on a valid key, the value will be zero. - */ - void onPress(int primaryCode); - - /** - * Called when the user releases a key. This is sent after the - * {@link #onKey} is called. For keys that repeat, this is only - * called once. - * - * @param primaryCode - * the code of the key that was released - */ - void onRelease(int primaryCode); - - /** - * Send a key press to the listener. - * - * @param primaryCode - * this is the key that was pressed - * @param keyCodes - * the codes for all the possible alternative keys with - * the primary code being the first. If the primary key - * code is a single character such as an alphabet or - * number or symbol, the alternatives will include other - * characters that may be on the same key or adjacent - * keys. These codes are useful to correct for - * accidental presses of a key adjacent to the intended - * key. - * @param x - * x-coordinate pixel of touched event. If onKey is not called by onTouchEvent, - * the value should be NOT_A_TOUCH_COORDINATE. - * @param y - * y-coordinate pixel of touched event. If onKey is not called by onTouchEvent, - * the value should be NOT_A_TOUCH_COORDINATE. - */ - void onKey(int primaryCode, int[] keyCodes, int x, int y); - - /** - * Sends a sequence of characters to the listener. - * - * @param text - * the sequence of characters to be displayed. - */ - void onText(CharSequence text); - - /** - * Called when user released a finger outside any key. - */ - void onCancel(); - - /** - * Called when the user quickly moves the finger from right to - * left. - */ - void swipeLeft(); - - /** - * Called when the user quickly moves the finger from left to - * right. - */ - void swipeRight(); - - /** - * Called when the user quickly moves the finger from up to down. - */ - void swipeDown(); - - /** - * Called when the user quickly moves the finger from down to up. - */ - void swipeUp(); - } - // Timing constants private final int mKeyRepeatInterval; // Miscellaneous constants - /* package */ static final int NOT_A_KEY = -1; private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable }; private static final int HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL = -1; @@ -187,7 +105,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private int mPopupLayout; // Main keyboard - private BaseKeyboard mKeyboard; + private Keyboard mKeyboard; private Key[] mKeys; // Key preview popup @@ -196,7 +114,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private PopupWindow mPreviewPopup; private int mPreviewTextSizeLarge; private int[] mOffsetInWindow; - private int mOldPreviewKeyIndex = NOT_A_KEY; + private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY; private boolean mShowPreview = true; private boolean mShowTouchPoints = true; private int mPopupPreviewOffsetX; @@ -208,7 +126,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { // Popup mini keyboard private PopupWindow mMiniKeyboardPopup; - private BaseKeyboardView mMiniKeyboard; + private KeyboardView mMiniKeyboard; private View mMiniKeyboardParent; private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); private int mMiniKeyboardOriginX; @@ -218,13 +136,13 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private final float mMiniKeyboardSlideAllowance; private int mMiniKeyboardTrackerId; - /** Listener for {@link OnKeyboardActionListener}. */ - private OnKeyboardActionListener mKeyboardActionListener; + /** Listener for {@link KeyboardActionListener}. */ + private KeyboardActionListener mKeyboardActionListener; private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>(); // TODO: Let the PointerTracker class manage this pointer queue - private final PointerQueue mPointerQueue = new PointerQueue(); + private final PointerTrackerQueue mPointerQueue = new PointerTrackerQueue(); private final boolean mHasDistinctMultitouch; private int mOldPointerCount = 1; @@ -370,63 +288,15 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { } }; - static class PointerQueue { - private LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>(); - - public void add(PointerTracker tracker) { - mQueue.add(tracker); - } - - public int lastIndexOf(PointerTracker tracker) { - LinkedList<PointerTracker> queue = mQueue; - for (int index = queue.size() - 1; index >= 0; index--) { - PointerTracker t = queue.get(index); - if (t == tracker) - return index; - } - return -1; - } - - public void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) { - LinkedList<PointerTracker> queue = mQueue; - int oldestPos = 0; - for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) { - if (t.isModifier()) { - oldestPos++; - } else { - t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); - queue.remove(oldestPos); - } - } - } - - public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { - for (PointerTracker t : mQueue) { - if (t == tracker) - continue; - t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); - t.setAlreadyProcessed(); - } - mQueue.clear(); - if (tracker != null) - mQueue.add(tracker); - } - - public void remove(PointerTracker tracker) { - mQueue.remove(tracker); - } - } - - public BaseKeyboardView(Context context, AttributeSet attrs) { + public KeyboardView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.keyboardViewStyle); } - public BaseKeyboardView(Context context, AttributeSet attrs, int defStyle) { + public KeyboardView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.BaseKeyboardView, defStyle, R.style.BaseKeyboardView); + attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView); LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); int previewLayout = 0; @@ -438,53 +308,53 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { int attr = a.getIndex(i); switch (attr) { - case R.styleable.BaseKeyboardView_keyBackground: + case R.styleable.KeyboardView_keyBackground: mKeyBackground = a.getDrawable(attr); break; - case R.styleable.BaseKeyboardView_keyHysteresisDistance: + case R.styleable.KeyboardView_keyHysteresisDistance: mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0); break; - case R.styleable.BaseKeyboardView_verticalCorrection: + case R.styleable.KeyboardView_verticalCorrection: mVerticalCorrection = a.getDimensionPixelOffset(attr, 0); break; - case R.styleable.BaseKeyboardView_keyPreviewLayout: + case R.styleable.KeyboardView_keyPreviewLayout: previewLayout = a.getResourceId(attr, 0); break; - case R.styleable.BaseKeyboardView_keyPreviewOffset: + case R.styleable.KeyboardView_keyPreviewOffset: mPreviewOffset = a.getDimensionPixelOffset(attr, 0); break; - case R.styleable.BaseKeyboardView_keyPreviewHeight: + case R.styleable.KeyboardView_keyPreviewHeight: mPreviewHeight = a.getDimensionPixelSize(attr, 80); break; - case R.styleable.BaseKeyboardView_keyLetterSize: + case R.styleable.KeyboardView_keyLetterSize: mKeyLetterSize = a.getDimensionPixelSize(attr, 18); break; - case R.styleable.BaseKeyboardView_keyTextColor: + case R.styleable.KeyboardView_keyTextColor: mKeyTextColor = a.getColor(attr, 0xFF000000); break; - case R.styleable.BaseKeyboardView_keyTextColorDisabled: + case R.styleable.KeyboardView_keyTextColorDisabled: mKeyTextColorDisabled = a.getColor(attr, 0xFF000000); break; - case R.styleable.BaseKeyboardView_labelTextSize: + case R.styleable.KeyboardView_labelTextSize: mLabelTextSize = a.getDimensionPixelSize(attr, 14); break; - case R.styleable.BaseKeyboardView_popupLayout: + case R.styleable.KeyboardView_popupLayout: mPopupLayout = a.getResourceId(attr, 0); break; - case R.styleable.BaseKeyboardView_shadowColor: + case R.styleable.KeyboardView_shadowColor: mShadowColor = a.getColor(attr, 0); break; - case R.styleable.BaseKeyboardView_shadowRadius: + case R.styleable.KeyboardView_shadowRadius: mShadowRadius = a.getFloat(attr, 0f); break; // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount) - case R.styleable.BaseKeyboardView_backgroundDimAmount: + case R.styleable.KeyboardView_backgroundDimAmount: mBackgroundDimAmount = a.getFloat(attr, 0.5f); break; - case R.styleable.BaseKeyboardView_keyLetterStyle: + case R.styleable.KeyboardView_keyLetterStyle: mKeyLetterStyle = Typeface.defaultFromStyle(a.getInt(attr, Typeface.NORMAL)); break; - case R.styleable.BaseKeyboardView_colorScheme: + case R.styleable.KeyboardView_colorScheme: mColorScheme = a.getInt(attr, COLOR_SCHEME_WHITE); break; } @@ -575,7 +445,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval); } - public void setOnKeyboardActionListener(OnKeyboardActionListener listener) { + public void setOnKeyboardActionListener(KeyboardActionListener listener) { mKeyboardActionListener = listener; for (PointerTracker tracker : mPointerTrackers) { tracker.setOnKeyboardActionListener(listener); @@ -583,21 +453,21 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { } /** - * Returns the {@link OnKeyboardActionListener} object. + * Returns the {@link KeyboardActionListener} object. * @return the listener attached to this keyboard */ - protected OnKeyboardActionListener getOnKeyboardActionListener() { + protected KeyboardActionListener getOnKeyboardActionListener() { return mKeyboardActionListener; } /** * Attaches a keyboard to this view. The keyboard can be switched at any time and the * view will re-layout itself to accommodate the keyboard. - * @see BaseKeyboard + * @see Keyboard * @see #getKeyboard() * @param keyboard the keyboard to display in this view */ - protected void setKeyboard(BaseKeyboard keyboard) { + public void setKeyboard(Keyboard keyboard) { if (mKeyboard != null) { dismissKeyPreview(); } @@ -622,9 +492,9 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { /** * Returns the current keyboard being displayed by this view. * @return the currently attached keyboard - * @see #setKeyboard(BaseKeyboard) + * @see #setKeyboard(Keyboard) */ - protected BaseKeyboard getKeyboard() { + public Keyboard getKeyboard() { return mKeyboard; } @@ -632,6 +502,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { * Return whether the device has distinct multi-touch panel. * @return true if the device has distinct multi-touch panel. */ + @Override public boolean hasDistinctMultitouch() { return mHasDistinctMultitouch; } @@ -670,7 +541,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { } /** - * When enabled, calls to {@link OnKeyboardActionListener#onKey} will include key + * When enabled, calls to {@link KeyboardActionListener#onKey} will include key * codes for adjacent keys. When disabled, only the primary key code will be * reported. * @param enabled whether or not the proximity correction is enabled @@ -715,7 +586,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { * @param keyboard * @param keys */ - private void computeProximityThreshold(BaseKeyboard keyboard, Key[] keys) { + private void computeProximityThreshold(Keyboard keyboard, Key[] keys) { if (keyboard == null || keys == null || keys.length == 0) return; final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>(); int maxCount = 0; @@ -750,6 +621,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { canvas.drawBitmap(mBuffer, 0, 0, null); } + @SuppressWarnings("unused") private void onBufferDraw() { if (mBuffer == null || mKeyboardChanged) { if (mBuffer == null || mKeyboardChanged && @@ -1020,22 +892,24 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private void dismissKeyPreview() { for (PointerTracker tracker : mPointerTrackers) tracker.releaseKey(); - showPreview(NOT_A_KEY, null); + showPreview(KeyDetector.NOT_A_KEY, null); } + @Override public void showPreview(int keyIndex, PointerTracker tracker) { int oldKeyIndex = mOldPreviewKeyIndex; mOldPreviewKeyIndex = keyIndex; // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show // the space key preview and 3) pointer moves off the space key to other letter key, we // should hide the preview of the previous key. + @SuppressWarnings("unused") final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null) || (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER && SubtypeSwitcher.getInstance().needsToDisplayLanguage() && (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex))); // If key changed and preview is on or the key is space (language switch is enabled) if (oldKeyIndex != keyIndex && (mShowPreview || (hidePreviewOrShowSpaceKeyPreview))) { - if (keyIndex == NOT_A_KEY) { + if (keyIndex == KeyDetector.NOT_A_KEY) { mHandler.cancelPopupPreview(); mHandler.dismissPreview(mDelayAfterPreview); } else if (tracker != null) { @@ -1145,9 +1019,10 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { * Invalidates a key so that it will be redrawn on the next repaint. Use this method if only * one key is changing it's content. Any changes that affect the position or size of the key * may not be honored. - * @param key key in the attached {@link BaseKeyboard}. + * @param key key in the attached {@link Keyboard}. * @see #invalidateAllKeys */ + @Override public void invalidateKey(Key key) { if (key == null) return; @@ -1183,7 +1058,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private void onLongPressShiftKey(PointerTracker tracker) { tracker.setAlreadyProcessed(); mPointerQueue.remove(tracker); - mKeyboardActionListener.onKey(LatinKeyboardView.KEYCODE_CAPSLOCK, null, 0, 0); + mKeyboardActionListener.onKey(LatinKeyboard.KEYCODE_CAPSLOCK, null, 0, 0); } private View inflateMiniKeyboardContainer(Key popupKey) { @@ -1194,34 +1069,43 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { if (container == null) throw new NullPointerException(); - BaseKeyboardView miniKeyboard = - (BaseKeyboardView)container.findViewById(R.id.BaseKeyboardView); - miniKeyboard.setOnKeyboardActionListener(new OnKeyboardActionListener() { + KeyboardView miniKeyboard = + (KeyboardView)container.findViewById(R.id.KeyboardView); + miniKeyboard.setOnKeyboardActionListener(new KeyboardActionListener() { + @Override public void onKey(int primaryCode, int[] keyCodes, int x, int y) { mKeyboardActionListener.onKey(primaryCode, keyCodes, x, y); dismissPopupKeyboard(); } + @Override public void onText(CharSequence text) { mKeyboardActionListener.onText(text); dismissPopupKeyboard(); } + @Override public void onCancel() { dismissPopupKeyboard(); } + @Override public void swipeLeft() { } + @Override public void swipeRight() { } + @Override public void swipeUp() { } + @Override public void swipeDown() { } + @Override public void onPress(int primaryCode) { mKeyboardActionListener.onPress(primaryCode); } + @Override public void onRelease(int primaryCode) { mKeyboardActionListener.onRelease(primaryCode); } @@ -1231,12 +1115,12 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { // Remove gesture detector on mini-keyboard miniKeyboard.mGestureDetector = null; - BaseKeyboard keyboard; + Keyboard keyboard; if (popupKey.popupCharacters != null) { - keyboard = new BaseKeyboard(getContext(), popupKeyboardId, popupKey.popupCharacters, + keyboard = new Keyboard(getContext(), popupKeyboardId, popupKey.popupCharacters, -1, getPaddingLeft() + getPaddingRight()); } else { - keyboard = new BaseKeyboard(getContext(), popupKeyboardId); + keyboard = new Keyboard(getContext(), popupKeyboardId); } miniKeyboard.setKeyboard(keyboard); miniKeyboard.setPopupParent(this); @@ -1256,8 +1140,8 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { // and bottom edge flags on. // When you want to use one row mini-keyboard from xml file, make sure that the row has // both top and bottom edge flags set. - return (edgeFlags & BaseKeyboard.EDGE_TOP) != 0 - && (edgeFlags & BaseKeyboard.EDGE_BOTTOM) != 0; + return (edgeFlags & Keyboard.EDGE_TOP) != 0 + && (edgeFlags & Keyboard.EDGE_BOTTOM) != 0; } /** @@ -1279,7 +1163,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { container = inflateMiniKeyboardContainer(popupKey); mMiniKeyboardCache.put(popupKey, container); } - mMiniKeyboard = (BaseKeyboardView)container.findViewById(R.id.BaseKeyboardView); + mMiniKeyboard = (KeyboardView)container.findViewById(R.id.KeyboardView); if (mWindowOffset == null) { mWindowOffset = new int[2]; getLocationInWindow(mWindowOffset); @@ -1325,7 +1209,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1]; mMiniKeyboard.setPopupOffset(adjustedX, y); // TODO: change the below line to use getLatinKeyboard() instead of getKeyboard() - BaseKeyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard(); + Keyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard(); if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null ? false : mKeyboard.isShiftedOrShiftLocked())) { mMiniKeyboard.invalidateAllKeys(); @@ -1376,7 +1260,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private PointerTracker getPointerTracker(final int id) { final ArrayList<PointerTracker> pointers = mPointerTrackers; final Key[] keys = mKeys; - final OnKeyboardActionListener listener = mKeyboardActionListener; + final KeyboardActionListener listener = mKeyboardActionListener; // Create pointer trackers until we can get 'id+1'-th tracker, if needed. for (int i = pointers.size(); i <= id; i++) { diff --git a/java/src/com/android/inputmethod/keyboard/LatinKey.java b/java/src/com/android/inputmethod/keyboard/LatinKey.java new file mode 100644 index 0000000000000000000000000000000000000000..4eaf4c8f6f9c8f8a4d3e10049cafea859331f050 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/LatinKey.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import android.content.res.Resources; +import android.content.res.XmlResourceParser; + +public class LatinKey extends Key { + + // functional normal state (with properties) + private final int[] KEY_STATE_FUNCTIONAL_NORMAL = { + android.R.attr.state_single + }; + + // functional pressed state (with properties) + private final int[] KEY_STATE_FUNCTIONAL_PRESSED = { + android.R.attr.state_single, + android.R.attr.state_pressed + }; + + private boolean mShiftLockEnabled; + + public LatinKey(Resources res, Row parent, int x, int y, + XmlResourceParser parser, KeyStyles keyStyles) { + super(res, parent, x, y, parser, keyStyles); + if (popupCharacters != null && popupCharacters.length() == 0) { + // If there is a keyboard with no keys specified in popupCharacters + popupResId = 0; + } + } + + void enableShiftLock() { + mShiftLockEnabled = true; + } + + // sticky is used for shift key. If a key is not sticky and is modifier, + // the key will be treated as functional. + private boolean isFunctionalKey() { + return !sticky && modifier; + } + + @Override + public void onReleased(boolean inside) { + if (!mShiftLockEnabled) { + super.onReleased(inside); + } else { + pressed = !pressed; + } + } + + /** + * Overriding this method so that we can reduce the target area for certain keys. + */ + @Override + public boolean isInside(int x, int y) { + boolean result = (keyboard instanceof LatinKeyboard) + && ((LatinKeyboard)keyboard).isInside(this, x, y); + return result; + } + + boolean isInsideSuper(int x, int y) { + return super.isInside(x, y); + } + + @Override + public int[] getCurrentDrawableState() { + if (isFunctionalKey()) { + if (pressed) { + return KEY_STATE_FUNCTIONAL_PRESSED; + } else { + return KEY_STATE_FUNCTIONAL_NORMAL; + } + } + return super.getCurrentDrawableState(); + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java similarity index 72% rename from java/src/com/android/inputmethod/latin/LatinKeyboard.java rename to java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index cae0b10b3e508491bf98be25057ff31d81558a81..29f749a46d2da17ec291af6b43be583465714b30 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2008 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 @@ -14,7 +14,11 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; + +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; import android.content.Context; import android.content.res.Resources; @@ -22,28 +26,33 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Paint.Align; -import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.text.TextPaint; import android.util.Log; -import android.view.ViewConfiguration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -public class LatinKeyboard extends BaseKeyboard { +public class LatinKeyboard extends Keyboard { private static final boolean DEBUG_PREFERRED_LETTER = false; private static final String TAG = "LatinKeyboard"; - private static final int OPACITY_FULLY_OPAQUE = 255; + + public static final int KEYCODE_OPTIONS = -100; + public static final int KEYCODE_OPTIONS_LONGPRESS = -101; + // TODO: remove this once LatinIME stops referring to this. + public static final int KEYCODE_VOICE = -102; + public static final int KEYCODE_NEXT_LANGUAGE = -104; + public static final int KEYCODE_PREV_LANGUAGE = -105; + public static final int KEYCODE_CAPSLOCK = -106; + + static final int OPACITY_FULLY_OPAQUE = 255; private static final int SPACE_LED_LENGTH_PERCENT = 80; private Drawable mShiftLockPreviewIcon; @@ -76,22 +85,22 @@ public class LatinKeyboard extends BaseKeyboard { // Minimum width of space key preview (proportional to keyboard width) private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; // Height in space key the language name will be drawn. (proportional to space key height) - private static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; + public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; // If the full language name needs to be smaller than this value to be drawn on space key, // its short language name will be used instead. private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; private static int sSpacebarVerticalCorrection; - public LatinKeyboard(Context context, KeyboardSwitcher.KeyboardId id) { + public LatinKeyboard(Context context, KeyboardId id) { super(context, id); final Resources res = context.getResources(); mContext = context; mRes = res; - if (id.mColorScheme == BaseKeyboardView.COLOR_SCHEME_BLACK) { + if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) { mSpaceBarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_black); - } else { // default color scheme is BaseKeyboardView.COLOR_SCHEME_WHITE + } else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE mSpaceBarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_white); } @@ -181,7 +190,7 @@ public class LatinKeyboard extends BaseKeyboard { return isAlphaKeyboard() && mShiftState.isManualTemporaryUpperCase(); } - /* package */ LatinKeyboardShiftState getKeyboardShiftState() { + public LatinKeyboardShiftState getKeyboardShiftState() { return mShiftState; } @@ -190,11 +199,11 @@ public class LatinKeyboard extends BaseKeyboard { } public boolean isPhoneKeyboard() { - return mId.mMode == KeyboardSwitcher.MODE_PHONE; + return mId.mMode == KeyboardId.MODE_PHONE; } public boolean isNumberKeyboard() { - return mId.mMode == KeyboardSwitcher.MODE_NUMBER; + return mId.mMode == KeyboardId.MODE_NUMBER; } /** @@ -272,6 +281,7 @@ public class LatinKeyboard extends BaseKeyboard { return language; } + @SuppressWarnings("unused") private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion) { final int width = mSpaceKey.width; final int height = mSpaceIcon.getIntrinsicHeight(); @@ -334,7 +344,8 @@ public class LatinKeyboard extends BaseKeyboard { final int width = Math.max(mSpaceKey.width, (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)); final int height = mSpacePreviewIcon.getIntrinsicHeight(); - mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, width, height); + mSlidingLocaleIcon = + new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height); mSlidingLocaleIcon.setBounds(0, 0, width, height); mSpaceKey.iconPreview = mSlidingLocaleIcon; } @@ -380,6 +391,7 @@ public class LatinKeyboard extends BaseKeyboard { * Does the magic of locking the touch gesture into the spacebar when * switching input languages. */ + @SuppressWarnings("unused") public boolean isInside(LatinKey key, int x, int y) { final int code = key.codes[0]; if (code == KEYCODE_SHIFT || code == KEYCODE_DELETE) { @@ -528,193 +540,4 @@ public class LatinKeyboard extends BaseKeyboard { int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue); return textSize; } - - public static class LatinKey extends BaseKeyboard.Key { - - // functional normal state (with properties) - private final int[] KEY_STATE_FUNCTIONAL_NORMAL = { - android.R.attr.state_single - }; - - // functional pressed state (with properties) - private final int[] KEY_STATE_FUNCTIONAL_PRESSED = { - android.R.attr.state_single, - android.R.attr.state_pressed - }; - - private boolean mShiftLockEnabled; - - public LatinKey(Resources res, BaseKeyboard.Row parent, int x, int y, - XmlResourceParser parser, KeyStyles keyStyles) { - super(res, parent, x, y, parser, keyStyles); - if (popupCharacters != null && popupCharacters.length() == 0) { - // If there is a keyboard with no keys specified in popupCharacters - popupResId = 0; - } - } - - private void enableShiftLock() { - mShiftLockEnabled = true; - } - - // sticky is used for shift key. If a key is not sticky and is modifier, - // the key will be treated as functional. - private boolean isFunctionalKey() { - return !sticky && modifier; - } - - @Override - public void onReleased(boolean inside) { - if (!mShiftLockEnabled) { - super.onReleased(inside); - } else { - pressed = !pressed; - } - } - - /** - * Overriding this method so that we can reduce the target area for certain keys. - */ - @Override - public boolean isInside(int x, int y) { - boolean result = (keyboard instanceof LatinKeyboard) - && ((LatinKeyboard)keyboard).isInside(this, x, y); - return result; - } - - private boolean isInsideSuper(int x, int y) { - return super.isInside(x, y); - } - - @Override - public int[] getCurrentDrawableState() { - if (isFunctionalKey()) { - if (pressed) { - return KEY_STATE_FUNCTIONAL_PRESSED; - } else { - return KEY_STATE_FUNCTIONAL_NORMAL; - } - } - return super.getCurrentDrawableState(); - } - } - - /** - * Animation to be displayed on the spacebar preview popup when switching - * languages by swiping the spacebar. It draws the current, previous and - * next languages and moves them by the delta of touch movement on the spacebar. - */ - private class SlidingLocaleDrawable extends Drawable { - - private final int mWidth; - private final int mHeight; - private final Drawable mBackground; - private final TextPaint mTextPaint; - private final int mMiddleX; - private final Drawable mLeftDrawable; - private final Drawable mRightDrawable; - private final int mThreshold; - private int mDiff; - private boolean mHitThreshold; - private String mCurrentLanguage; - private String mNextLanguage; - private String mPrevLanguage; - - public SlidingLocaleDrawable(Drawable background, int width, int height) { - mBackground = background; - setDefaultBounds(mBackground); - mWidth = width; - mHeight = height; - final TextPaint textPaint = new TextPaint(); - textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18)); - textPaint.setColor(R.color.latinkeyboard_transparent); - textPaint.setTextAlign(Align.CENTER); - textPaint.setAlpha(OPACITY_FULLY_OPAQUE); - textPaint.setAntiAlias(true); - mTextPaint = textPaint; - mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; - final Resources res = mRes; - mLeftDrawable = res.getDrawable( - R.drawable.sym_keyboard_feedback_language_arrows_left); - mRightDrawable = res.getDrawable( - R.drawable.sym_keyboard_feedback_language_arrows_right); - mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop(); - } - - private void setDiff(int diff) { - if (diff == Integer.MAX_VALUE) { - mHitThreshold = false; - mCurrentLanguage = null; - return; - } - mDiff = diff; - if (mDiff > mWidth) mDiff = mWidth; - if (mDiff < -mWidth) mDiff = -mWidth; - if (Math.abs(mDiff) > mThreshold) mHitThreshold = true; - invalidateSelf(); - } - - - @Override - public void draw(Canvas canvas) { - canvas.save(); - if (mHitThreshold) { - Paint paint = mTextPaint; - final int width = mWidth; - final int height = mHeight; - final int diff = mDiff; - final Drawable lArrow = mLeftDrawable; - final Drawable rArrow = mRightDrawable; - canvas.clipRect(0, 0, width, height); - if (mCurrentLanguage == null) { - SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance(); - mCurrentLanguage = subtypeSwitcher.getInputLanguageName(); - mNextLanguage = subtypeSwitcher.getNextInputLanguageName(); - mPrevLanguage = subtypeSwitcher.getPreviousInputLanguageName(); - } - // Draw language text with shadow - final float baseline = mHeight * SPACEBAR_LANGUAGE_BASELINE - paint.descent(); - paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text)); - canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint); - canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint); - canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint); - - setDefaultBounds(lArrow); - rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width, - rArrow.getIntrinsicHeight()); - lArrow.draw(canvas); - rArrow.draw(canvas); - } - if (mBackground != null) { - canvas.translate(mMiddleX, 0); - mBackground.draw(canvas); - } - canvas.restore(); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int alpha) { - // Ignore - } - - @Override - public void setColorFilter(ColorFilter cf) { - // Ignore - } - - @Override - public int getIntrinsicWidth() { - return mWidth; - } - - @Override - public int getIntrinsicHeight() { - return mHeight; - } - } } diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java similarity index 80% rename from java/src/com/android/inputmethod/latin/LatinKeyboardShiftState.java rename to java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java index e916306c84316d30c1363619d8b9d9cb897cefec..6d78428570bb04fa3a8b62c1adcc9918877ac8e4 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardShiftState.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardShiftState.java @@ -1,4 +1,22 @@ -package com.android.inputmethod.latin; +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.latin.KeyboardSwitcher; import android.util.Log; @@ -86,4 +104,4 @@ public class LatinKeyboardShiftState { default: return "UKNOWN"; } } -} \ No newline at end of file +} diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java similarity index 93% rename from java/src/com/android/inputmethod/latin/LatinKeyboardView.java rename to java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index ac68e3c398fa6beb4367815296b23a0922012182..55427d23f0f9e87e0f3cd849a8a51fca953c9561 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -1,12 +1,12 @@ /* * Copyright (C) 2008 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 @@ -14,9 +14,9 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboard.Key; +import com.android.inputmethod.latin.LatinIMEUtil; import com.android.inputmethod.voice.VoiceIMEConnector; import android.content.Context; @@ -31,15 +31,7 @@ import android.view.MotionEvent; import java.util.List; -public class LatinKeyboardView extends BaseKeyboardView { - - public static final int KEYCODE_OPTIONS = -100; - public static final int KEYCODE_OPTIONS_LONGPRESS = -101; - // TODO: remove this once LatinIME stops referring to this. - public static final int KEYCODE_VOICE = -102; - public static final int KEYCODE_NEXT_LANGUAGE = -104; - public static final int KEYCODE_PREV_LANGUAGE = -105; - public static final int KEYCODE_CAPSLOCK = -106; +public class LatinKeyboardView extends KeyboardView { /** Whether we've started dropping move events because we found a big jump */ private boolean mDroppingEvents; @@ -84,7 +76,7 @@ public class LatinKeyboardView extends BaseKeyboardView { } public LatinKeyboard getLatinKeyboard() { - BaseKeyboard keyboard = getKeyboard(); + Keyboard keyboard = getKeyboard(); if (keyboard instanceof LatinKeyboard) { return (LatinKeyboard)keyboard; } else { @@ -95,8 +87,8 @@ public class LatinKeyboardView extends BaseKeyboardView { @Override protected boolean onLongPress(Key key) { int primaryCode = key.codes[0]; - if (primaryCode == KEYCODE_OPTIONS) { - return invokeOnKey(KEYCODE_OPTIONS_LONGPRESS); + if (primaryCode == LatinKeyboard.KEYCODE_OPTIONS) { + return invokeOnKey(LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS); } else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) { // Long pressing on 0 in phone number keypad gives you a '+'. return invokeOnKey('+'); @@ -107,8 +99,8 @@ public class LatinKeyboardView extends BaseKeyboardView { private boolean invokeOnKey(int primaryCode) { getOnKeyboardActionListener().onKey(primaryCode, null, - BaseKeyboardView.NOT_A_TOUCH_COORDINATE, - BaseKeyboardView.NOT_A_TOUCH_COORDINATE); + KeyboardView.NOT_A_TOUCH_COORDINATE, + KeyboardView.NOT_A_TOUCH_COORDINATE); return true; } @@ -223,7 +215,8 @@ public class LatinKeyboardView extends BaseKeyboardView { int languageDirection = keyboard.getLanguageChangeDirection(); if (languageDirection != 0) { getOnKeyboardActionListener().onKey( - languageDirection == 1 ? KEYCODE_NEXT_LANGUAGE : KEYCODE_PREV_LANGUAGE, + languageDirection == 1 + ? LatinKeyboard.KEYCODE_NEXT_LANGUAGE : LatinKeyboard.KEYCODE_PREV_LANGUAGE, null, mLastX, mLastY); me.setAction(MotionEvent.ACTION_CANCEL); keyboard.keyReleased(); @@ -236,8 +229,8 @@ public class LatinKeyboardView extends BaseKeyboardView { /**************************** INSTRUMENTATION *******************************/ - static final boolean DEBUG_AUTO_PLAY = false; - static final boolean DEBUG_LINE = false; + public static final boolean DEBUG_AUTO_PLAY = false; + public static final boolean DEBUG_LINE = false; private static final int MSG_TOUCH_DOWN = 1; private static final int MSG_TOUCH_UP = 2; diff --git a/java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java similarity index 86% rename from java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java rename to java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java index 3cc43b99cda6602f918d58678804209f04dcf2d6..53879cde11ebc0a14e5e3cbfd1c3862f271dfd90 100644 --- a/java/src/com/android/inputmethod/latin/MiniKeyboardKeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java @@ -14,11 +14,9 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboard.Key; - -class MiniKeyboardKeyDetector extends KeyDetector { +public class MiniKeyboardKeyDetector extends KeyDetector { private static final int MAX_NEARBY_KEYS = 1; private final int mSlideAllowanceSquare; @@ -42,7 +40,7 @@ class MiniKeyboardKeyDetector extends KeyDetector { final int touchX = getTouchX(x); final int touchY = getTouchY(y); - int closestKeyIndex = BaseKeyboardView.NOT_A_KEY; + int closestKeyIndex = NOT_A_KEY; int closestKeyDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare; final int keyCount = keys.length; for (int index = 0; index < keyCount; index++) { @@ -53,7 +51,7 @@ class MiniKeyboardKeyDetector extends KeyDetector { } } - if (allKeys != null && closestKeyIndex != BaseKeyboardView.NOT_A_KEY) + if (allKeys != null && closestKeyIndex != NOT_A_KEY) allKeys[0] = keys[closestKeyIndex].codes[0]; return closestKeyIndex; } diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java similarity index 94% rename from java/src/com/android/inputmethod/latin/PointerTracker.java rename to java/src/com/android/inputmethod/keyboard/PointerTracker.java index 327fef107879b2f8815ce8b5094de990261f36de..aa0f9bd3758da44aafdd35fe625cafa2c3e975f9 100644 --- a/java/src/com/android/inputmethod/latin/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -14,11 +14,11 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; -import com.android.inputmethod.latin.BaseKeyboard.Key; -import com.android.inputmethod.latin.BaseKeyboardView.OnKeyboardActionListener; -import com.android.inputmethod.latin.BaseKeyboardView.UIHandler; +import com.android.inputmethod.keyboard.KeyboardView.UIHandler; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.R; import android.content.res.Resources; import android.util.Log; @@ -44,16 +44,16 @@ public class PointerTracker { private final int mMultiTapKeyTimeout; // Miscellaneous constants - private static final int NOT_A_KEY = BaseKeyboardView.NOT_A_KEY; - private static final int[] KEY_DELETE = { BaseKeyboard.KEYCODE_DELETE }; + private static final int NOT_A_KEY = KeyDetector.NOT_A_KEY; + private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE }; private final UIProxy mProxy; private final UIHandler mHandler; private final KeyDetector mKeyDetector; - private OnKeyboardActionListener mListener; + private KeyboardActionListener mListener; private final boolean mHasDistinctMultitouch; - private BaseKeyboard mKeyboard; + private Keyboard mKeyboard; private Key[] mKeys; private int mKeyHysteresisDistanceSquared = -1; @@ -181,11 +181,11 @@ public class PointerTracker { resetMultiTap(); } - public void setOnKeyboardActionListener(OnKeyboardActionListener listener) { + public void setOnKeyboardActionListener(KeyboardActionListener listener) { mListener = listener; } - public void setKeyboard(BaseKeyboard keyboard, Key[] keys, float keyHysteresisDistance) { + public void setKeyboard(Keyboard keyboard, Key[] keys, float keyHysteresisDistance) { if (keyboard == null || keys == null || keyHysteresisDistance < 0) throw new IllegalArgumentException(); mKeyboard = keyboard; @@ -208,8 +208,8 @@ public class PointerTracker { if (key == null) return false; int primaryCode = key.codes[0]; - return primaryCode == BaseKeyboard.KEYCODE_SHIFT - || primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE; + return primaryCode == Keyboard.KEYCODE_SHIFT + || primaryCode == Keyboard.KEYCODE_MODE_CHANGE; } public boolean isModifier() { @@ -420,7 +420,7 @@ public class PointerTracker { private void startLongPressTimer(int keyIndex) { Key key = getKey(keyIndex); - if (key.codes[0] == BaseKeyboard.KEYCODE_SHIFT) { + if (key.codes[0] == Keyboard.KEYCODE_SHIFT) { mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this); } else { mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); @@ -433,7 +433,7 @@ public class PointerTracker { } private void detectAndSendKey(int index, int x, int y, long eventTime) { - final OnKeyboardActionListener listener = mListener; + final KeyboardActionListener listener = mListener; final Key key = getKey(index); if (key == null) { @@ -453,7 +453,7 @@ public class PointerTracker { // Multi-tap if (mInMultiTap) { if (mTapCount != -1) { - mListener.onKey(BaseKeyboard.KEYCODE_DELETE, KEY_DELETE, x, y); + mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y); } else { mTapCount = 0; } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java new file mode 100644 index 0000000000000000000000000000000000000000..a3c0808282082495b6af37fe012a5e8e41a89ba4 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import java.util.LinkedList; + +public class PointerTrackerQueue { + private LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>(); + + public void add(PointerTracker tracker) { + mQueue.add(tracker); + } + + public int lastIndexOf(PointerTracker tracker) { + LinkedList<PointerTracker> queue = mQueue; + for (int index = queue.size() - 1; index >= 0; index--) { + PointerTracker t = queue.get(index); + if (t == tracker) + return index; + } + return -1; + } + + public void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) { + LinkedList<PointerTracker> queue = mQueue; + int oldestPos = 0; + for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) { + if (t.isModifier()) { + oldestPos++; + } else { + t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); + t.setAlreadyProcessed(); + queue.remove(oldestPos); + } + } + } + + public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { + for (PointerTracker t : mQueue) { + if (t == tracker) + continue; + t.onUpEvent(t.getLastX(), t.getLastY(), eventTime); + t.setAlreadyProcessed(); + } + mQueue.clear(); + if (tracker != null) + mQueue.add(tracker); + } + + public void remove(PointerTracker tracker) { + mQueue.remove(tracker); + } +} diff --git a/java/src/com/android/inputmethod/latin/ProximityKeyDetector.java b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java similarity index 88% rename from java/src/com/android/inputmethod/latin/ProximityKeyDetector.java rename to java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java index 35bdc672843326fcdb705404ca3ed504366803de..047173445bc8d56cf36c48a0c58fd75a1ab5a1bb 100644 --- a/java/src/com/android/inputmethod/latin/ProximityKeyDetector.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityKeyDetector.java @@ -14,13 +14,11 @@ * the License. */ -package com.android.inputmethod.latin; - -import com.android.inputmethod.latin.BaseKeyboard.Key; +package com.android.inputmethod.keyboard; import java.util.Arrays; -class ProximityKeyDetector extends KeyDetector { +public class ProximityKeyDetector extends KeyDetector { private static final int MAX_NEARBY_KEYS = 12; // working area @@ -37,8 +35,8 @@ class ProximityKeyDetector extends KeyDetector { final int touchX = getTouchX(x); final int touchY = getTouchY(y); - int primaryIndex = BaseKeyboardView.NOT_A_KEY; - int closestKeyIndex = BaseKeyboardView.NOT_A_KEY; + int primaryIndex = NOT_A_KEY; + int closestKeyIndex = NOT_A_KEY; int closestKeyDist = mProximityThresholdSquare + 1; final int[] distances = mDistances; Arrays.fill(distances, Integer.MAX_VALUE); @@ -72,6 +70,6 @@ class ProximityKeyDetector extends KeyDetector { } } - return primaryIndex == BaseKeyboardView.NOT_A_KEY ? closestKeyIndex : primaryIndex; + return primaryIndex == NOT_A_KEY ? closestKeyIndex : primaryIndex; } } diff --git a/java/src/com/android/inputmethod/keyboard/Row.java b/java/src/com/android/inputmethod/keyboard/Row.java new file mode 100644 index 0000000000000000000000000000000000000000..cb778f317d39242aa0cf46cb5a01039ecc143a1a --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/Row.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.latin.R; + +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.util.Xml; + +/** + * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. + * Some of the key size defaults can be overridden per row from what the {@link Keyboard} + * defines. + */ +public class Row { + /** Default width of a key in this row. */ + public int defaultWidth; + /** Default height of a key in this row. */ + public int defaultHeight; + /** Default horizontal gap between keys in this row. */ + public int defaultHorizontalGap; + /** Vertical gap following this row. */ + public int verticalGap; + /** + * Edge flags for this row of keys. Possible values that can be assigned are + * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM} + */ + public int rowEdgeFlags; + + final Keyboard parent; + + Row(Keyboard parent) { + this.parent = parent; + } + + public Row(Resources res, Keyboard parent, XmlResourceParser parser) { + this.parent = parent; + TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.Keyboard); + defaultWidth = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_keyWidth, + parent.mDisplayWidth, parent.mDefaultWidth); + defaultHeight = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_keyHeight, + parent.mDisplayHeight, parent.mDefaultHeight); + defaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_horizontalGap, + parent.mDisplayWidth, parent.mDefaultHorizontalGap); + verticalGap = KeyboardParser.getDimensionOrFraction(a, + R.styleable.Keyboard_verticalGap, + parent.mDisplayHeight, parent.mDefaultVerticalGap); + a.recycle(); + a = res.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.Keyboard_Row); + rowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0); + } +} diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java new file mode 100644 index 0000000000000000000000000000000000000000..689791cff79601475d5f4272c9bba68924dbf34f --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * 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.inputmethod.keyboard; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Paint.Align; +import android.graphics.drawable.Drawable; +import android.text.TextPaint; +import android.view.ViewConfiguration; + +/** + * Animation to be displayed on the spacebar preview popup when switching languages by swiping the + * spacebar. It draws the current, previous and next languages and moves them by the delta of touch + * movement on the spacebar. + */ +public class SlidingLocaleDrawable extends Drawable { + + private final Context mContext; + private final Resources mRes; + private final int mWidth; + private final int mHeight; + private final Drawable mBackground; + private final TextPaint mTextPaint; + private final int mMiddleX; + private final Drawable mLeftDrawable; + private final Drawable mRightDrawable; + private final int mThreshold; + private int mDiff; + private boolean mHitThreshold; + private String mCurrentLanguage; + private String mNextLanguage; + private String mPrevLanguage; + + public SlidingLocaleDrawable(Context context, Drawable background, int width, int height) { + mContext = context; + mRes = context.getResources(); + mBackground = background; + LatinKeyboard.setDefaultBounds(mBackground); + mWidth = width; + mHeight = height; + final TextPaint textPaint = new TextPaint(); + textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18)); + textPaint.setColor(R.color.latinkeyboard_transparent); + textPaint.setTextAlign(Align.CENTER); + textPaint.setAlpha(LatinKeyboard.OPACITY_FULLY_OPAQUE); + textPaint.setAntiAlias(true); + mTextPaint = textPaint; + mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; + final Resources res = mRes; + mLeftDrawable = res.getDrawable( + R.drawable.sym_keyboard_feedback_language_arrows_left); + mRightDrawable = res.getDrawable( + R.drawable.sym_keyboard_feedback_language_arrows_right); + mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop(); + } + + private int getTextSizeFromTheme(int style, int defValue) { + TypedArray array = mContext.getTheme().obtainStyledAttributes( + style, new int[] { android.R.attr.textSize }); + int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue); + return textSize; + } + + void setDiff(int diff) { + if (diff == Integer.MAX_VALUE) { + mHitThreshold = false; + mCurrentLanguage = null; + return; + } + mDiff = diff; + if (mDiff > mWidth) mDiff = mWidth; + if (mDiff < -mWidth) mDiff = -mWidth; + if (Math.abs(mDiff) > mThreshold) mHitThreshold = true; + invalidateSelf(); + } + + + @Override + public void draw(Canvas canvas) { + canvas.save(); + if (mHitThreshold) { + Paint paint = mTextPaint; + final int width = mWidth; + final int height = mHeight; + final int diff = mDiff; + final Drawable lArrow = mLeftDrawable; + final Drawable rArrow = mRightDrawable; + canvas.clipRect(0, 0, width, height); + if (mCurrentLanguage == null) { + SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance(); + mCurrentLanguage = subtypeSwitcher.getInputLanguageName(); + mNextLanguage = subtypeSwitcher.getNextInputLanguageName(); + mPrevLanguage = subtypeSwitcher.getPreviousInputLanguageName(); + } + // Draw language text with shadow + final float baseline = mHeight * LatinKeyboard.SPACEBAR_LANGUAGE_BASELINE + - paint.descent(); + paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text)); + canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint); + canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint); + canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint); + + LatinKeyboard.setDefaultBounds(lArrow); + rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width, + rArrow.getIntrinsicHeight()); + lArrow.draw(canvas); + rArrow.draw(canvas); + } + if (mBackground != null) { + canvas.translate(mMiddleX, 0); + mBackground.draw(canvas); + } + canvas.restore(); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public void setAlpha(int alpha) { + // Ignore + } + + @Override + public void setColorFilter(ColorFilter cf) { + // Ignore + } + + @Override + public int getIntrinsicWidth() { + return mWidth; + } + + @Override + public int getIntrinsicHeight() { + return mHeight; + } +} diff --git a/java/src/com/android/inputmethod/latin/SwipeTracker.java b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java similarity index 97% rename from java/src/com/android/inputmethod/latin/SwipeTracker.java rename to java/src/com/android/inputmethod/keyboard/SwipeTracker.java index 970e9196560160d22f9ad2ef904392010b8ea60b..730cdc3902e1ff2beef39028cdda3dde7e55881d 100644 --- a/java/src/com/android/inputmethod/latin/SwipeTracker.java +++ b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java @@ -14,11 +14,11 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.keyboard; import android.view.MotionEvent; -class SwipeTracker { +public class SwipeTracker { private static final int NUM_PAST = 4; private static final int LONGEST_PAST_TIME = 200; @@ -91,7 +91,7 @@ class SwipeTracker { return mYVelocity; } - static class EventRingBuffer { + public static class EventRingBuffer { private final int bufSize; private final float xBuf[]; private final float yBuf[]; @@ -154,4 +154,4 @@ class SwipeTracker { end = advance(end); } } -} \ No newline at end of file +} diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboard.java b/java/src/com/android/inputmethod/latin/BaseKeyboard.java deleted file mode 100644 index e2331f33405f2008c1cce49e2cf81fcd3e86025d..0000000000000000000000000000000000000000 --- a/java/src/com/android/inputmethod/latin/BaseKeyboard.java +++ /dev/null @@ -1,717 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. - * - * 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.inputmethod.latin; - -import com.android.inputmethod.latin.BaseKeyboardParser.ParseException; -import com.android.inputmethod.latin.KeyStyles.KeyStyle; -import com.android.inputmethod.latin.KeyboardSwitcher.KeyboardId; - -import org.xmlpull.v1.XmlPullParserException; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.Log; -import android.util.Xml; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard - * consists of rows of keys. - * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p> - * <pre> - * <Keyboard - * latin:keyWidth="%10p" - * latin:keyHeight="50px" - * latin:horizontalGap="2px" - * latin:verticalGap="2px" > - * <Row latin:keyWidth="32px" > - * <Key latin:keyLabel="A" /> - * ... - * </Row> - * ... - * </Keyboard> - * </pre> - */ -public class BaseKeyboard { - - static final String TAG = "BaseKeyboard"; - - public static final int EDGE_LEFT = 0x01; - public static final int EDGE_RIGHT = 0x02; - public static final int EDGE_TOP = 0x04; - public static final int EDGE_BOTTOM = 0x08; - - public static final int KEYCODE_SHIFT = -1; - public static final int KEYCODE_MODE_CHANGE = -2; - public static final int KEYCODE_CANCEL = -3; - public static final int KEYCODE_DONE = -4; - public static final int KEYCODE_DELETE = -5; - public static final int KEYCODE_ALT = -6; - - /** Horizontal gap default for all rows */ - private int mDefaultHorizontalGap; - - /** Default key width */ - private int mDefaultWidth; - - /** Default key height */ - private int mDefaultHeight; - - /** Default gap between rows */ - private int mDefaultVerticalGap; - - /** Is the keyboard in the shifted state */ - private boolean mShifted; - - /** List of shift keys in this keyboard */ - private final List<Key> mShiftKeys = new ArrayList<Key>(); - - /** List of shift keys and its shifted state icon */ - private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>(); - - /** Total height of the keyboard, including the padding and keys */ - private int mTotalHeight; - - /** - * Total width of the keyboard, including left side gaps and keys, but not any gaps on the - * right side. - */ - private int mTotalWidth; - - /** List of keys in this keyboard */ - private final List<Key> mKeys = new ArrayList<Key>(); - - /** Width of the screen available to fit the keyboard */ - private final int mDisplayWidth; - - /** Height of the screen */ - private final int mDisplayHeight; - - protected final KeyboardId mId; - - // Variables for pre-computing nearest keys. - - public final int GRID_WIDTH; - public final int GRID_HEIGHT; - private final int GRID_SIZE; - private int mCellWidth; - private int mCellHeight; - private int[][] mGridNeighbors; - private int mProximityThreshold; - private static int[] EMPTY_INT_ARRAY = new int[0]; - /** Number of key widths from current touch point to search for nearest keys. */ - private static float SEARCH_DISTANCE = 1.2f; - - /** - * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. - * Some of the key size defaults can be overridden per row from what the {@link BaseKeyboard} - * defines. - */ - public static class Row { - /** Default width of a key in this row. */ - public int defaultWidth; - /** Default height of a key in this row. */ - public int defaultHeight; - /** Default horizontal gap between keys in this row. */ - public int defaultHorizontalGap; - /** Vertical gap following this row. */ - public int verticalGap; - /** - * Edge flags for this row of keys. Possible values that can be assigned are - * {@link BaseKeyboard#EDGE_TOP EDGE_TOP} and {@link BaseKeyboard#EDGE_BOTTOM EDGE_BOTTOM} - */ - public int rowEdgeFlags; - - private final BaseKeyboard parent; - - private Row(BaseKeyboard parent) { - this.parent = parent; - } - - public Row(Resources res, BaseKeyboard parent, XmlResourceParser parser) { - this.parent = parent; - TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard); - defaultWidth = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyWidth, - parent.mDisplayWidth, parent.mDefaultWidth); - defaultHeight = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyHeight, - parent.mDisplayHeight, parent.mDefaultHeight); - defaultHorizontalGap = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_horizontalGap, - parent.mDisplayWidth, parent.mDefaultHorizontalGap); - verticalGap = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_verticalGap, - parent.mDisplayHeight, parent.mDefaultVerticalGap); - a.recycle(); - a = res.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard_Row); - rowEdgeFlags = a.getInt(R.styleable.BaseKeyboard_Row_rowEdgeFlags, 0); - } - } - - /** - * Class for describing the position and characteristics of a single key in the keyboard. - */ - public static class Key { - /** - * All the key codes (unicode or custom code) that this key could generate, zero'th - * being the most important. - */ - public int[] codes; - /** The unicode that this key generates in manual temporary upper case mode. */ - public int manualTemporaryUpperCaseCode; - - /** Label to display */ - public CharSequence label; - /** Option of the label */ - public int labelOption; - - /** Icon to display instead of a label. Icon takes precedence over a label */ - public Drawable icon; - /** Hint icon to display on the key in conjunction with the label */ - public Drawable hintIcon; - /** Preview version of the icon, for the preview popup */ - /** - * The hint icon to display on the key when keyboard is in manual temporary upper case - * mode. - */ - public Drawable manualTemporaryUpperCaseHintIcon; - - public Drawable iconPreview; - /** Width of the key, not including the gap */ - public int width; - /** Height of the key, not including the gap */ - public int height; - /** The horizontal gap before this key */ - public int gap; - /** Whether this key is sticky, i.e., a toggle key */ - public boolean sticky; - /** X coordinate of the key in the keyboard layout */ - public int x; - /** Y coordinate of the key in the keyboard layout */ - public int y; - /** The current pressed state of this key */ - public boolean pressed; - /** If this is a sticky key, is it on? */ - public boolean on; - /** Text to output when pressed. This can be multiple characters, like ".com" */ - public CharSequence text; - /** Popup characters */ - public CharSequence popupCharacters; - - /** - * Flags that specify the anchoring to edges of the keyboard for detecting touch events - * that are just out of the boundary of the key. This is a bit mask of - * {@link BaseKeyboard#EDGE_LEFT}, {@link BaseKeyboard#EDGE_RIGHT}, - * {@link BaseKeyboard#EDGE_TOP} and {@link BaseKeyboard#EDGE_BOTTOM}. - */ - public int edgeFlags; - /** Whether this is a modifier key, such as Shift or Alt */ - public boolean modifier; - /** The BaseKeyboard that this key belongs to */ - protected final BaseKeyboard keyboard; - /** - * If this key pops up a mini keyboard, this is the resource id for the XML layout for that - * keyboard. - */ - public int popupResId; - /** Whether this key repeats itself when held down */ - public boolean repeatable; - - - private final static int[] KEY_STATE_NORMAL_ON = { - android.R.attr.state_checkable, - android.R.attr.state_checked - }; - - private final static int[] KEY_STATE_PRESSED_ON = { - android.R.attr.state_pressed, - android.R.attr.state_checkable, - android.R.attr.state_checked - }; - - private final static int[] KEY_STATE_NORMAL_OFF = { - android.R.attr.state_checkable - }; - - private final static int[] KEY_STATE_PRESSED_OFF = { - android.R.attr.state_pressed, - android.R.attr.state_checkable - }; - - private final static int[] KEY_STATE_NORMAL = { - }; - - private final static int[] KEY_STATE_PRESSED = { - android.R.attr.state_pressed - }; - - /** Create an empty key with no attributes. */ - public Key(Row parent) { - keyboard = parent.parent; - height = parent.defaultHeight; - gap = parent.defaultHorizontalGap; - width = parent.defaultWidth - gap; - edgeFlags = parent.rowEdgeFlags; - } - - /** Create a key with the given top-left coordinate and extract its attributes from - * the XML parser. - * @param res resources associated with the caller's context - * @param parent the row that this key belongs to. The row must already be attached to - * a {@link BaseKeyboard}. - * @param x the x coordinate of the top-left - * @param y the y coordinate of the top-left - * @param parser the XML parser containing the attributes for this key - */ - public Key(Resources res, Row parent, int x, int y, XmlResourceParser parser, - KeyStyles keyStyles) { - this(parent); - - TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), - R.styleable.BaseKeyboard); - height = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyHeight, - keyboard.mDisplayHeight, parent.defaultHeight); - gap = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_horizontalGap, - keyboard.mDisplayWidth, parent.defaultHorizontalGap); - width = BaseKeyboardParser.getDimensionOrFraction(a, - R.styleable.BaseKeyboard_keyWidth, - keyboard.mDisplayWidth, parent.defaultWidth) - gap; - a.recycle(); - - a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.BaseKeyboard_Key); - - final KeyStyle style; - if (a.hasValue(R.styleable.BaseKeyboard_Key_keyStyle)) { - String styleName = a.getString(R.styleable.BaseKeyboard_Key_keyStyle); - style = keyStyles.getKeyStyle(styleName); - if (style == null) - throw new ParseException("Unknown key style: " + styleName, parser); - } else { - style = keyStyles.getEmptyKeyStyle(); - } - - // Horizontal gap is divided equally to both sides of the key. - this.x = x + gap / 2; - this.y = y; - - codes = style.getIntArray(a, R.styleable.BaseKeyboard_Key_codes); - iconPreview = style.getDrawable(a, R.styleable.BaseKeyboard_Key_iconPreview); - setDefaultBounds(iconPreview); - popupCharacters = style.getText(a, R.styleable.BaseKeyboard_Key_popupCharacters); - popupResId = style.getResourceId(a, R.styleable.BaseKeyboard_Key_popupKeyboard, 0); - repeatable = style.getBoolean(a, R.styleable.BaseKeyboard_Key_isRepeatable, false); - modifier = style.getBoolean(a, R.styleable.BaseKeyboard_Key_isModifier, false); - sticky = style.getBoolean(a, R.styleable.BaseKeyboard_Key_isSticky, false); - edgeFlags = style.getFlag(a, R.styleable.BaseKeyboard_Key_keyEdgeFlags, 0); - edgeFlags |= parent.rowEdgeFlags; - - icon = style.getDrawable(a, R.styleable.BaseKeyboard_Key_keyIcon); - setDefaultBounds(icon); - hintIcon = style.getDrawable(a, R.styleable.BaseKeyboard_Key_keyHintIcon); - setDefaultBounds(hintIcon); - manualTemporaryUpperCaseHintIcon = style.getDrawable(a, - R.styleable.BaseKeyboard_Key_manualTemporaryUpperCaseHintIcon); - setDefaultBounds(manualTemporaryUpperCaseHintIcon); - - label = style.getText(a, R.styleable.BaseKeyboard_Key_keyLabel); - labelOption = style.getFlag(a, R.styleable.BaseKeyboard_Key_keyLabelOption, 0); - manualTemporaryUpperCaseCode = style.getInt(a, - R.styleable.BaseKeyboard_Key_manualTemporaryUpperCaseCode, 0); - text = style.getText(a, R.styleable.BaseKeyboard_Key_keyOutputText); - final Drawable shiftedIcon = style.getDrawable(a, - R.styleable.BaseKeyboard_Key_shiftedIcon); - if (shiftedIcon != null) - keyboard.getShiftedIcons().put(this, shiftedIcon); - - if (codes == null && !TextUtils.isEmpty(label)) { - codes = new int[] { label.charAt(0) }; - } - a.recycle(); - } - - /** - * Informs the key that it has been pressed, in case it needs to change its appearance or - * state. - * @see #onReleased(boolean) - */ - public void onPressed() { - pressed = !pressed; - } - - /** - * Changes the pressed state of the key. If it is a sticky key, it will also change the - * toggled state of the key if the finger was release inside. - * @param inside whether the finger was released inside the key - * @see #onPressed() - */ - public void onReleased(boolean inside) { - pressed = !pressed; - if (sticky) { - on = !on; - } - } - - /** - * Detects if a point falls inside this key. - * @param x the x-coordinate of the point - * @param y the y-coordinate of the point - * @return whether or not the point falls inside the key. If the key is attached to an - * edge, it will assume that all points between the key and the edge are considered to be - * inside the key. - */ - public boolean isInside(int x, int y) { - boolean leftEdge = (edgeFlags & EDGE_LEFT) > 0; - boolean rightEdge = (edgeFlags & EDGE_RIGHT) > 0; - boolean topEdge = (edgeFlags & EDGE_TOP) > 0; - boolean bottomEdge = (edgeFlags & EDGE_BOTTOM) > 0; - if ((x >= this.x || (leftEdge && x <= this.x + this.width)) - && (x < this.x + this.width || (rightEdge && x >= this.x)) - && (y >= this.y || (topEdge && y <= this.y + this.height)) - && (y < this.y + this.height || (bottomEdge && y >= this.y))) { - return true; - } else { - return false; - } - } - - /** - * Returns the square of the distance to the nearest edge of the key and the given point. - * @param x the x-coordinate of the point - * @param y the y-coordinate of the point - * @return the square of the distance of the point from the nearest edge of the key - */ - public int squaredDistanceToEdge(int x, int y) { - final int left = this.x; - final int right = left + this.width; - final int top = this.y; - final int bottom = top + this.height; - final int edgeX = x < left ? left : (x > right ? right : x); - final int edgeY = y < top ? top : (y > bottom ? bottom : y); - final int dx = x - edgeX; - final int dy = y - edgeY; - return dx * dx + dy * dy; - } - - /** - * Returns the drawable state for the key, based on the current state and type of the key. - * @return the drawable state of the key. - * @see android.graphics.drawable.StateListDrawable#setState(int[]) - */ - public int[] getCurrentDrawableState() { - int[] states = KEY_STATE_NORMAL; - - if (on) { - if (pressed) { - states = KEY_STATE_PRESSED_ON; - } else { - states = KEY_STATE_NORMAL_ON; - } - } else { - if (sticky) { - if (pressed) { - states = KEY_STATE_PRESSED_OFF; - } else { - states = KEY_STATE_NORMAL_OFF; - } - } else { - if (pressed) { - states = KEY_STATE_PRESSED; - } - } - } - return states; - } - } - - /** - * Creates a keyboard from the given xml key layout file. - * @param context the application or service context - * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. - */ - public BaseKeyboard(Context context, int xmlLayoutResId) { - this(context, xmlLayoutResId, null); - } - - /** - * Creates a keyboard from the given keyboard identifier. - * @param context the application or service context - * @param id keyboard identifier - */ - public BaseKeyboard(Context context, KeyboardId id) { - this(context, id.getXmlId(), id); - } - - /** - * Creates a keyboard from the given xml key layout file. - * @param context the application or service context - * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. - * @param id keyboard identifier - */ - private BaseKeyboard(Context context, int xmlLayoutResId, KeyboardId id) { - this(context, xmlLayoutResId, id, - context.getResources().getDisplayMetrics().widthPixels, - context.getResources().getDisplayMetrics().heightPixels); - } - - private BaseKeyboard(Context context, int xmlLayoutResId, KeyboardId id, int width, - int height) { - Resources res = context.getResources(); - GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width); - GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height); - GRID_SIZE = GRID_WIDTH * GRID_HEIGHT; - - mDisplayWidth = width; - mDisplayHeight = height; - - mDefaultHorizontalGap = 0; - setKeyWidth(mDisplayWidth / 10); - mDefaultVerticalGap = 0; - mDefaultHeight = mDefaultWidth; - mId = id; - loadKeyboard(context, xmlLayoutResId); - } - - /** - * <p>Creates a blank keyboard from the given resource file and populates it with the specified - * characters in left-to-right, top-to-bottom fashion, using the specified number of columns. - * </p> - * <p>If the specified number of columns is -1, then the keyboard will fit as many keys as - * possible in each row.</p> - * @param context the application or service context - * @param layoutTemplateResId the layout template file, containing no keys. - * @param characters the list of characters to display on the keyboard. One key will be created - * for each character. - * @param columns the number of columns of keys to display. If this number is greater than the - * number of keys that can fit in a row, it will be ignored. If this number is -1, the - * keyboard will fit as many keys as possible in each row. - */ - public BaseKeyboard(Context context, int layoutTemplateResId, - CharSequence characters, int columns, int horizontalPadding) { - this(context, layoutTemplateResId); - int x = 0; - int y = 0; - int column = 0; - mTotalWidth = 0; - - Row row = new Row(this); - row.defaultHeight = mDefaultHeight; - row.defaultWidth = mDefaultWidth; - row.defaultHorizontalGap = mDefaultHorizontalGap; - row.verticalGap = mDefaultVerticalGap; - row.rowEdgeFlags = EDGE_TOP | EDGE_BOTTOM; - final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns; - for (int i = 0; i < characters.length(); i++) { - char c = characters.charAt(i); - if (column >= maxColumns - || x + mDefaultWidth + horizontalPadding > mDisplayWidth) { - x = 0; - y += mDefaultVerticalGap + mDefaultHeight; - column = 0; - } - final Key key = new Key(row); - // Horizontal gap is divided equally to both sides of the key. - key.x = x + key.gap / 2; - key.y = y; - key.label = String.valueOf(c); - key.codes = new int[] { c }; - column++; - x += key.width + key.gap; - mKeys.add(key); - if (x > mTotalWidth) { - mTotalWidth = x; - } - } - mTotalHeight = y + mDefaultHeight; - } - - public KeyboardId getKeyboardId() { - return mId; - } - - public List<Key> getKeys() { - return mKeys; - } - - protected int getHorizontalGap() { - return mDefaultHorizontalGap; - } - - protected void setHorizontalGap(int gap) { - mDefaultHorizontalGap = gap; - } - - protected int getVerticalGap() { - return mDefaultVerticalGap; - } - - protected void setVerticalGap(int gap) { - mDefaultVerticalGap = gap; - } - - protected int getKeyHeight() { - return mDefaultHeight; - } - - protected void setKeyHeight(int height) { - mDefaultHeight = height; - } - - protected int getKeyWidth() { - return mDefaultWidth; - } - - protected void setKeyWidth(int width) { - mDefaultWidth = width; - final int threshold = (int) (width * SEARCH_DISTANCE); - mProximityThreshold = threshold * threshold; - } - - /** - * Returns the total height of the keyboard - * @return the total height of the keyboard - */ - public int getHeight() { - return mTotalHeight; - } - - public int getMinWidth() { - return mTotalWidth; - } - - public int getKeyboardHeight() { - return mDisplayHeight; - } - - public int getKeyboardWidth() { - return mDisplayWidth; - } - - public boolean setShifted(boolean shiftState) { - for (final Key key : mShiftKeys) { - key.on = shiftState; - } - if (mShifted != shiftState) { - mShifted = shiftState; - return true; - } - return false; - } - - public boolean isShiftedOrShiftLocked() { - return mShifted; - } - - public List<Key> getShiftKeys() { - return mShiftKeys; - } - - public Map<Key, Drawable> getShiftedIcons() { - return mShiftedIcons; - } - - private void computeNearestNeighbors() { - // Round-up so we don't have any pixels outside the grid - mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; - mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT; - mGridNeighbors = new int[GRID_SIZE][]; - final int[] indices = new int[mKeys.size()]; - final int gridWidth = GRID_WIDTH * mCellWidth; - final int gridHeight = GRID_HEIGHT * mCellHeight; - final int threshold = mProximityThreshold; - for (int x = 0; x < gridWidth; x += mCellWidth) { - for (int y = 0; y < gridHeight; y += mCellHeight) { - final int centerX = x + mCellWidth / 2; - final int centerY = y + mCellHeight / 2; - int count = 0; - for (int i = 0; i < mKeys.size(); i++) { - final Key key = mKeys.get(i); - if (key.squaredDistanceToEdge(centerX, centerY) < threshold) - indices[count++] = i; - } - final int[] cell = new int[count]; - System.arraycopy(indices, 0, cell, 0, count); - mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell; - } - } - } - - /** - * Returns the indices of the keys that are closest to the given point. - * @param x the x-coordinate of the point - * @param y the y-coordinate of the point - * @return the array of integer indices for the nearest keys to the given point. If the given - * point is out of range, then an array of size zero is returned. - */ - public int[] getNearestKeys(int x, int y) { - if (mGridNeighbors == null) computeNearestNeighbors(); - if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) { - int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth); - if (index < GRID_SIZE) { - return mGridNeighbors[index]; - } - } - return EMPTY_INT_ARRAY; - } - - // TODO should be private - protected BaseKeyboard.Row createRowFromXml(Resources res, XmlResourceParser parser) { - return new BaseKeyboard.Row(res, this, parser); - } - - // TODO should be private - protected BaseKeyboard.Key createKeyFromXml(Resources res, Row parent, int x, int y, - XmlResourceParser parser, KeyStyles keyStyles) { - return new BaseKeyboard.Key(res, parent, x, y, parser, keyStyles); - } - - private void loadKeyboard(Context context, int xmlLayoutResId) { - try { - final Resources res = context.getResources(); - BaseKeyboardParser parser = new BaseKeyboardParser(this, res); - parser.parseKeyboard(res.getXml(xmlLayoutResId)); - // mTotalWidth is the width of this keyboard which is maximum width of row. - mTotalWidth = parser.getMaxRowWidth(); - mTotalHeight = parser.getTotalHeight(); - } catch (XmlPullParserException e) { - Log.w(TAG, "keyboard XML parse error: " + e); - throw new IllegalArgumentException(e); - } catch (IOException e) { - Log.w(TAG, "keyboard XML parse error: " + e); - throw new RuntimeException(e); - } - } - - protected static void setDefaultBounds(Drawable drawable) { - if (drawable != null) - drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), - drawable.getIntrinsicHeight()); - } -} diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java index fc517aeb78218d835288249e499f3b8364343ea1..ad3f1db9b98c346632d895450985c3604f5f25b9 100644 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -57,6 +57,7 @@ public class InputLanguageSelection extends PreferenceActivity { return this.label; } + @Override public int compareTo(Object o) { return sCollator.compare(this.label, ((Loc) o).label); } diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java index 00b6f0a43d1f7177d5eca4074603dc1fdb258597..e8487e798aeaa4b2a2f9fe339038a658963d78a8 100644 --- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java @@ -16,16 +16,19 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.KeyboardView; +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.LatinKeyboard; +import com.android.inputmethod.keyboard.LatinKeyboardView; + import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.util.Log; import android.view.InflateException; -import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import java.lang.ref.SoftReference; -import java.util.Arrays; import java.util.HashMap; import java.util.Locale; @@ -34,14 +37,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private static final boolean DEBUG = false; public static final boolean DEBUG_STATE = false; - public static final int MODE_TEXT = 0; - public static final int MODE_URL = 1; - public static final int MODE_EMAIL = 2; - public static final int MODE_IM = 3; - public static final int MODE_WEB = 4; - public static final int MODE_PHONE = 5; - public static final int MODE_NUMBER = 6; - // Changing DEFAULT_LAYOUT_ID also requires prefs_for_debug.xml to be matched with. public static final String DEFAULT_LAYOUT_ID = "5"; public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902"; @@ -74,7 +69,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache = new HashMap<KeyboardId, SoftReference<LatinKeyboard>>(); - private int mMode = MODE_TEXT; /* default value */ + private int mMode = KeyboardId.MODE_TEXT; /* default value */ private int mImeOptions; private boolean mIsSymbols; /** mIsAutoCompletionActive indicates that auto completed word will be input instead of @@ -132,129 +127,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard" // respectively here for xlarge device's layout switching. mSymbolsId = new KeyboardId(locale, orientation, mode, - mode == MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols, + mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols, colorScheme, hasSettingsKey, voiceKeyEnabled, hasVoiceKey, imeOptions, true); mSymbolsShiftedId = new KeyboardId(locale, orientation, mode, - mode == MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift, + mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift, colorScheme, hasSettingsKey, voiceKeyEnabled, hasVoiceKey, imeOptions, true); } - /** - * Represents the parameters necessary to construct a new LatinKeyboard, - * which also serve as a unique identifier for each keyboard type. - */ - public static class KeyboardId { - public final Locale mLocale; - public final int mOrientation; - public final int mMode; - public final int mXmlId; - public final int mColorScheme; - public final boolean mHasSettingsKey; - public final boolean mVoiceKeyEnabled; - public final boolean mHasVoiceKey; - public final int mImeOptions; - public final boolean mEnableShiftLock; - - private final int mHashCode; - - public KeyboardId(Locale locale, int orientation, int mode, - int xmlId, int colorScheme, boolean hasSettingsKey, boolean voiceKeyEnabled, - boolean hasVoiceKey, int imeOptions, boolean enableShiftLock) { - this.mLocale = locale; - this.mOrientation = orientation; - this.mMode = mode; - this.mXmlId = xmlId; - this.mColorScheme = colorScheme; - this.mHasSettingsKey = hasSettingsKey; - this.mVoiceKeyEnabled = voiceKeyEnabled; - this.mHasVoiceKey = hasVoiceKey; - // We are interested only in IME_MASK_ACTION enum value and IME_FLAG_NO_ENTER_ACTION. - this.mImeOptions = imeOptions - & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION); - this.mEnableShiftLock = enableShiftLock; - - this.mHashCode = Arrays.hashCode(new Object[] { - locale, - orientation, - mode, - xmlId, - colorScheme, - hasSettingsKey, - voiceKeyEnabled, - hasVoiceKey, - imeOptions, - enableShiftLock, - }); - } - - public int getXmlId() { - return mXmlId; - } - - public boolean isAlphabetMode() { - return mXmlId == R.xml.kbd_qwerty; - } - - @Override - public boolean equals(Object other) { - return other instanceof KeyboardId && equals((KeyboardId) other); - } - - private boolean equals(KeyboardId other) { - return other.mLocale.equals(this.mLocale) - && other.mOrientation == this.mOrientation - && other.mMode == this.mMode - && other.mXmlId == this.mXmlId - && other.mColorScheme == this.mColorScheme - && other.mHasSettingsKey == this.mHasSettingsKey - && other.mVoiceKeyEnabled == this.mVoiceKeyEnabled - && other.mHasVoiceKey == this.mHasVoiceKey - && other.mImeOptions == this.mImeOptions - && other.mEnableShiftLock == this.mEnableShiftLock; - } - - @Override - public int hashCode() { - return mHashCode; - } - - @Override - public String toString() { - return String.format("[%s %s %5s imeOptions=0x%08x xml=0x%08x %s%s%s%s%s]", - mLocale, - (mOrientation == 1 ? "port" : "land"), - modeName(mMode), - mImeOptions, - mXmlId, - colorSchemeName(mColorScheme), - (mHasSettingsKey ? " hasSettingsKey" : ""), - (mVoiceKeyEnabled ? " voiceKeyEnabled" : ""), - (mHasVoiceKey ? " hasVoiceKey" : ""), - (mEnableShiftLock ? " enableShiftLock" : "")); - } - - private static String modeName(int mode) { - switch (mode) { - case MODE_TEXT: return "text"; - case MODE_URL: return "url"; - case MODE_EMAIL: return "email"; - case MODE_IM: return "im"; - case MODE_WEB: return "web"; - case MODE_PHONE: return "phone"; - case MODE_NUMBER: return "number"; - } - return null; - } - - private static String colorSchemeName(int colorScheme) { - switch (colorScheme) { - case BaseKeyboardView.COLOR_SCHEME_WHITE: return "white"; - case BaseKeyboardView.COLOR_SCHEME_BLACK: return "black"; - } - return null; - } - } - private boolean hasVoiceKey(boolean isSymbols) { return mVoiceKeyEnabled && (isSymbols != mVoiceButtonOnPrimary); } @@ -327,9 +206,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final boolean enableShiftLock; if (isSymbols) { - if (mode == MODE_PHONE) { + if (mode == KeyboardId.MODE_PHONE) { xmlId = R.xml.kbd_phone_symbols; - } else if (mode == MODE_NUMBER) { + } else if (mode == KeyboardId.MODE_NUMBER) { // Note: MODE_NUMBER keyboard layout has no "switch alpha symbol" key. xmlId = R.xml.kbd_number; } else { @@ -337,10 +216,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } enableShiftLock = false; } else { - if (mode == MODE_PHONE) { + if (mode == KeyboardId.MODE_PHONE) { xmlId = R.xml.kbd_phone; enableShiftLock = false; - } else if (mode == MODE_NUMBER) { + } else if (mode == KeyboardId.MODE_NUMBER) { xmlId = R.xml.kbd_number; enableShiftLock = false; } else { @@ -731,7 +610,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private int getColorScheme() { return (mInputView != null) - ? mInputView.getColorScheme() : BaseKeyboardView.COLOR_SCHEME_WHITE; + ? mInputView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE; } public void onAutoCompletionStateChanged(boolean isAutoCompletion) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 36c77efaf4abc3aff620b80d150d315ad992a21b..4f4112fa8fdde5dc6a79b8445db1fa5ab020262b 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -16,6 +16,12 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardActionListener; +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.KeyboardView; +import com.android.inputmethod.keyboard.LatinKeyboard; +import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer; import com.android.inputmethod.voice.VoiceIMEConnector; @@ -73,7 +79,7 @@ import java.util.Locale; * Input method implementation for Qwerty'ish keyboard. */ public class LatinIME extends InputMethodService - implements BaseKeyboardView.OnKeyboardActionListener, + implements KeyboardActionListener, SharedPreferences.OnSharedPreferenceChangeListener, Tutorial.TutorialListener { private static final String TAG = "LatinIME"; @@ -548,10 +554,10 @@ public class LatinIME extends InputMethodService switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: - mode = KeyboardSwitcher.MODE_NUMBER; + mode = KeyboardId.MODE_NUMBER; break; case EditorInfo.TYPE_CLASS_PHONE: - mode = KeyboardSwitcher.MODE_PHONE; + mode = KeyboardId.MODE_PHONE; break; case EditorInfo.TYPE_CLASS_TEXT: //startPrediction(); @@ -568,24 +574,24 @@ public class LatinIME extends InputMethodService } if (isEmailVariation(variation)) { mPredictionOn = false; - mode = KeyboardSwitcher.MODE_EMAIL; + mode = KeyboardId.MODE_EMAIL; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { mPredictionOn = false; - mode = KeyboardSwitcher.MODE_URL; + mode = KeyboardId.MODE_URL; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { - mode = KeyboardSwitcher.MODE_IM; + mode = KeyboardId.MODE_IM; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { mPredictionOn = false; - mode = KeyboardSwitcher.MODE_TEXT; + mode = KeyboardId.MODE_TEXT; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { - mode = KeyboardSwitcher.MODE_WEB; + mode = KeyboardId.MODE_WEB; // If it's a browser edit field and auto correct is not ON explicitly, then // disable auto correction, but keep suggestions on. if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { mInputTypeNoAutoCorrect = true; } } else { - mode = KeyboardSwitcher.MODE_TEXT; + mode = KeyboardId.MODE_TEXT; } // If NO_SUGGESTIONS is set, don't do prediction. @@ -604,7 +610,7 @@ public class LatinIME extends InputMethodService } break; default: - mode = KeyboardSwitcher.MODE_TEXT; + mode = KeyboardId.MODE_TEXT; break; } inputView.closing(); @@ -675,7 +681,7 @@ public class LatinIME extends InputMethodService mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging); - BaseKeyboardView inputView = mKeyboardSwitcher.getInputView(); + KeyboardView inputView = mKeyboardSwitcher.getInputView(); if (inputView != null) inputView.closing(); if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); @@ -685,7 +691,7 @@ public class LatinIME extends InputMethodService @Override public void onFinishInputView(boolean finishingInput) { super.onFinishInputView(finishingInput); - BaseKeyboardView inputView = mKeyboardSwitcher.getInputView(); + KeyboardView inputView = mKeyboardSwitcher.getInputView(); if (inputView != null) inputView.setForeground(false); // Remove pending messages related to update suggestions @@ -1073,51 +1079,52 @@ public class LatinIME extends InputMethodService // Implementation of KeyboardViewListener + @Override public void onKey(int primaryCode, int[] keyCodes, int x, int y) { long when = SystemClock.uptimeMillis(); - if (primaryCode != BaseKeyboard.KEYCODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { + if (primaryCode != Keyboard.KEYCODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { mDeleteCount = 0; } mLastKeyTime = when; KeyboardSwitcher switcher = mKeyboardSwitcher; final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); switch (primaryCode) { - case BaseKeyboard.KEYCODE_DELETE: + case Keyboard.KEYCODE_DELETE: handleBackspace(); mDeleteCount++; LatinImeLogger.logOnDelete(); break; - case BaseKeyboard.KEYCODE_SHIFT: + case Keyboard.KEYCODE_SHIFT: // Shift key is handled in onPress() when device has distinct multi-touch panel. if (!distinctMultiTouch) switcher.toggleShift(); break; - case BaseKeyboard.KEYCODE_MODE_CHANGE: + case Keyboard.KEYCODE_MODE_CHANGE: // Symbol key is handled in onPress() when device has distinct multi-touch panel. if (!distinctMultiTouch) switcher.changeKeyboardMode(); break; - case BaseKeyboard.KEYCODE_CANCEL: + case Keyboard.KEYCODE_CANCEL: if (!isShowingOptionDialog()) { handleClose(); } break; - case LatinKeyboardView.KEYCODE_OPTIONS: + case LatinKeyboard.KEYCODE_OPTIONS: onOptionKeyPressed(); break; - case LatinKeyboardView.KEYCODE_OPTIONS_LONGPRESS: + case LatinKeyboard.KEYCODE_OPTIONS_LONGPRESS: onOptionKeyLongPressed(); break; - case LatinKeyboardView.KEYCODE_NEXT_LANGUAGE: + case LatinKeyboard.KEYCODE_NEXT_LANGUAGE: toggleLanguage(false, true); break; - case LatinKeyboardView.KEYCODE_PREV_LANGUAGE: + case LatinKeyboard.KEYCODE_PREV_LANGUAGE: toggleLanguage(false, false); break; - case LatinKeyboardView.KEYCODE_CAPSLOCK: + case LatinKeyboard.KEYCODE_CAPSLOCK: switcher.toggleCapsLock(); break; - case LatinKeyboardView.KEYCODE_VOICE: /* was a button press, was not a swipe */ + case LatinKeyboard.KEYCODE_VOICE: /* was a button press, was not a swipe */ mVoiceConnector.startListening(false, mKeyboardSwitcher.getInputView().getWindowToken(), mConfigurationChanging); break; @@ -1143,6 +1150,7 @@ public class LatinIME extends InputMethodService mEnteredText = null; } + @Override public void onText(CharSequence text) { mVoiceConnector.commitVoiceInput(); InputConnection ic = getCurrentInputConnection(); @@ -1161,6 +1169,7 @@ public class LatinIME extends InputMethodService mEnteredText = text; } + @Override public void onCancel() { // User released a finger outside any key } @@ -1420,24 +1429,26 @@ public class LatinIME extends InputMethodService } public void switchToKeyboardView() { - mHandler.post(new Runnable() { - public void run() { - if (DEBUG) { - Log.d(TAG, "Switch to keyboard view."); - } - View v = mKeyboardSwitcher.getInputView(); - if (v != null) { - // Confirms that the keyboard view doesn't have parent view. - ViewParent p = v.getParent(); - if (p != null && p instanceof ViewGroup) { - ((ViewGroup)p).removeView(v); - } - setInputView(v); - } - setCandidatesViewShown(isCandidateStripVisible()); - updateInputViewShown(); - mHandler.postUpdateSuggestions(); - }}); + mHandler.post(new Runnable() { + @Override + public void run() { + if (DEBUG) { + Log.d(TAG, "Switch to keyboard view."); + } + View v = mKeyboardSwitcher.getInputView(); + if (v != null) { + // Confirms that the keyboard view doesn't have parent view. + ViewParent p = v.getParent(); + if (p != null && p instanceof ViewGroup) { + ((ViewGroup) p).removeView(v); + } + setInputView(v); + } + setCandidatesViewShown(isCandidateStripVisible()); + updateInputViewShown(); + mHandler.postUpdateSuggestions(); + } + }); } public void clearSuggestions() { @@ -1586,8 +1597,8 @@ public class LatinIME extends InputMethodService LatinImeLogger.logOnManualSuggestion( "", suggestion.toString(), index, suggestions); final char primaryCode = suggestion.charAt(0); - onKey(primaryCode, new int[]{primaryCode}, BaseKeyboardView.NOT_A_TOUCH_COORDINATE, - BaseKeyboardView.NOT_A_TOUCH_COORDINATE); + onKey(primaryCode, new int[]{primaryCode}, KeyboardView.NOT_A_TOUCH_COORDINATE, + KeyboardView.NOT_A_TOUCH_COORDINATE); if (ic != null) { ic.endBatchEdit(); } @@ -1877,6 +1888,7 @@ public class LatinIME extends InputMethodService switcher.updateShiftState(); } + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { mSubtypeSwitcher.onSharedPreferenceChanged(sharedPreferences, key); @@ -1888,6 +1900,7 @@ public class LatinIME extends InputMethodService } } + @Override public void swipeRight() { if (LatinKeyboardView.DEBUG_AUTO_PLAY) { CharSequence text = ((android.text.ClipboardManager)getSystemService( @@ -1898,38 +1911,43 @@ public class LatinIME extends InputMethodService } } + @Override public void swipeLeft() { } + @Override public void swipeDown() { handleClose(); } + @Override public void swipeUp() { } + @Override public void onPress(int primaryCode) { vibrate(); playKeyClick(primaryCode); KeyboardSwitcher switcher = mKeyboardSwitcher; final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); - if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) { + if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { switcher.onPressShift(); - } else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) { + } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { switcher.onPressSymbol(); } else { switcher.onOtherKeyPressed(); } } + @Override public void onRelease(int primaryCode) { KeyboardSwitcher switcher = mKeyboardSwitcher; // Reset any drag flags in the keyboard switcher.keyReleased(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); - if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) { + if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) { switcher.onReleaseShift(); - } else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) { + } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { switcher.onReleaseSymbol(); } } @@ -1966,7 +1984,7 @@ public class LatinIME extends InputMethodService // FIXME: These should be triggered after auto-repeat logic int sound = AudioManager.FX_KEYPRESS_STANDARD; switch (primaryCode) { - case BaseKeyboard.KEYCODE_DELETE: + case Keyboard.KEYCODE_DELETE: sound = AudioManager.FX_KEYPRESS_DELETE; break; case KEYCODE_ENTER: @@ -2006,6 +2024,7 @@ public class LatinIME extends InputMethodService } // Tutorial.TutorialListener + @Override public void onTutorialDone() { sendDownUpKeyEvents(-1); // Inform the setupwizard that tutorial is in last bubble mTutorial = null; @@ -2171,6 +2190,7 @@ public class LatinIME extends InputMethodService itemInputMethod, itemSettings}, new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface di, int position) { di.dismiss(); switch (position) { diff --git a/java/src/com/android/inputmethod/latin/LatinIMEDebugSettings.java b/java/src/com/android/inputmethod/latin/LatinIMEDebugSettings.java index cba1a0af9265d66ebc896f13ee0f2ffc8c75e4e1..68738eca13257a2c7478a39542e9a59b6ef2bf7b 100644 --- a/java/src/com/android/inputmethod/latin/LatinIMEDebugSettings.java +++ b/java/src/com/android/inputmethod/latin/LatinIMEDebugSettings.java @@ -43,6 +43,7 @@ public class LatinIMEDebugSettings extends PreferenceActivity updateDebugMode(); } + @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { if (key.equals(DEBUG_MODE_KEY)) { if (mDebugMode != null) { diff --git a/java/src/com/android/inputmethod/latin/LatinIMESettings.java b/java/src/com/android/inputmethod/latin/LatinIMESettings.java index ae6646113bb73a74d20bf3b8cb702517b1f8f5ed..187b6d39409518b1eb8885cab25f91d996244120 100644 --- a/java/src/com/android/inputmethod/latin/LatinIMESettings.java +++ b/java/src/com/android/inputmethod/latin/LatinIMESettings.java @@ -137,6 +137,7 @@ public class LatinIMESettings extends PreferenceActivity super.onDestroy(); } + @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { (new BackupManager(this)).dataChanged(); // If turning on voice input, show dialog @@ -181,6 +182,7 @@ public class LatinIMESettings extends PreferenceActivity switch (id) { case VOICE_INPUT_CONFIRM_DIALOG: DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int whichButton) { if (whichButton == DialogInterface.BUTTON_NEGATIVE) { mVoicePreference.setValue(mVoiceModeOff); @@ -226,6 +228,7 @@ public class LatinIMESettings extends PreferenceActivity } } + @Override public void onDismiss(DialogInterface dialog) { mLogger.settingsWarningDialogDismissed(); if (!mOkClicked) { diff --git a/java/src/com/android/inputmethod/latin/LatinIMEUtil.java b/java/src/com/android/inputmethod/latin/LatinIMEUtil.java index a58f630cd3d462bef7e2c041b94941e0dcc98b12..f508b9ab830a72eaea5b1ca10daab1ec7c412ec6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIMEUtil.java +++ b/java/src/com/android/inputmethod/latin/LatinIMEUtil.java @@ -310,6 +310,7 @@ public class LatinIMEUtil { public void write(final String log) { mLoggingHandler.post(new Runnable() { + @Override public void run() { createLogFileIfNotExist(); final long currentTime = System.currentTimeMillis(); @@ -327,6 +328,7 @@ public class LatinIMEUtil { public void printAll() { mLoggingHandler.post(new Runnable() { + @Override public void run() { mWriter.flush(); StringBuilder sb = new StringBuilder(); @@ -355,6 +357,7 @@ public class LatinIMEUtil { public void clearAll() { mLoggingHandler.post(new Runnable() { + @Override public void run() { if (mFile != null && mFile.exists()) { if (LatinImeLogger.sDBG) { diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index b64e3ddb2490186240b737a87e530c771053355e..de194d21bcaa4f32424ad67c59dd52886542184a 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.Dictionary.DataType; import android.content.Context; @@ -27,6 +28,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static boolean sDBG = false; + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { } @@ -67,7 +69,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static void onAddSuggestedWord(String word, int typeId, DataType dataType) { } - public static void onSetKeyboard(BaseKeyboard kb) { + public static void onSetKeyboard(Keyboard kb) { } public static void onPrintAllUsabilityStudtyLogs() { diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 103443e6dbcda34f5a92b75ccbf37678c5c7d6be..a9891768993ff54ab7272a83093272d041516fbe 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.LatinKeyboard; import com.android.inputmethod.voice.SettingsUtil; import com.android.inputmethod.voice.VoiceIMEConnector; import com.android.inputmethod.voice.VoiceInput; @@ -197,7 +198,7 @@ public class SubtypeSwitcher { || VoiceIMEConnector.getInstance().needsToShowWarningDialog()) { if (mVoiceInput != null) { // TODO: Call proper function to trigger VoiceIME - mService.onKey(LatinKeyboardView.KEYCODE_VOICE, null, 0, 0); + mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0); } } } else { @@ -350,7 +351,7 @@ public class SubtypeSwitcher { if (DBG) { Log.d(TAG, "Set and call voice input."); } - mService.onKey(LatinKeyboardView.KEYCODE_VOICE, null, 0, 0); + mService.onKey(LatinKeyboard.KEYCODE_VOICE, null, 0, 0); return true; } } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index ca2ffe13a54c207fea3b2f9605ba615540acc637..4c9b7509a48b7c9a8cf004311215092a6fd20602 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -423,6 +423,7 @@ public class Suggest implements Dictionary.WordCallback { return false; } + @Override public boolean addWord(final char[] word, final int offset, final int length, int freq, final int dicTypeId, final Dictionary.DataType dataType) { Dictionary.DataType dataTypeForLog = dataType; diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java index 56347af5db24ef83a37a90eb3719ac2f8687e42a..31a192bfe3e315bb07237f0a99720e64d4341939 100644 --- a/java/src/com/android/inputmethod/latin/TextEntryState.java +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -16,7 +16,7 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.latin.BaseKeyboard.Key; +import com.android.inputmethod.keyboard.Key; import android.content.Context; import android.text.format.DateFormat; diff --git a/java/src/com/android/inputmethod/latin/Tutorial.java b/java/src/com/android/inputmethod/latin/Tutorial.java index cd7636f3c3da9c2cc61f9cd50201c4a9447ff3e3..bd069bd0d8c545ccb596ddd8bd9066caee3937e8 100644 --- a/java/src/com/android/inputmethod/latin/Tutorial.java +++ b/java/src/com/android/inputmethod/latin/Tutorial.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.keyboard.LatinKeyboardView; + import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Handler; @@ -133,6 +135,7 @@ public class Tutorial implements OnTouchListener { if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) offy -= window.getHeight(); if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) offx -= window.getWidth(); textView.setOnTouchListener(new View.OnTouchListener() { + @Override public boolean onTouch(View view, MotionEvent me) { Tutorial.this.next(); return true; @@ -237,6 +240,7 @@ public class Tutorial implements OnTouchListener { return true; } + @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { next(); diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java index 49b95e9aa14279c8e869871f84d4b3cab1867c6d..a522303e6842c9c4d0e4ab7de81afb5f0137f7f0 100644 --- a/java/src/com/android/inputmethod/latin/UserDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserDictionary.java @@ -97,6 +97,7 @@ public class UserDictionary extends ExpandableDictionary { final ContentResolver contentResolver = getContext().getContentResolver(); new Thread("addWord") { + @Override public void run() { contentResolver.insert(Words.CONTENT_URI, values); } diff --git a/java/src/com/android/inputmethod/voice/FieldContext.java b/java/src/com/android/inputmethod/voice/FieldContext.java index 5fbacfb6c3d16e0fd84d502e6982882b75cce97c..dfdfbaa9f7896ec8e2853b7fcd379085b24f229c 100644 --- a/java/src/com/android/inputmethod/voice/FieldContext.java +++ b/java/src/com/android/inputmethod/voice/FieldContext.java @@ -73,6 +73,7 @@ public class FieldContext { bundle.putInt(IME_OPTIONS, info.imeOptions); } + @SuppressWarnings("static-access") private static void addInputConnectionToBundle( InputConnection conn, Bundle bundle) { if (conn == null) { @@ -96,6 +97,7 @@ public class FieldContext { return mFieldInfo; } + @Override public String toString() { return mFieldInfo.toString(); } diff --git a/java/src/com/android/inputmethod/voice/RecognitionView.java b/java/src/com/android/inputmethod/voice/RecognitionView.java index 1d12977134140b034dcdac5c0004a95b8bc0b1ba..12d0de8529ce2e7bbc5360c9c7daf3e2a082e158 100644 --- a/java/src/com/android/inputmethod/voice/RecognitionView.java +++ b/java/src/com/android/inputmethod/voice/RecognitionView.java @@ -51,6 +51,7 @@ import java.util.List; * plays beeps, shows errors, etc. */ public class RecognitionView { + @SuppressWarnings("unused") private static final String TAG = "RecognitionView"; private Handler mUiHandler; // Reference to UI thread @@ -78,6 +79,7 @@ public class RecognitionView { /** Updates the microphone icon to show user their volume.*/ private Runnable mUpdateVolumeRunnable = new Runnable() { + @Override public void run() { if (mState != State.LISTENING) { return; @@ -141,6 +143,7 @@ public class RecognitionView { public void restoreState() { mUiHandler.post(new Runnable() { + @Override public void run() { // Restart the spinner if (mState == State.WORKING) { @@ -153,6 +156,7 @@ public class RecognitionView { public void showInitializing() { mUiHandler.post(new Runnable() { + @Override public void run() { prepareDialog(false, mContext.getText(R.string.voice_initializing), mInitializing, mContext.getText(R.string.cancel)); @@ -162,6 +166,7 @@ public class RecognitionView { public void showListening() { mUiHandler.post(new Runnable() { + @Override public void run() { mState = State.LISTENING; prepareDialog(false, mContext.getText(R.string.voice_listening), mSpeakNow.get(0), @@ -177,6 +182,7 @@ public class RecognitionView { public void showError(final String message) { mUiHandler.post(new Runnable() { + @Override public void run() { mState = State.READY; prepareDialog(false, message, mError, mContext.getText(R.string.ok)); @@ -190,6 +196,7 @@ public class RecognitionView { final int speechEndPosition) { mUiHandler.post(new Runnable() { + @Override public void run() { mState = State.WORKING; prepareDialog(true, mContext.getText(R.string.voice_working), null, mContext @@ -309,6 +316,7 @@ public class RecognitionView { public void finish() { mUiHandler.post(new Runnable() { + @Override public void run() { mState = State.READY; exitWorking(); diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 5574a21de511c6e98080c13ac0f5a288d45c945d..73b3b19e3e4f2d6f43a6ae0d5213522ea8f4e2cc 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -39,7 +39,6 @@ import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; import android.text.method.LinkMovementMethod; -import android.text.method.MovementMethod; import android.text.style.ClickableSpan; import android.text.style.URLSpan; import android.view.LayoutInflater; @@ -120,6 +119,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (VOICE_INSTALLED) { mVoiceInput = new VoiceInput(context, this); mHints = new Hints(context, prefs, new Hints.Display() { + @Override public void showHint(int viewResource) { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE); @@ -519,6 +519,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { public void switchToRecognitionStatusView(final boolean configurationChanging) { final boolean configChanged = configurationChanging; mHandler.post(new Runnable() { + @Override public void run() { mContext.setCandidatesViewShown(false); mRecognizing = true; diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/voice/VoiceInput.java index 6d45ef97cc6e2484e34626b4d6feeb11b88837e5..d51d8694dae00ae13a363ad7da00cb4ec6571dd5 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInput.java +++ b/java/src/com/android/inputmethod/voice/VoiceInput.java @@ -86,6 +86,7 @@ public class VoiceInput implements OnClickListener { private static final String ALTERNATES_BUNDLE = "alternates_bundle"; // This is copied from the VoiceSearch app. + @SuppressWarnings("unused") private static final class AlternatesBundleKeys { public static final String ALTERNATES = "alternates"; public static final String CONFIDENCE = "confidence"; @@ -405,6 +406,7 @@ public class VoiceInput implements OnClickListener { /** * Handle the cancel button. */ + @Override public void onClick(View view) { switch(view.getId()) { case R.id.button: @@ -556,36 +558,43 @@ public class VoiceInput implements OnClickListener { int mSpeechStart; private boolean mEndpointed = false; + @Override public void onReadyForSpeech(Bundle noiseParams) { mRecognitionView.showListening(); } + @Override public void onBeginningOfSpeech() { mEndpointed = false; mSpeechStart = mWaveBuffer.size(); } + @Override public void onRmsChanged(float rmsdB) { mRecognitionView.updateVoiceMeter(rmsdB); } + @Override public void onBufferReceived(byte[] buf) { try { mWaveBuffer.write(buf); } catch (IOException e) {} } + @Override public void onEndOfSpeech() { mEndpointed = true; mState = WORKING; mRecognitionView.showWorking(mWaveBuffer, mSpeechStart, mWaveBuffer.size()); } + @Override public void onError(int errorType) { mState = ERROR; VoiceInput.this.onError(errorType, mEndpointed); } + @Override public void onResults(Bundle resultsBundle) { List<String> results = resultsBundle .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); @@ -638,10 +647,12 @@ public class VoiceInput implements OnClickListener { mRecognitionView.finish(); } + @Override public void onPartialResults(final Bundle partialResults) { // currently - do nothing } + @Override public void onEvent(int eventType, Bundle params) { // do nothing - reserved for events that might be added in the future } diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java index ec0ae649a8427d3317259a13dffee253fb47dec1..3e65434a23c82aaf4016ed51b317c85314635995 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java +++ b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java @@ -31,6 +31,7 @@ import android.content.Intent; * on on the VoiceSearch side. */ public class VoiceInputLogger { + @SuppressWarnings("unused") private static final String TAG = VoiceInputLogger.class.getSimpleName(); private static VoiceInputLogger sVoiceInputLogger; diff --git a/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java b/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java index 620f036db3bb16575861bfe5491cb03e297b70ec..869781f3d167aca134e333141779306d3a55c2a3 100644 --- a/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java +++ b/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java @@ -16,7 +16,7 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.latin.SwipeTracker.EventRingBuffer; +import com.android.inputmethod.keyboard.SwipeTracker.EventRingBuffer; import android.test.AndroidTestCase;