Add null analysis annotations to keyboard package
Change-Id: I6f020ece3c45d584d413e4265d6d3fbdf1ea8bd8
This commit is contained in:
parent
bb4075bc93
commit
9d5d01a543
17 changed files with 219 additions and 100 deletions
|
@ -43,6 +43,9 @@ import com.android.inputmethod.latin.common.StringUtils;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for describing the position and characteristics of a single key in the keyboard.
|
* Class for describing the position and characteristics of a single key in the keyboard.
|
||||||
*/
|
*/
|
||||||
|
@ -113,9 +116,11 @@ public class Key implements Comparable<Key> {
|
||||||
/** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */
|
/** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */
|
||||||
private final int mY;
|
private final int mY;
|
||||||
/** Hit bounding box of the key */
|
/** Hit bounding box of the key */
|
||||||
|
@Nonnull
|
||||||
private final Rect mHitBox = new Rect();
|
private final Rect mHitBox = new Rect();
|
||||||
|
|
||||||
/** More keys. It is guaranteed that this is null or an array of one or more elements */
|
/** More keys. It is guaranteed that this is null or an array of one or more elements */
|
||||||
|
@Nullable
|
||||||
private final MoreKeySpec[] mMoreKeys;
|
private final MoreKeySpec[] mMoreKeys;
|
||||||
/** More keys column number and flags */
|
/** More keys column number and flags */
|
||||||
private final int mMoreKeysColumnAndFlags;
|
private final int mMoreKeysColumnAndFlags;
|
||||||
|
@ -158,8 +163,9 @@ public class Key implements Comparable<Key> {
|
||||||
private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
|
private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
|
||||||
private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
|
private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private final KeyVisualAttributes mKeyVisualAttributes;
|
private final KeyVisualAttributes mKeyVisualAttributes;
|
||||||
|
@Nullable
|
||||||
private final OptionalAttributes mOptionalAttributes;
|
private final OptionalAttributes mOptionalAttributes;
|
||||||
|
|
||||||
private static final class OptionalAttributes {
|
private static final class OptionalAttributes {
|
||||||
|
@ -181,6 +187,7 @@ public class Key implements Comparable<Key> {
|
||||||
mVisualInsetsRight = visualInsetsRight;
|
mVisualInsetsRight = visualInsetsRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static OptionalAttributes newInstance(final String outputText, final int altCode,
|
public static OptionalAttributes newInstance(final String outputText, final int altCode,
|
||||||
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
|
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
|
||||||
if (outputText == null && altCode == CODE_UNSPECIFIED
|
if (outputText == null && altCode == CODE_UNSPECIFIED
|
||||||
|
@ -204,10 +211,10 @@ public class Key implements Comparable<Key> {
|
||||||
* Constructor for a key on <code>MoreKeyKeyboard</code>, on <code>MoreSuggestions</code>,
|
* Constructor for a key on <code>MoreKeyKeyboard</code>, on <code>MoreSuggestions</code>,
|
||||||
* and in a <GridRows/>.
|
* and in a <GridRows/>.
|
||||||
*/
|
*/
|
||||||
public Key(final String label, final int iconId, final int code, final String outputText,
|
public Key(@Nullable final String label, final int iconId, final int code,
|
||||||
final String hintLabel, final int labelFlags, final int backgroundType, final int x,
|
@Nullable final String outputText, @Nullable final String hintLabel,
|
||||||
final int y, final int width, final int height, final int horizontalGap,
|
final int labelFlags, final int backgroundType, final int x, final int y,
|
||||||
final int verticalGap) {
|
final int width, final int height, final int horizontalGap, final int verticalGap) {
|
||||||
mWidth = width - horizontalGap;
|
mWidth = width - horizontalGap;
|
||||||
mHeight = height - verticalGap;
|
mHeight = height - verticalGap;
|
||||||
mHorizontalGap = horizontalGap;
|
mHorizontalGap = horizontalGap;
|
||||||
|
@ -245,8 +252,9 @@ public class Key implements Comparable<Key> {
|
||||||
* @param row the row that this key belongs to. row's x-coordinate will be the right edge of
|
* @param row the row that this key belongs to. row's x-coordinate will be the right edge of
|
||||||
* this key.
|
* this key.
|
||||||
*/
|
*/
|
||||||
public Key(final String keySpec, final TypedArray keyAttr, final KeyStyle style,
|
public Key(@Nullable final String keySpec, @Nonnull final TypedArray keyAttr,
|
||||||
final KeyboardParams params, final KeyboardRow row) {
|
@Nonnull final KeyStyle style, @Nonnull final KeyboardParams params,
|
||||||
|
@Nonnull final KeyboardRow row) {
|
||||||
mHorizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
|
mHorizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
|
||||||
mVerticalGap = params.mVerticalGap;
|
mVerticalGap = params.mVerticalGap;
|
||||||
|
|
||||||
|
@ -403,11 +411,11 @@ public class Key implements Comparable<Key> {
|
||||||
*
|
*
|
||||||
* @param key the original key.
|
* @param key the original key.
|
||||||
*/
|
*/
|
||||||
protected Key(final Key key) {
|
protected Key(@Nonnull final Key key) {
|
||||||
this(key, key.mMoreKeys);
|
this(key, key.mMoreKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Key(final Key key, final MoreKeySpec[] moreKeys) {
|
private Key(@Nonnull final Key key, @Nullable final MoreKeySpec[] moreKeys) {
|
||||||
// Final attributes.
|
// Final attributes.
|
||||||
mCode = key.mCode;
|
mCode = key.mCode;
|
||||||
mLabel = key.mLabel;
|
mLabel = key.mLabel;
|
||||||
|
@ -433,8 +441,9 @@ public class Key implements Comparable<Key> {
|
||||||
mEnabled = key.mEnabled;
|
mEnabled = key.mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Key removeRedundantMoreKeys(final Key key,
|
@Nonnull
|
||||||
final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
|
public static Key removeRedundantMoreKeys(@Nonnull final Key key,
|
||||||
|
@Nonnull final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
|
||||||
final MoreKeySpec[] moreKeys = key.getMoreKeys();
|
final MoreKeySpec[] moreKeys = key.getMoreKeys();
|
||||||
final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys(
|
final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys(
|
||||||
moreKeys, lettersOnBaseLayout);
|
moreKeys, lettersOnBaseLayout);
|
||||||
|
@ -554,14 +563,17 @@ public class Key implements Comparable<Key> {
|
||||||
return mCode;
|
return mCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return mLabel;
|
return mLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getHintLabel() {
|
public String getHintLabel() {
|
||||||
return mHintLabel;
|
return mHintLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public MoreKeySpec[] getMoreKeys() {
|
public MoreKeySpec[] getMoreKeys() {
|
||||||
return mMoreKeys;
|
return mMoreKeys;
|
||||||
}
|
}
|
||||||
|
@ -620,6 +632,7 @@ public class Key implements Comparable<Key> {
|
||||||
return mKeyVisualAttributes;
|
return mKeyVisualAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public final Typeface selectTypeface(final KeyDrawParams params) {
|
public final Typeface selectTypeface(final KeyDrawParams params) {
|
||||||
switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) {
|
switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) {
|
||||||
case LABEL_FLAGS_FONT_NORMAL:
|
case LABEL_FLAGS_FONT_NORMAL:
|
||||||
|
@ -696,6 +709,7 @@ public class Key implements Comparable<Key> {
|
||||||
return params.mLetterSize;
|
return params.mLetterSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public Typeface selectPreviewTypeface(final KeyDrawParams params) {
|
public Typeface selectPreviewTypeface(final KeyDrawParams params) {
|
||||||
if (previewHasLetterSize()) {
|
if (previewHasLetterSize()) {
|
||||||
return selectTypeface(params);
|
return selectTypeface(params);
|
||||||
|
@ -780,6 +794,7 @@ public class Key implements Comparable<Key> {
|
||||||
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0;
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public final String getOutputText() {
|
public final String getOutputText() {
|
||||||
final OptionalAttributes attrs = mOptionalAttributes;
|
final OptionalAttributes attrs = mOptionalAttributes;
|
||||||
return (attrs != null) ? attrs.mOutputText : null;
|
return (attrs != null) ? attrs.mOutputText : null;
|
||||||
|
@ -794,6 +809,7 @@ public class Key implements Comparable<Key> {
|
||||||
return mIconId;
|
return mIconId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
|
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
|
||||||
final OptionalAttributes attrs = mOptionalAttributes;
|
final OptionalAttributes attrs = mOptionalAttributes;
|
||||||
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
|
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
|
||||||
|
@ -805,6 +821,7 @@ public class Key implements Comparable<Key> {
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) {
|
public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) {
|
||||||
return iconSet.getIconDrawable(getIconId());
|
return iconSet.getIconDrawable(getIconId());
|
||||||
}
|
}
|
||||||
|
@ -897,6 +914,7 @@ public class Key implements Comparable<Key> {
|
||||||
mEnabled = enabled;
|
mEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public Rect getHitBox() {
|
public Rect getHitBox() {
|
||||||
return mHitBox;
|
return mHitBox;
|
||||||
}
|
}
|
||||||
|
@ -968,8 +986,10 @@ public class Key implements Comparable<Key> {
|
||||||
* @return the background drawable of the key.
|
* @return the background drawable of the key.
|
||||||
* @see android.graphics.drawable.StateListDrawable#setState(int[])
|
* @see android.graphics.drawable.StateListDrawable#setState(int[])
|
||||||
*/
|
*/
|
||||||
public final Drawable selectBackgroundDrawable(final Drawable keyBackground,
|
@Nonnull
|
||||||
final Drawable functionalKeyBackground, final Drawable spacebarBackground) {
|
public final Drawable selectBackgroundDrawable(@Nonnull final Drawable keyBackground,
|
||||||
|
@Nonnull final Drawable functionalKeyBackground,
|
||||||
|
@Nonnull final Drawable spacebarBackground) {
|
||||||
final Drawable background;
|
final Drawable background;
|
||||||
if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
|
if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
|
||||||
background = functionalKeyBackground;
|
background = functionalKeyBackground;
|
||||||
|
|
|
@ -28,6 +28,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
|
* Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
|
||||||
* consists of rows of keys.
|
* consists of rows of keys.
|
||||||
|
@ -47,6 +50,7 @@ import java.util.List;
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class Keyboard {
|
public class Keyboard {
|
||||||
|
@Nonnull
|
||||||
public final KeyboardId mId;
|
public final KeyboardId mId;
|
||||||
public final int mThemeId;
|
public final int mThemeId;
|
||||||
|
|
||||||
|
@ -78,17 +82,22 @@ public class Keyboard {
|
||||||
public final int mMaxMoreKeysKeyboardColumn;
|
public final int mMaxMoreKeysKeyboardColumn;
|
||||||
|
|
||||||
/** List of keys in this keyboard */
|
/** List of keys in this keyboard */
|
||||||
|
@Nonnull
|
||||||
private final List<Key> mSortedKeys;
|
private final List<Key> mSortedKeys;
|
||||||
|
@Nonnull
|
||||||
public final List<Key> mShiftKeys;
|
public final List<Key> mShiftKeys;
|
||||||
|
@Nonnull
|
||||||
public final List<Key> mAltCodeKeysWhileTyping;
|
public final List<Key> mAltCodeKeysWhileTyping;
|
||||||
|
@Nonnull
|
||||||
public final KeyboardIconsSet mIconsSet;
|
public final KeyboardIconsSet mIconsSet;
|
||||||
|
|
||||||
private final SparseArray<Key> mKeyCache = new SparseArray<>();
|
private final SparseArray<Key> mKeyCache = new SparseArray<>();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private final ProximityInfo mProximityInfo;
|
private final ProximityInfo mProximityInfo;
|
||||||
private final boolean mProximityCharsCorrectionEnabled;
|
private final boolean mProximityCharsCorrectionEnabled;
|
||||||
|
|
||||||
public Keyboard(final KeyboardParams params) {
|
public Keyboard(@Nonnull final KeyboardParams params) {
|
||||||
mId = params.mId;
|
mId = params.mId;
|
||||||
mThemeId = params.mThemeId;
|
mThemeId = params.mThemeId;
|
||||||
mOccupiedHeight = params.mOccupiedHeight;
|
mOccupiedHeight = params.mOccupiedHeight;
|
||||||
|
@ -114,7 +123,7 @@ public class Keyboard {
|
||||||
mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled;
|
mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Keyboard(final Keyboard keyboard) {
|
protected Keyboard(@Nonnull final Keyboard keyboard) {
|
||||||
mId = keyboard.mId;
|
mId = keyboard.mId;
|
||||||
mThemeId = keyboard.mThemeId;
|
mThemeId = keyboard.mThemeId;
|
||||||
mOccupiedHeight = keyboard.mOccupiedHeight;
|
mOccupiedHeight = keyboard.mOccupiedHeight;
|
||||||
|
@ -150,6 +159,7 @@ public class Keyboard {
|
||||||
return canAssumeNativeHasProximityCharsInfoOfAllKeys || Character.isLetter(code);
|
return canAssumeNativeHasProximityCharsInfoOfAllKeys || Character.isLetter(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public ProximityInfo getProximityInfo() {
|
public ProximityInfo getProximityInfo() {
|
||||||
return mProximityInfo;
|
return mProximityInfo;
|
||||||
}
|
}
|
||||||
|
@ -160,10 +170,12 @@ public class Keyboard {
|
||||||
* The list may contain {@link Key.Spacer} object as well.
|
* The list may contain {@link Key.Spacer} object as well.
|
||||||
* @return the sorted unmodifiable list of {@link Key}s of this keyboard.
|
* @return the sorted unmodifiable list of {@link Key}s of this keyboard.
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public List<Key> getSortedKeys() {
|
public List<Key> getSortedKeys() {
|
||||||
return mSortedKeys;
|
return mSortedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Key getKey(final int code) {
|
public Key getKey(final int code) {
|
||||||
if (code == Constants.CODE_UNSPECIFIED) {
|
if (code == Constants.CODE_UNSPECIFIED) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -185,7 +197,7 @@ public class Keyboard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasKey(final Key aKey) {
|
public boolean hasKey(@Nonnull final Key aKey) {
|
||||||
if (mKeyCache.indexOfValue(aKey) >= 0) {
|
if (mKeyCache.indexOfValue(aKey) >= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +223,7 @@ public class Keyboard {
|
||||||
* @return the list of the nearest keys to the given point. If the given
|
* @return the list of the nearest keys to the given point. If the given
|
||||||
* point is out of range, then an array of size zero is returned.
|
* point is out of range, then an array of size zero is returned.
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public List<Key> getNearestKeys(final int x, final int y) {
|
public List<Key> getNearestKeys(final int x, final int y) {
|
||||||
// Avoid dead pixels at edges of the keyboard
|
// Avoid dead pixels at edges of the keyboard
|
||||||
final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1));
|
final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1));
|
||||||
|
@ -218,7 +231,8 @@ public class Keyboard {
|
||||||
return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
|
return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getCoordinates(final int[] codePoints) {
|
@Nonnull
|
||||||
|
public int[] getCoordinates(@Nonnull final int[] codePoints) {
|
||||||
final int length = codePoints.length;
|
final int length = codePoints.length;
|
||||||
final int[] coordinates = CoordinateUtils.newCoordinateArray(length);
|
final int[] coordinates = CoordinateUtils.newCoordinateArray(length);
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ public final class KeyboardLayoutSet {
|
||||||
private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_";
|
private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
@Nonnull
|
||||||
private final Params mParams;
|
private final Params mParams;
|
||||||
|
|
||||||
// How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and
|
// How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and
|
||||||
|
@ -84,6 +85,7 @@ public final class KeyboardLayoutSet {
|
||||||
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
|
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
|
||||||
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
|
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
|
@Nonnull
|
||||||
private static final KeysCache sKeysCache = new KeysCache();
|
private static final KeysCache sKeysCache = new KeysCache();
|
||||||
private final static HashMap<InputMethodSubtype, Integer> sScriptIdsForSubtypes =
|
private final static HashMap<InputMethodSubtype, Integer> sScriptIdsForSubtypes =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
|
@ -145,7 +147,8 @@ public final class KeyboardLayoutSet {
|
||||||
sKeysCache.clear();
|
sKeysCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getScriptId(final Resources resources, final InputMethodSubtype subtype) {
|
public static int getScriptId(final Resources resources,
|
||||||
|
@Nonnull final InputMethodSubtype subtype) {
|
||||||
final Integer value = sScriptIdsForSubtypes.get(subtype);
|
final Integer value = sScriptIdsForSubtypes.get(subtype);
|
||||||
if (null == value) {
|
if (null == value) {
|
||||||
final int scriptId = Builder.readScriptId(resources, subtype);
|
final int scriptId = Builder.readScriptId(resources, subtype);
|
||||||
|
@ -155,11 +158,12 @@ public final class KeyboardLayoutSet {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardLayoutSet(final Context context, final Params params) {
|
KeyboardLayoutSet(final Context context, @Nonnull final Params params) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mParams = params;
|
mParams = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
|
public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
|
||||||
final int keyboardLayoutSetElementId;
|
final int keyboardLayoutSetElementId;
|
||||||
switch (mParams.mMode) {
|
switch (mParams.mMode) {
|
||||||
|
@ -203,6 +207,7 @@ public final class KeyboardLayoutSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) {
|
private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) {
|
||||||
final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
|
final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
|
||||||
final Keyboard cachedKeyboard = (ref == null) ? null : ref.get();
|
final Keyboard cachedKeyboard = (ref == null) ? null : ref.get();
|
||||||
|
|
|
@ -103,7 +103,8 @@ public class KeyboardView extends View {
|
||||||
// TODO: Consider having a dummy keyboard object to make this @Nonnull
|
// TODO: Consider having a dummy keyboard object to make this @Nonnull
|
||||||
@Nullable
|
@Nullable
|
||||||
private Keyboard mKeyboard;
|
private Keyboard mKeyboard;
|
||||||
protected final KeyDrawParams mKeyDrawParams = new KeyDrawParams();
|
@Nonnull
|
||||||
|
private final KeyDrawParams mKeyDrawParams = new KeyDrawParams();
|
||||||
|
|
||||||
// Drawing
|
// Drawing
|
||||||
/** True if all keys should be drawn */
|
/** True if all keys should be drawn */
|
||||||
|
@ -120,6 +121,7 @@ public class KeyboardView extends View {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final Paint mPaint = new Paint();
|
private final Paint mPaint = new Paint();
|
||||||
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
|
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
|
||||||
|
|
||||||
public KeyboardView(final Context context, final AttributeSet attrs) {
|
public KeyboardView(final Context context, final AttributeSet attrs) {
|
||||||
this(context, attrs, R.attr.keyboardViewStyle);
|
this(context, attrs, R.attr.keyboardViewStyle);
|
||||||
}
|
}
|
||||||
|
@ -210,6 +212,11 @@ public class KeyboardView extends View {
|
||||||
return mVerticalCorrection;
|
return mVerticalCorrection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
protected KeyDrawParams getKeyDrawParams() {
|
||||||
|
return mKeyDrawParams;
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateKeyDrawParams(final int keyHeight) {
|
protected void updateKeyDrawParams(final int keyHeight) {
|
||||||
mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
|
mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -484,7 +484,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
|
||||||
|
|
||||||
locatePreviewPlacerView();
|
locatePreviewPlacerView();
|
||||||
getLocationInWindow(mOriginCoords);
|
getLocationInWindow(mOriginCoords);
|
||||||
mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, mKeyDrawParams,
|
mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, getKeyDrawParams(),
|
||||||
getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
|
getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.common.StringUtils;
|
import com.android.inputmethod.latin.common.StringUtils;
|
||||||
import com.android.inputmethod.latin.utils.TypefaceUtils;
|
import com.android.inputmethod.latin.utils.TypefaceUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public final class MoreKeysKeyboard extends Keyboard {
|
public final class MoreKeysKeyboard extends Keyboard {
|
||||||
private final int mDefaultKeyCoordX;
|
private final int mDefaultKeyCoordX;
|
||||||
|
|
||||||
|
@ -328,6 +330,7 @@ public final class MoreKeysKeyboard extends Keyboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nonnull
|
||||||
public MoreKeysKeyboard build() {
|
public MoreKeysKeyboard build() {
|
||||||
final MoreKeysKeyboardParams params = mParams;
|
final MoreKeysKeyboardParams params = mParams;
|
||||||
final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags();
|
final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags();
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ProximityInfo {
|
public class ProximityInfo {
|
||||||
private static final String TAG = ProximityInfo.class.getSimpleName();
|
private static final String TAG = ProximityInfo.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
@ -36,6 +38,7 @@ public class ProximityInfo {
|
||||||
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
|
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
|
||||||
/** Number of key widths from current touch point to search for nearest keys. */
|
/** Number of key widths from current touch point to search for nearest keys. */
|
||||||
private static final float SEARCH_DISTANCE = 1.2f;
|
private static final float SEARCH_DISTANCE = 1.2f;
|
||||||
|
@Nonnull
|
||||||
private static final List<Key> EMPTY_KEY_LIST = Collections.emptyList();
|
private static final List<Key> EMPTY_KEY_LIST = Collections.emptyList();
|
||||||
private static final float DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS = 0.15f;
|
private static final float DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS = 0.15f;
|
||||||
|
|
||||||
|
@ -49,13 +52,16 @@ public class ProximityInfo {
|
||||||
private final int mKeyboardHeight;
|
private final int mKeyboardHeight;
|
||||||
private final int mMostCommonKeyWidth;
|
private final int mMostCommonKeyWidth;
|
||||||
private final int mMostCommonKeyHeight;
|
private final int mMostCommonKeyHeight;
|
||||||
|
@Nonnull
|
||||||
private final List<Key> mSortedKeys;
|
private final List<Key> mSortedKeys;
|
||||||
|
@Nonnull
|
||||||
private final List<Key>[] mGridNeighbors;
|
private final List<Key>[] mGridNeighbors;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
ProximityInfo(final int gridWidth, final int gridHeight, final int minWidth, final int height,
|
ProximityInfo(final int gridWidth, final int gridHeight, final int minWidth, final int height,
|
||||||
final int mostCommonKeyWidth, final int mostCommonKeyHeight, final List<Key> sortedKeys,
|
final int mostCommonKeyWidth, final int mostCommonKeyHeight,
|
||||||
final TouchPositionCorrection touchPositionCorrection) {
|
@Nonnull final List<Key> sortedKeys,
|
||||||
|
@Nonnull final TouchPositionCorrection touchPositionCorrection) {
|
||||||
mGridWidth = gridWidth;
|
mGridWidth = gridWidth;
|
||||||
mGridHeight = gridHeight;
|
mGridHeight = gridHeight;
|
||||||
mGridSize = mGridWidth * mGridHeight;
|
mGridSize = mGridWidth * mGridHeight;
|
||||||
|
@ -104,7 +110,8 @@ public class ProximityInfo {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long createNativeProximityInfo(final TouchPositionCorrection touchPositionCorrection) {
|
private long createNativeProximityInfo(
|
||||||
|
@Nonnull final TouchPositionCorrection touchPositionCorrection) {
|
||||||
final List<Key>[] gridNeighborKeys = mGridNeighbors;
|
final List<Key>[] gridNeighborKeys = mGridNeighbors;
|
||||||
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
||||||
|
@ -163,7 +170,7 @@ public class ProximityInfo {
|
||||||
infoIndex++;
|
infoIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
|
if (touchPositionCorrection.isValid()) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "touchPositionCorrection: ON");
|
Log.d(TAG, "touchPositionCorrection: ON");
|
||||||
}
|
}
|
||||||
|
@ -385,10 +392,8 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public List<Key> getNearestKeys(final int x, final int y) {
|
public List<Key> getNearestKeys(final int x, final int y) {
|
||||||
if (mGridNeighbors == null) {
|
|
||||||
return EMPTY_KEY_LIST;
|
|
||||||
}
|
|
||||||
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
|
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
|
||||||
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
|
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
|
||||||
if (index < mGridSize) {
|
if (index < mGridSize) {
|
||||||
|
|
|
@ -20,8 +20,12 @@ import android.graphics.Typeface;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class KeyDrawParams {
|
public final class KeyDrawParams {
|
||||||
public Typeface mTypeface;
|
@Nonnull
|
||||||
|
public Typeface mTypeface = Typeface.DEFAULT;
|
||||||
|
|
||||||
public int mLetterSize;
|
public int mLetterSize;
|
||||||
public int mLabelSize;
|
public int mLabelSize;
|
||||||
|
@ -49,7 +53,7 @@ public final class KeyDrawParams {
|
||||||
|
|
||||||
public KeyDrawParams() {}
|
public KeyDrawParams() {}
|
||||||
|
|
||||||
private KeyDrawParams(final KeyDrawParams copyFrom) {
|
private KeyDrawParams(@Nonnull final KeyDrawParams copyFrom) {
|
||||||
mTypeface = copyFrom.mTypeface;
|
mTypeface = copyFrom.mTypeface;
|
||||||
|
|
||||||
mLetterSize = copyFrom.mLetterSize;
|
mLetterSize = copyFrom.mLetterSize;
|
||||||
|
@ -77,7 +81,7 @@ public final class KeyDrawParams {
|
||||||
mAnimAlpha = copyFrom.mAnimAlpha;
|
mAnimAlpha = copyFrom.mAnimAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateParams(final int keyHeight, final KeyVisualAttributes attr) {
|
public void updateParams(final int keyHeight, @Nullable final KeyVisualAttributes attr) {
|
||||||
if (attr == null) {
|
if (attr == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +121,9 @@ public final class KeyDrawParams {
|
||||||
attr.mHintLabelOffCenterRatio, mHintLabelOffCenterRatio);
|
attr.mHintLabelOffCenterRatio, mHintLabelOffCenterRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public KeyDrawParams mayCloneAndUpdateParams(final int keyHeight,
|
public KeyDrawParams mayCloneAndUpdateParams(final int keyHeight,
|
||||||
final KeyVisualAttributes attr) {
|
@Nullable final KeyVisualAttributes attr) {
|
||||||
if (attr == null) {
|
if (attr == null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ import static com.android.inputmethod.latin.common.Constants.CODE_UNSPECIFIED;
|
||||||
import com.android.inputmethod.latin.common.Constants;
|
import com.android.inputmethod.latin.common.Constants;
|
||||||
import com.android.inputmethod.latin.common.StringUtils;
|
import com.android.inputmethod.latin.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The string parser of the key specification.
|
* The string parser of the key specification.
|
||||||
*
|
*
|
||||||
|
@ -53,11 +56,11 @@ public final class KeySpecParser {
|
||||||
// Intentional empty constructor for utility class.
|
// Intentional empty constructor for utility class.
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasIcon(final String keySpec) {
|
private static boolean hasIcon(@Nonnull final String keySpec) {
|
||||||
return keySpec.startsWith(KeyboardIconsSet.PREFIX_ICON);
|
return keySpec.startsWith(KeyboardIconsSet.PREFIX_ICON);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasCode(final String keySpec, final int labelEnd) {
|
private static boolean hasCode(@Nonnull final String keySpec, final int labelEnd) {
|
||||||
if (labelEnd <= 0 || labelEnd + 1 >= keySpec.length()) {
|
if (labelEnd <= 0 || labelEnd + 1 >= keySpec.length()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +75,8 @@ public final class KeySpecParser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String parseEscape(final String text) {
|
@Nonnull
|
||||||
|
private static String parseEscape(@Nonnull final String text) {
|
||||||
if (text.indexOf(BACKSLASH) < 0) {
|
if (text.indexOf(BACKSLASH) < 0) {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +95,7 @@ public final class KeySpecParser {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int indexOfLabelEnd(final String keySpec) {
|
private static int indexOfLabelEnd(@Nonnull final String keySpec) {
|
||||||
final int length = keySpec.length();
|
final int length = keySpec.length();
|
||||||
if (keySpec.indexOf(BACKSLASH) < 0) {
|
if (keySpec.indexOf(BACKSLASH) < 0) {
|
||||||
final int labelEnd = keySpec.indexOf(VERTICAL_BAR);
|
final int labelEnd = keySpec.indexOf(VERTICAL_BAR);
|
||||||
|
@ -116,22 +120,25 @@ public final class KeySpecParser {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getBeforeLabelEnd(final String keySpec, final int labelEnd) {
|
@Nonnull
|
||||||
|
private static String getBeforeLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||||
return (labelEnd < 0) ? keySpec : keySpec.substring(0, labelEnd);
|
return (labelEnd < 0) ? keySpec : keySpec.substring(0, labelEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getAfterLabelEnd(final String keySpec, final int labelEnd) {
|
@Nonnull
|
||||||
|
private static String getAfterLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||||
return keySpec.substring(labelEnd + /* VERTICAL_BAR */1);
|
return keySpec.substring(labelEnd + /* VERTICAL_BAR */1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkDoubleLabelEnd(final String keySpec, final int labelEnd) {
|
private static void checkDoubleLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||||
if (indexOfLabelEnd(getAfterLabelEnd(keySpec, labelEnd)) < 0) {
|
if (indexOfLabelEnd(getAfterLabelEnd(keySpec, labelEnd)) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new KeySpecParserError("Multiple " + VERTICAL_BAR + ": " + keySpec);
|
throw new KeySpecParserError("Multiple " + VERTICAL_BAR + ": " + keySpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLabel(final String keySpec) {
|
@Nullable
|
||||||
|
public static String getLabel(@Nullable final String keySpec) {
|
||||||
if (keySpec == null) {
|
if (keySpec == null) {
|
||||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||||
return null;
|
return null;
|
||||||
|
@ -147,7 +154,8 @@ public final class KeySpecParser {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getOutputTextInternal(final String keySpec, final int labelEnd) {
|
@Nullable
|
||||||
|
private static String getOutputTextInternal(@Nonnull final String keySpec, final int labelEnd) {
|
||||||
if (labelEnd <= 0) {
|
if (labelEnd <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +163,8 @@ public final class KeySpecParser {
|
||||||
return parseEscape(getAfterLabelEnd(keySpec, labelEnd));
|
return parseEscape(getAfterLabelEnd(keySpec, labelEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getOutputText(final String keySpec) {
|
@Nullable
|
||||||
|
public static String getOutputText(@Nullable final String keySpec) {
|
||||||
if (keySpec == null) {
|
if (keySpec == null) {
|
||||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||||
return null;
|
return null;
|
||||||
|
@ -184,7 +193,7 @@ public final class KeySpecParser {
|
||||||
return (StringUtils.codePointCount(label) == 1) ? null : label;
|
return (StringUtils.codePointCount(label) == 1) ? null : label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCode(final String keySpec) {
|
public static int getCode(@Nullable final String keySpec) {
|
||||||
if (keySpec == null) {
|
if (keySpec == null) {
|
||||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||||
return CODE_UNSPECIFIED;
|
return CODE_UNSPECIFIED;
|
||||||
|
@ -211,7 +220,7 @@ public final class KeySpecParser {
|
||||||
return (StringUtils.codePointCount(label) == 1) ? label.codePointAt(0) : CODE_OUTPUT_TEXT;
|
return (StringUtils.codePointCount(label) == 1) ? label.codePointAt(0) : CODE_OUTPUT_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int parseCode(final String text, final int defaultCode) {
|
public static int parseCode(@Nullable final String text, final int defaultCode) {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
return defaultCode;
|
return defaultCode;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +235,7 @@ public final class KeySpecParser {
|
||||||
return defaultCode;
|
return defaultCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getIconId(final String keySpec) {
|
public static int getIconId(@Nullable final String keySpec) {
|
||||||
if (keySpec == null) {
|
if (keySpec == null) {
|
||||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||||
return KeyboardIconsSet.ICON_UNDEFINED;
|
return KeyboardIconsSet.ICON_UNDEFINED;
|
||||||
|
|
|
@ -18,18 +18,22 @@ package com.android.inputmethod.keyboard.internal;
|
||||||
|
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public abstract class KeyStyle {
|
public abstract class KeyStyle {
|
||||||
private final KeyboardTextsSet mTextsSet;
|
private final KeyboardTextsSet mTextsSet;
|
||||||
|
|
||||||
public abstract String[] getStringArray(TypedArray a, int index);
|
public abstract @Nullable String[] getStringArray(TypedArray a, int index);
|
||||||
public abstract String getString(TypedArray a, int index);
|
public abstract @Nullable String getString(TypedArray a, int index);
|
||||||
public abstract int getInt(TypedArray a, int index, int defaultValue);
|
public abstract int getInt(TypedArray a, int index, int defaultValue);
|
||||||
public abstract int getFlags(TypedArray a, int index);
|
public abstract int getFlags(TypedArray a, int index);
|
||||||
|
|
||||||
protected KeyStyle(final KeyboardTextsSet textsSet) {
|
protected KeyStyle(@Nonnull final KeyboardTextsSet textsSet) {
|
||||||
mTextsSet = textsSet;
|
mTextsSet = textsSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
protected String parseString(final TypedArray a, final int index) {
|
protected String parseString(final TypedArray a, final int index) {
|
||||||
if (a.hasValue(index)) {
|
if (a.hasValue(index)) {
|
||||||
return mTextsSet.resolveTextReference(a.getString(index));
|
return mTextsSet.resolveTextReference(a.getString(index));
|
||||||
|
@ -37,6 +41,7 @@ public abstract class KeyStyle {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
protected String[] parseStringArray(final TypedArray a, final int index) {
|
protected String[] parseStringArray(final TypedArray a, final int index) {
|
||||||
if (a.hasValue(index)) {
|
if (a.hasValue(index)) {
|
||||||
final String text = mTextsSet.resolveTextReference(a.getString(index));
|
final String text = mTextsSet.resolveTextReference(a.getString(index));
|
||||||
|
|
|
@ -29,33 +29,42 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class KeyStylesSet {
|
public final class KeyStylesSet {
|
||||||
private static final String TAG = KeyStylesSet.class.getSimpleName();
|
private static final String TAG = KeyStylesSet.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private final HashMap<String, KeyStyle> mStyles = new HashMap<>();
|
private final HashMap<String, KeyStyle> mStyles = new HashMap<>();
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private final KeyboardTextsSet mTextsSet;
|
private final KeyboardTextsSet mTextsSet;
|
||||||
|
@Nonnull
|
||||||
private final KeyStyle mEmptyKeyStyle;
|
private final KeyStyle mEmptyKeyStyle;
|
||||||
|
@Nonnull
|
||||||
private static final String EMPTY_STYLE_NAME = "<empty>";
|
private static final String EMPTY_STYLE_NAME = "<empty>";
|
||||||
|
|
||||||
public KeyStylesSet(final KeyboardTextsSet textsSet) {
|
public KeyStylesSet(@Nonnull final KeyboardTextsSet textsSet) {
|
||||||
mTextsSet = textsSet;
|
mTextsSet = textsSet;
|
||||||
mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
|
mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
|
||||||
mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
|
mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class EmptyKeyStyle extends KeyStyle {
|
private static final class EmptyKeyStyle extends KeyStyle {
|
||||||
EmptyKeyStyle(final KeyboardTextsSet textsSet) {
|
EmptyKeyStyle(@Nonnull final KeyboardTextsSet textsSet) {
|
||||||
super(textsSet);
|
super(textsSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String[] getStringArray(final TypedArray a, final int index) {
|
public String[] getStringArray(final TypedArray a, final int index) {
|
||||||
return parseStringArray(a, index);
|
return parseStringArray(a, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getString(final TypedArray a, final int index) {
|
public String getString(final TypedArray a, final int index) {
|
||||||
return parseString(a, index);
|
return parseString(a, index);
|
||||||
}
|
}
|
||||||
|
@ -76,14 +85,16 @@ public final class KeyStylesSet {
|
||||||
private final String mParentStyleName;
|
private final String mParentStyleName;
|
||||||
private final SparseArray<Object> mStyleAttributes = new SparseArray<>();
|
private final SparseArray<Object> mStyleAttributes = new SparseArray<>();
|
||||||
|
|
||||||
public DeclaredKeyStyle(final String parentStyleName, final KeyboardTextsSet textsSet,
|
public DeclaredKeyStyle(@Nonnull final String parentStyleName,
|
||||||
final HashMap<String, KeyStyle> styles) {
|
@Nonnull final KeyboardTextsSet textsSet,
|
||||||
|
@Nonnull final HashMap<String, KeyStyle> styles) {
|
||||||
super(textsSet);
|
super(textsSet);
|
||||||
mParentStyleName = parentStyleName;
|
mParentStyleName = parentStyleName;
|
||||||
mStyles = styles;
|
mStyles = styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String[] getStringArray(final TypedArray a, final int index) {
|
public String[] getStringArray(final TypedArray a, final int index) {
|
||||||
if (a.hasValue(index)) {
|
if (a.hasValue(index)) {
|
||||||
return parseStringArray(a, index);
|
return parseStringArray(a, index);
|
||||||
|
@ -98,6 +109,7 @@ public final class KeyStylesSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getString(final TypedArray a, final int index) {
|
public String getString(final TypedArray a, final int index) {
|
||||||
if (a.hasValue(index)) {
|
if (a.hasValue(index)) {
|
||||||
return parseString(a, index);
|
return parseString(a, index);
|
||||||
|
@ -176,37 +188,43 @@ public final class KeyStylesSet {
|
||||||
public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
|
public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
|
||||||
final XmlPullParser parser) throws XmlPullParserException {
|
final XmlPullParser parser) throws XmlPullParserException {
|
||||||
final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
|
final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
|
||||||
|
if (styleName == null) {
|
||||||
|
throw new XmlParseUtils.ParseException(
|
||||||
|
KeyboardBuilder.TAG_KEY_STYLE + " has no styleName attribute", parser);
|
||||||
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, String.format("<%s styleName=%s />",
|
Log.d(TAG, String.format("<%s styleName=%s />",
|
||||||
KeyboardBuilder.TAG_KEY_STYLE, styleName));
|
KeyboardBuilder.TAG_KEY_STYLE, styleName));
|
||||||
if (mStyles.containsKey(styleName)) {
|
if (mStyles.containsKey(styleName)) {
|
||||||
Log.d(TAG, "key-style " + styleName + " is overridden at "
|
Log.d(TAG, KeyboardBuilder.TAG_KEY_STYLE + " " + styleName + " is overridden at "
|
||||||
+ parser.getPositionDescription());
|
+ parser.getPositionDescription());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String parentStyleName = EMPTY_STYLE_NAME;
|
final String parentStyleInAttr = keyStyleAttr.getString(
|
||||||
if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
|
R.styleable.Keyboard_KeyStyle_parentStyle);
|
||||||
parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
|
if (parentStyleInAttr != null && !mStyles.containsKey(parentStyleInAttr)) {
|
||||||
if (!mStyles.containsKey(parentStyleName)) {
|
throw new XmlParseUtils.ParseException(
|
||||||
throw new XmlParseUtils.ParseException(
|
"Unknown parentStyle " + parentStyleInAttr, parser);
|
||||||
"Unknown parentStyle " + parentStyleName, parser);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
final String parentStyleName = (parentStyleInAttr == null) ? EMPTY_STYLE_NAME
|
||||||
|
: parentStyleInAttr;
|
||||||
final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
|
final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
|
||||||
style.readKeyAttributes(keyAttrs);
|
style.readKeyAttributes(keyAttrs);
|
||||||
mStyles.put(styleName, style);
|
mStyles.put(styleName, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
|
public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
|
||||||
throws XmlParseUtils.ParseException {
|
throws XmlParseUtils.ParseException {
|
||||||
if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
|
final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
|
||||||
|
if (styleName == null) {
|
||||||
return mEmptyKeyStyle;
|
return mEmptyKeyStyle;
|
||||||
}
|
}
|
||||||
final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
|
final KeyStyle style = mStyles.get(styleName);
|
||||||
if (!mStyles.containsKey(styleName)) {
|
if (style == null) {
|
||||||
throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
|
throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
|
||||||
}
|
}
|
||||||
return mStyles.get(styleName);
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,11 @@ import android.util.SparseIntArray;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class KeyVisualAttributes {
|
public final class KeyVisualAttributes {
|
||||||
|
@Nullable
|
||||||
public final Typeface mTypeface;
|
public final Typeface mTypeface;
|
||||||
|
|
||||||
public final float mLetterRatio;
|
public final float mLetterRatio;
|
||||||
|
@ -81,7 +85,8 @@ public final class KeyVisualAttributes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeyVisualAttributes newInstance(final TypedArray keyAttr) {
|
@Nullable
|
||||||
|
public static KeyVisualAttributes newInstance(@Nonnull final TypedArray keyAttr) {
|
||||||
final int indexCount = keyAttr.getIndexCount();
|
final int indexCount = keyAttr.getIndexCount();
|
||||||
for (int i = 0; i < indexCount; i++) {
|
for (int i = 0; i < indexCount; i++) {
|
||||||
final int attrId = keyAttr.getIndex(i);
|
final int attrId = keyAttr.getIndex(i);
|
||||||
|
@ -93,7 +98,7 @@ public final class KeyVisualAttributes {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyVisualAttributes(final TypedArray keyAttr) {
|
private KeyVisualAttributes(@Nonnull final TypedArray keyAttr) {
|
||||||
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyTypeface)) {
|
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyTypeface)) {
|
||||||
mTypeface = Typeface.defaultFromStyle(
|
mTypeface = Typeface.defaultFromStyle(
|
||||||
keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL));
|
keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL));
|
||||||
|
|
|
@ -139,6 +139,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
|
private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
|
||||||
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
protected final KP mParams;
|
protected final KP mParams;
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
protected final Resources mResources;
|
protected final Resources mResources;
|
||||||
|
@ -149,7 +150,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
private boolean mTopEdge;
|
private boolean mTopEdge;
|
||||||
private Key mRightEdgeKey = null;
|
private Key mRightEdgeKey = null;
|
||||||
|
|
||||||
public KeyboardBuilder(final Context context, final KP params) {
|
public KeyboardBuilder(final Context context, @Nonnull final KP params) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
mResources = res;
|
mResources = res;
|
||||||
|
@ -194,6 +195,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
mParams.mProximityCharsCorrectionEnabled = enabled;
|
mParams.mProximityCharsCorrectionEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public Keyboard build() {
|
public Keyboard build() {
|
||||||
return new Keyboard(mParams);
|
return new Keyboard(mParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ import com.android.inputmethod.latin.R;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class KeyboardIconsSet {
|
public final class KeyboardIconsSet {
|
||||||
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
|
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
|
||||||
|
|
||||||
|
@ -127,6 +130,7 @@ public final class KeyboardIconsSet {
|
||||||
return iconId >= 0 && iconId < ICON_NAMES.length;
|
return iconId >= 0 && iconId < ICON_NAMES.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public static String getIconName(final int iconId) {
|
public static String getIconName(final int iconId) {
|
||||||
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
|
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
|
||||||
}
|
}
|
||||||
|
@ -147,6 +151,7 @@ public final class KeyboardIconsSet {
|
||||||
throw new RuntimeException("unknown icon name: " + name);
|
throw new RuntimeException("unknown icon name: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Drawable getIconDrawable(final int iconId) {
|
public Drawable getIconDrawable(final int iconId) {
|
||||||
if (isValidIconId(iconId)) {
|
if (isValidIconId(iconId)) {
|
||||||
return mIcons[iconId];
|
return mIcons[iconId];
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class KeyboardParams {
|
||||||
public int mLeftPadding;
|
public int mLeftPadding;
|
||||||
public int mRightPadding;
|
public int mRightPadding;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public KeyVisualAttributes mKeyVisualAttributes;
|
public KeyVisualAttributes mKeyVisualAttributes;
|
||||||
|
|
||||||
public int mDefaultRowHeight;
|
public int mDefaultRowHeight;
|
||||||
|
@ -63,14 +64,22 @@ public class KeyboardParams {
|
||||||
public int GRID_HEIGHT;
|
public int GRID_HEIGHT;
|
||||||
|
|
||||||
// Keys are sorted from top-left to bottom-right order.
|
// Keys are sorted from top-left to bottom-right order.
|
||||||
|
@Nonnull
|
||||||
public final SortedSet<Key> mSortedKeys = new TreeSet<>(ROW_COLUMN_COMPARATOR);
|
public final SortedSet<Key> mSortedKeys = new TreeSet<>(ROW_COLUMN_COMPARATOR);
|
||||||
|
@Nonnull
|
||||||
public final ArrayList<Key> mShiftKeys = new ArrayList<>();
|
public final ArrayList<Key> mShiftKeys = new ArrayList<>();
|
||||||
|
@Nonnull
|
||||||
public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<>();
|
public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<>();
|
||||||
|
@Nonnull
|
||||||
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
||||||
|
@Nonnull
|
||||||
public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
|
public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
|
||||||
|
@Nonnull
|
||||||
public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
|
public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
|
||||||
|
|
||||||
@Nullable public KeysCache mKeysCache;
|
// TODO: Make this @Nonnull
|
||||||
|
@Nullable
|
||||||
|
public KeysCache mKeysCache;
|
||||||
public boolean mAllowRedundantMoreKeys;
|
public boolean mAllowRedundantMoreKeys;
|
||||||
|
|
||||||
public int mMostCommonKeyHeight = 0;
|
public int mMostCommonKeyHeight = 0;
|
||||||
|
@ -78,6 +87,7 @@ public class KeyboardParams {
|
||||||
|
|
||||||
public boolean mProximityCharsCorrectionEnabled;
|
public boolean mProximityCharsCorrectionEnabled;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public final TouchPositionCorrection mTouchPositionCorrection =
|
public final TouchPositionCorrection mTouchPositionCorrection =
|
||||||
new TouchPositionCorrection();
|
new TouchPositionCorrection();
|
||||||
|
|
||||||
|
@ -100,7 +110,9 @@ public class KeyboardParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAddKey(@Nonnull final Key newKey) {
|
public void onAddKey(@Nonnull final Key newKey) {
|
||||||
final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
|
// To avoid possible null pointer access.
|
||||||
|
final KeysCache keysCache = mKeysCache;
|
||||||
|
final Key key = (keysCache != null) ? keysCache.get(newKey) : newKey;
|
||||||
final boolean isSpacer = key.isSpacer();
|
final boolean isSpacer = key.isSpacer();
|
||||||
if (isSpacer && key.getWidth() == 0) {
|
if (isSpacer && key.getWidth() == 0) {
|
||||||
// Ignore zero width {@link Spacer}.
|
// Ignore zero width {@link Spacer}.
|
||||||
|
@ -128,12 +140,14 @@ public class KeyboardParams {
|
||||||
for (final Key key : mSortedKeys) {
|
for (final Key key : mSortedKeys) {
|
||||||
lettersOnBaseLayout.addLetter(key);
|
lettersOnBaseLayout.addLetter(key);
|
||||||
}
|
}
|
||||||
|
// To avoid possible null pointer access.
|
||||||
|
final KeysCache keysCache = mKeysCache;
|
||||||
final ArrayList<Key> allKeys = new ArrayList<>(mSortedKeys);
|
final ArrayList<Key> allKeys = new ArrayList<>(mSortedKeys);
|
||||||
mSortedKeys.clear();
|
mSortedKeys.clear();
|
||||||
for (final Key key : allKeys) {
|
for (final Key key : allKeys) {
|
||||||
final Key filteredKey = Key.removeRedundantMoreKeys(key, lettersOnBaseLayout);
|
final Key filteredKey = Key.removeRedundantMoreKeys(key, lettersOnBaseLayout);
|
||||||
if (mKeysCache != null) {
|
if (keysCache != null) {
|
||||||
mKeysCache.replace(key, filteredKey);
|
keysCache.replace(key, filteredKey);
|
||||||
}
|
}
|
||||||
mSortedKeys.add(filteredKey);
|
mSortedKeys.add(filteredKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.android.inputmethod.keyboard.Key;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// TODO: Rename more appropriate name.
|
||||||
public final class KeysCache {
|
public final class KeysCache {
|
||||||
private final HashMap<Key, Key> mMap = new HashMap<>();
|
private final HashMap<Key, Key> mMap = new HashMap<>();
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ public final class KeysCache {
|
||||||
mMap.clear();
|
mMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Rename more descriptive name.
|
||||||
public Key get(final Key key) {
|
public Key get(final Key key) {
|
||||||
final Key existingKey = mMap.get(key);
|
final Key existingKey = mMap.get(key);
|
||||||
if (existingKey != null) {
|
if (existingKey != null) {
|
||||||
|
@ -37,6 +39,7 @@ public final class KeysCache {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Rename more descriptive name.
|
||||||
public Key replace(final Key oldKey, final Key newKey) {
|
public Key replace(final Key oldKey, final Key newKey) {
|
||||||
if (oldKey.equals(newKey)) {
|
if (oldKey.equals(newKey)) {
|
||||||
return oldKey;
|
return oldKey;
|
||||||
|
|
|
@ -24,14 +24,13 @@ import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.latin.common.CollectionUtils;
|
import com.android.inputmethod.latin.common.CollectionUtils;
|
||||||
import com.android.inputmethod.latin.common.Constants;
|
import com.android.inputmethod.latin.common.Constants;
|
||||||
import com.android.inputmethod.latin.common.StringUtils;
|
import com.android.inputmethod.latin.common.StringUtils;
|
||||||
import com.android.inputmethod.latin.define.DebugFlags;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The more key specification object. The more keys are an array of {@link MoreKeySpec}.
|
* The more key specification object. The more keys are an array of {@link MoreKeySpec}.
|
||||||
|
@ -47,12 +46,15 @@ import javax.annotation.Nonnull;
|
||||||
// TODO: Should extend the key specification object.
|
// TODO: Should extend the key specification object.
|
||||||
public final class MoreKeySpec {
|
public final class MoreKeySpec {
|
||||||
public final int mCode;
|
public final int mCode;
|
||||||
|
@Nullable
|
||||||
public final String mLabel;
|
public final String mLabel;
|
||||||
|
@Nullable
|
||||||
public final String mOutputText;
|
public final String mOutputText;
|
||||||
public final int mIconId;
|
public final int mIconId;
|
||||||
|
|
||||||
public MoreKeySpec(final String moreKeySpec, boolean needsToUpperCase, final Locale locale) {
|
public MoreKeySpec(@Nonnull final String moreKeySpec, boolean needsToUpperCase,
|
||||||
if (TextUtils.isEmpty(moreKeySpec)) {
|
@Nonnull final Locale locale) {
|
||||||
|
if (moreKeySpec.isEmpty()) {
|
||||||
throw new KeySpecParser.KeySpecParserError("Empty more key spec");
|
throw new KeySpecParser.KeySpecParserError("Empty more key spec");
|
||||||
}
|
}
|
||||||
final String label = KeySpecParser.getLabel(moreKeySpec);
|
final String label = KeySpecParser.getLabel(moreKeySpec);
|
||||||
|
@ -76,7 +78,7 @@ public final class MoreKeySpec {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Key buildKey(final int x, final int y, final int labelFlags,
|
public Key buildKey(final int x, final int y, final int labelFlags,
|
||||||
final KeyboardParams params) {
|
@Nonnull final KeyboardParams params) {
|
||||||
return new Key(mLabel, mIconId, mCode, mOutputText, null /* hintLabel */, labelFlags,
|
return new Key(mLabel, mIconId, mCode, mOutputText, null /* hintLabel */, labelFlags,
|
||||||
Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultKeyWidth, params.mDefaultRowHeight,
|
Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultKeyWidth, params.mDefaultRowHeight,
|
||||||
params.mHorizontalGap, params.mVerticalGap);
|
params.mHorizontalGap, params.mVerticalGap);
|
||||||
|
@ -87,14 +89,18 @@ public final class MoreKeySpec {
|
||||||
int hashCode = 1;
|
int hashCode = 1;
|
||||||
hashCode = 31 + mCode;
|
hashCode = 31 + mCode;
|
||||||
hashCode = hashCode * 31 + mIconId;
|
hashCode = hashCode * 31 + mIconId;
|
||||||
hashCode = hashCode * 31 + (mLabel == null ? 0 : mLabel.hashCode());
|
final String label = mLabel;
|
||||||
hashCode = hashCode * 31 + (mOutputText == null ? 0 : mOutputText.hashCode());
|
hashCode = hashCode * 31 + (label == null ? 0 : label.hashCode());
|
||||||
|
final String outputText = mOutputText;
|
||||||
|
hashCode = hashCode * 31 + (outputText == null ? 0 : outputText.hashCode());
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (o instanceof MoreKeySpec) {
|
if (o instanceof MoreKeySpec) {
|
||||||
final MoreKeySpec other = (MoreKeySpec)o;
|
final MoreKeySpec other = (MoreKeySpec)o;
|
||||||
return mCode == other.mCode
|
return mCode == other.mCode
|
||||||
|
@ -121,7 +127,7 @@ public final class MoreKeySpec {
|
||||||
private final SparseIntArray mCodes = new SparseIntArray();
|
private final SparseIntArray mCodes = new SparseIntArray();
|
||||||
private final HashSet<String> mTexts = new HashSet<>();
|
private final HashSet<String> mTexts = new HashSet<>();
|
||||||
|
|
||||||
public void addLetter(final Key key) {
|
public void addLetter(@Nonnull final Key key) {
|
||||||
final int code = key.getCode();
|
final int code = key.getCode();
|
||||||
if (CharacterCompat.isAlphabetic(code)) {
|
if (CharacterCompat.isAlphabetic(code)) {
|
||||||
mCodes.put(code, 0);
|
mCodes.put(code, 0);
|
||||||
|
@ -130,7 +136,7 @@ public final class MoreKeySpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(final MoreKeySpec moreKey) {
|
public boolean contains(@Nonnull final MoreKeySpec moreKey) {
|
||||||
final int code = moreKey.mCode;
|
final int code = moreKey.mCode;
|
||||||
if (CharacterCompat.isAlphabetic(code) && mCodes.indexOfKey(code) >= 0) {
|
if (CharacterCompat.isAlphabetic(code) && mCodes.indexOfKey(code) >= 0) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -141,8 +147,9 @@ public final class MoreKeySpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MoreKeySpec[] removeRedundantMoreKeys(final MoreKeySpec[] moreKeys,
|
@Nullable
|
||||||
final LettersOnBaseLayout lettersOnBaseLayout) {
|
public static MoreKeySpec[] removeRedundantMoreKeys(@Nullable final MoreKeySpec[] moreKeys,
|
||||||
|
@Nonnull final LettersOnBaseLayout lettersOnBaseLayout) {
|
||||||
if (moreKeys == null) {
|
if (moreKeys == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +169,6 @@ public final class MoreKeySpec {
|
||||||
return filteredMoreKeys.toArray(new MoreKeySpec[size]);
|
return filteredMoreKeys.toArray(new MoreKeySpec[size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean DEBUG = DebugFlags.DEBUG_ENABLED;
|
|
||||||
// Constants for parsing.
|
// Constants for parsing.
|
||||||
private static final char COMMA = Constants.CODE_COMMA;
|
private static final char COMMA = Constants.CODE_COMMA;
|
||||||
private static final char BACKSLASH = Constants.CODE_BACKSLASH;
|
private static final char BACKSLASH = Constants.CODE_BACKSLASH;
|
||||||
|
@ -180,7 +186,8 @@ public final class MoreKeySpec {
|
||||||
* @return an array of key specification text. Null if the specified <code>text</code> is empty
|
* @return an array of key specification text. Null if the specified <code>text</code> is empty
|
||||||
* or has no key specifications.
|
* or has no key specifications.
|
||||||
*/
|
*/
|
||||||
public static String[] splitKeySpecs(final String text) {
|
@Nullable
|
||||||
|
public static String[] splitKeySpecs(@Nullable final String text) {
|
||||||
if (TextUtils.isEmpty(text)) {
|
if (TextUtils.isEmpty(text)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -222,9 +229,11 @@ public final class MoreKeySpec {
|
||||||
return list.toArray(new String[list.size()]);
|
return list.toArray(new String[list.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||||
|
|
||||||
private static String[] filterOutEmptyString(final String[] array) {
|
@Nonnull
|
||||||
|
private static String[] filterOutEmptyString(@Nullable final String[] array) {
|
||||||
if (array == null) {
|
if (array == null) {
|
||||||
return EMPTY_STRING_ARRAY;
|
return EMPTY_STRING_ARRAY;
|
||||||
}
|
}
|
||||||
|
@ -245,8 +254,8 @@ public final class MoreKeySpec {
|
||||||
return out.toArray(new String[out.size()]);
|
return out.toArray(new String[out.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] insertAdditionalMoreKeys(final String[] moreKeySpecs,
|
public static String[] insertAdditionalMoreKeys(@Nullable final String[] moreKeySpecs,
|
||||||
final String[] additionalMoreKeySpecs) {
|
@Nullable final String[] additionalMoreKeySpecs) {
|
||||||
final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
|
final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
|
||||||
final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
|
final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
|
||||||
final int moreKeysCount = moreKeys.length;
|
final int moreKeysCount = moreKeys.length;
|
||||||
|
@ -280,11 +289,6 @@ public final class MoreKeySpec {
|
||||||
if (additionalCount > 0 && additionalIndex == 0) {
|
if (additionalCount > 0 && additionalIndex == 0) {
|
||||||
// No '%' marker is found in more keys.
|
// No '%' marker is found in more keys.
|
||||||
// Insert all additional more keys to the head of more keys.
|
// Insert all additional more keys to the head of more keys.
|
||||||
if (DEBUG && out != null) {
|
|
||||||
throw new RuntimeException("Internal logic error:"
|
|
||||||
+ " moreKeys=" + Arrays.toString(moreKeys)
|
|
||||||
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
|
|
||||||
}
|
|
||||||
out = CollectionUtils.arrayAsList(additionalMoreKeys, additionalIndex, additionalCount);
|
out = CollectionUtils.arrayAsList(additionalMoreKeys, additionalIndex, additionalCount);
|
||||||
for (int i = 0; i < moreKeysCount; i++) {
|
for (int i = 0; i < moreKeysCount; i++) {
|
||||||
out.add(moreKeys[i]);
|
out.add(moreKeys[i]);
|
||||||
|
@ -292,11 +296,6 @@ public final class MoreKeySpec {
|
||||||
} else if (additionalIndex < additionalCount) {
|
} else if (additionalIndex < additionalCount) {
|
||||||
// The number of '%' markers are less than additional more keys.
|
// The number of '%' markers are less than additional more keys.
|
||||||
// Append remained additional more keys to the tail of more keys.
|
// Append remained additional more keys to the tail of more keys.
|
||||||
if (DEBUG && out != null) {
|
|
||||||
throw new RuntimeException("Internal logic error:"
|
|
||||||
+ " moreKeys=" + Arrays.toString(moreKeys)
|
|
||||||
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
|
|
||||||
}
|
|
||||||
out = CollectionUtils.arrayAsList(moreKeys, 0, moreKeysCount);
|
out = CollectionUtils.arrayAsList(moreKeys, 0, moreKeysCount);
|
||||||
for (int i = additionalIndex; i < additionalCount; i++) {
|
for (int i = additionalIndex; i < additionalCount; i++) {
|
||||||
out.add(additionalMoreKeys[additionalIndex]);
|
out.add(additionalMoreKeys[additionalIndex]);
|
||||||
|
@ -311,7 +310,7 @@ public final class MoreKeySpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getIntValue(final String[] moreKeys, final String key,
|
public static int getIntValue(@Nullable final String[] moreKeys, final String key,
|
||||||
final int defaultValue) {
|
final int defaultValue) {
|
||||||
if (moreKeys == null) {
|
if (moreKeys == null) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
@ -338,7 +337,7 @@ public final class MoreKeySpec {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getBooleanValue(final String[] moreKeys, final String key) {
|
public static boolean getBooleanValue(@Nullable final String[] moreKeys, final String key) {
|
||||||
if (moreKeys == null) {
|
if (moreKeys == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue