Make Key, Row and Keyboard attributes final

Change-Id: Ie87e9e8936646334646cc93b228e0f6a93a79e5b
main
Tadashi G. Takaoka 2010-12-03 13:17:26 +09:00
parent 7545ec8df0
commit a275e9eb48
5 changed files with 148 additions and 120 deletions

View File

@ -35,47 +35,48 @@ public class Key {
* All the key codes (unicode or custom code) that this key could generate, zero'th
* being the most important.
*/
public int[] mCodes;
public final int[] mCodes;
/** The unicode that this key generates in manual temporary upper case mode. */
public int mManualTemporaryUpperCaseCode;
public final int mManualTemporaryUpperCaseCode;
/** Label to display */
public CharSequence mLabel;
public final CharSequence mLabel;
/** Option of the label */
public int mLabelOption;
public final int mLabelOption;
/** Icon to display instead of a label. Icon takes precedence over a label */
public Drawable mIcon;
/** Hint icon to display on the key in conjunction with the label */
public Drawable mHintIcon;
private Drawable mIcon;
/** Preview version of the icon, for the preview popup */
private Drawable mPreviewIcon;
/** Hint icon to display on the key in conjunction with the label */
public final Drawable mHintIcon;
/**
* The hint icon to display on the key when keyboard is in manual temporary upper case
* mode.
*/
public Drawable mManualTemporaryUpperCaseHintIcon;
public final Drawable mManualTemporaryUpperCaseHintIcon;
public Drawable mPreviewIcon;
/** Width of the key, not including the gap */
public int mWidth;
public final int mWidth;
/** Height of the key, not including the gap */
public int mHeight;
public final int mHeight;
/** The horizontal gap before this key */
public int mGap;
public final int mGap;
/** Whether this key is sticky, i.e., a toggle key */
public boolean mSticky;
public final boolean mSticky;
/** X coordinate of the key in the keyboard layout */
public int mX;
public final int mX;
/** Y coordinate of the key in the keyboard layout */
public int mY;
/** The current pressed state of this key */
public boolean mPressed;
/** If this is a sticky key, is it on? */
public boolean mOn;
public final int mY;
/** Text to output when pressed. This can be multiple characters, like ".com" */
public CharSequence mOutputText;
public final CharSequence mOutputText;
/** Popup characters */
public CharSequence mPopupCharacters;
public final CharSequence mPopupCharacters;
/**
* If this key pops up a mini keyboard, this is the resource id for the XML layout for that
* keyboard.
*/
public final int mPopupResId;
/**
* Flags that specify the anchoring to edges of the keyboard for detecting touch events
@ -83,19 +84,19 @@ public class Key {
* {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT},
* {@link Keyboard#EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM}.
*/
public int mEdgeFlags;
public final int mEdgeFlags;
/** Whether this is a modifier key, such as Shift or Alt */
public boolean mModifier;
/** The Keyboard that this key belongs to */
protected final Keyboard mKeyboard;
/**
* If this key pops up a mini keyboard, this is the resource id for the XML layout for that
* keyboard.
*/
public int mPopupResId;
public final boolean mModifier;
/** Whether this key repeats itself when held down */
public boolean mRepeatable;
public final boolean mRepeatable;
/** The Keyboard that this key belongs to */
private final Keyboard mKeyboard;
/** The current pressed state of this key */
public boolean mPressed;
/** If this is a sticky key, is it on? */
public boolean mOn;
private final static int[] KEY_STATE_NORMAL_ON = {
android.R.attr.state_checkable,
@ -136,38 +137,53 @@ public class Key {
};
/** Create an empty key with no attributes. */
public Key(Row parent) {
mKeyboard = parent.mParent;
mHeight = parent.mDefaultHeight;
mGap = parent.mDefaultHorizontalGap;
mWidth = parent.mDefaultWidth - mGap;
mEdgeFlags = parent.mRowEdgeFlags;
public Key(Row row, char letter, int x, int y) {
mKeyboard = row.getKeyboard();
mHeight = row.mDefaultHeight;
mGap = row.mDefaultHorizontalGap;
mWidth = row.mDefaultWidth - mGap;
mEdgeFlags = row.mRowEdgeFlags;
mHintIcon = null;
mManualTemporaryUpperCaseHintIcon = null;
mManualTemporaryUpperCaseCode = 0;
mLabelOption = 0;
mModifier = false;
mSticky = false;
mRepeatable = false;
mOutputText = null;
mPopupCharacters = null;
mPopupResId = 0;
mLabel = String.valueOf(letter);
mCodes = new int[] { letter };
// Horizontal gap is divided equally to both sides of the key.
mX = x + mGap / 2;
mY = y;
}
/** 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
* @param row 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,
public Key(Resources res, Row row, int x, int y, XmlResourceParser parser,
KeyStyles keyStyles) {
this(parent);
mKeyboard = row.getKeyboard();
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard);
mHeight = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyHeight,
mKeyboard.mDisplayHeight, parent.mDefaultHeight);
mKeyboard.getKeyboardHeight(), row.mDefaultHeight);
mGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_horizontalGap,
mKeyboard.mDisplayWidth, parent.mDefaultHorizontalGap);
mKeyboard.getKeyboardWidth(), row.mDefaultHorizontalGap);
mWidth = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyWidth,
mKeyboard.mDisplayWidth, parent.mDefaultWidth) - mGap;
mKeyboard.getKeyboardWidth(), row.mDefaultWidth) - mGap;
a.recycle();
a = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key);
@ -186,7 +202,7 @@ public class Key {
this.mX = x + mGap / 2;
this.mY = y;
mCodes = style.getIntArray(a, R.styleable.Keyboard_Key_codes);
int[] codes = style.getIntArray(a, R.styleable.Keyboard_Key_codes);
mPreviewIcon = style.getDrawable(a, R.styleable.Keyboard_Key_iconPreview);
Keyboard.setDefaultBounds(mPreviewIcon);
mPopupCharacters = style.getText(a, R.styleable.Keyboard_Key_popupCharacters);
@ -194,8 +210,8 @@ public class Key {
mRepeatable = style.getBoolean(a, R.styleable.Keyboard_Key_isRepeatable, false);
mModifier = style.getBoolean(a, R.styleable.Keyboard_Key_isModifier, false);
mSticky = style.getBoolean(a, R.styleable.Keyboard_Key_isSticky, false);
mEdgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0);
mEdgeFlags |= parent.mRowEdgeFlags;
mEdgeFlags = style.getFlag(a, R.styleable.Keyboard_Key_keyEdgeFlags, 0)
| row.mRowEdgeFlags;
mIcon = style.getDrawable(a, R.styleable.Keyboard_Key_keyIcon);
Keyboard.setDefaultBounds(mIcon);
@ -217,9 +233,25 @@ public class Key {
if (shiftedIcon != null)
mKeyboard.getShiftedIcons().put(this, shiftedIcon);
if (mCodes == null && !TextUtils.isEmpty(mLabel)) {
mCodes = new int[] { mLabel.charAt(0) };
}
if (codes == null && !TextUtils.isEmpty(mLabel))
codes = new int[] { mLabel.charAt(0) };
mCodes = codes;
}
public Drawable getIcon() {
return mIcon;
}
public Drawable getPreviewIcon() {
return mPreviewIcon;
}
public void setIcon(Drawable icon) {
mIcon = icon;
}
public void setPreviewIcon(Drawable icon) {
mPreviewIcon = icon;
}
/**

View File

@ -80,16 +80,16 @@ public class Keyboard {
public static final int CODE_VOICE = -109;
/** Horizontal gap default for all rows */
int mDefaultHorizontalGap;
private int mDefaultHorizontalGap;
/** Default key width */
int mDefaultWidth;
private int mDefaultWidth;
/** Default key height */
int mDefaultHeight;
private int mDefaultHeight;
/** Default gap between rows */
int mDefaultVerticalGap;
private int mDefaultVerticalGap;
/** List of shift keys in this keyboard and its icons and state */
private final List<Key> mShiftKeys = new ArrayList<Key>();
@ -116,12 +116,12 @@ public class Keyboard {
private final List<Key> mKeys = new ArrayList<Key>();
/** Width of the screen available to fit the keyboard */
final int mDisplayWidth;
private final int mDisplayWidth;
/** Height of the screen */
final int mDisplayHeight;
private final int mDisplayHeight;
protected final KeyboardId mId;
public final KeyboardId mId;
// Variables for pre-computing nearest keys.
@ -206,12 +206,7 @@ public class Keyboard {
int column = 0;
mTotalWidth = 0;
Row row = new Row(this);
row.mDefaultHeight = mDefaultHeight;
row.mDefaultWidth = mDefaultWidth;
row.mDefaultHorizontalGap = mDefaultHorizontalGap;
row.mVerticalGap = mDefaultVerticalGap;
row.mRowEdgeFlags = EDGE_TOP | EDGE_BOTTOM;
final Row row = new Row(this);
final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns;
for (int i = 0; i < characters.length(); i++) {
char c = characters.charAt(i);
@ -221,12 +216,7 @@ public class Keyboard {
y += mDefaultVerticalGap + mDefaultHeight;
column = 0;
}
final Key key = new Key(row);
// Horizontal gap is divided equally to both sides of the key.
key.mX = x + key.mGap / 2;
key.mY = y;
key.mLabel = String.valueOf(c);
key.mCodes = new int[] { c };
final Key key = new Key(row, c, x, y);
column++;
x += key.mWidth + key.mGap;
mKeys.add(key);
@ -237,43 +227,39 @@ public class Keyboard {
mTotalHeight = y + mDefaultHeight;
}
public KeyboardId getKeyboardId() {
return mId;
}
public List<Key> getKeys() {
return mKeys;
}
protected int getHorizontalGap() {
public int getHorizontalGap() {
return mDefaultHorizontalGap;
}
protected void setHorizontalGap(int gap) {
public void setHorizontalGap(int gap) {
mDefaultHorizontalGap = gap;
}
protected int getVerticalGap() {
public int getVerticalGap() {
return mDefaultVerticalGap;
}
protected void setVerticalGap(int gap) {
public void setVerticalGap(int gap) {
mDefaultVerticalGap = gap;
}
protected int getKeyHeight() {
public int getKeyHeight() {
return mDefaultHeight;
}
protected void setKeyHeight(int height) {
public void setKeyHeight(int height) {
mDefaultHeight = height;
}
protected int getKeyWidth() {
public int getKeyWidth() {
return mDefaultWidth;
}
protected void setKeyWidth(int width) {
public void setKeyWidth(int width) {
mDefaultWidth = width;
final int threshold = (int) (width * SEARCH_DISTANCE);
mProximityThreshold = threshold * threshold;
@ -310,7 +296,7 @@ public class Keyboard {
public void enableShiftLock() {
for (final Key key : getShiftKeys()) {
mShiftLockEnabled.add(key);
mNormalShiftIcons.put(key, key.mIcon);
mNormalShiftIcons.put(key, key.getIcon());
}
}
@ -322,7 +308,7 @@ public class Keyboard {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
key.mOn = newShiftLockState;
key.mIcon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key);
key.setIcon(newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key));
}
mShiftState.setShiftLocked(newShiftLockState);
return true;
@ -336,9 +322,9 @@ public class Keyboard {
final Map<Key, Drawable> shiftedIcons = getShiftedIcons();
for (final Key key : getShiftKeys()) {
if (!newShiftState && !mShiftState.isShiftLocked()) {
key.mIcon = mNormalShiftIcons.get(key);
key.setIcon(mNormalShiftIcons.get(key));
} else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
key.mIcon = shiftedIcons.get(key);
key.setIcon(shiftedIcons.get(key));
}
}
return mShiftState.setShifted(newShiftState);
@ -379,8 +365,8 @@ public class Keyboard {
public void setSpaceKey(Key space) {
mSpaceKey = space;
mSpaceIcon = space.mIcon;
mSpacePreviewIcon = space.mPreviewIcon;
mSpaceIcon = space.getIcon();
mSpacePreviewIcon = space.getPreviewIcon();
}
private void computeNearestNeighbors() {

View File

@ -758,9 +758,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
paint.setShadowLayer(0, 0, 0, 0);
}
// Draw key icon
if (key.mLabel == null && key.mIcon != null) {
final int drawableWidth = key.mIcon.getIntrinsicWidth();
final int drawableHeight = key.mIcon.getIntrinsicHeight();
final Drawable icon = key.getIcon();
if (key.mLabel == null && icon != null) {
final int drawableWidth = icon.getIntrinsicWidth();
final int drawableHeight = icon.getIntrinsicHeight();
final int drawableX;
final int drawableY = (
key.mHeight + padding.top - padding.bottom - drawableHeight) / 2;
@ -780,7 +781,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight,
0xc0008080, new Paint());
}
drawIcon(canvas, key.mIcon, drawableX, drawableY, drawableWidth, drawableHeight);
drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
if (DEBUG_SHOW_ALIGN)
drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
0x80c00000, new Paint());
@ -790,10 +791,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final int drawableHeight = key.mHeight;
final int drawableX = 0;
final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
Drawable icon = (isManualTemporaryUpperCase
Drawable hintIcon = (isManualTemporaryUpperCase
&& key.mManualTemporaryUpperCaseHintIcon != null)
? key.mManualTemporaryUpperCaseHintIcon : key.mHintIcon;
drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
drawIcon(canvas, hintIcon, drawableX, drawableY, drawableWidth, drawableHeight);
if (DEBUG_SHOW_ALIGN)
drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight,
0x80c0c000, new Paint());
@ -965,8 +966,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mPreviewText.setTypeface(mKeyLetterStyle);
}
} else {
final Drawable previewIcon = key.getPreviewIcon();
mPreviewText.setCompoundDrawables(null, null, null,
key.mPreviewIcon != null ? key.mPreviewIcon : key.mIcon);
previewIcon != null ? previewIcon : key.getIcon());
mPreviewText.setText(null);
}
mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),

View File

@ -109,15 +109,15 @@ public class LatinKeyboard extends Keyboard {
final Resources res = mRes;
// If application locales are explicitly selected.
if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) {
mSpaceKey.mIcon = new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
mSpaceKey.setIcon(new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion)));
} else {
// sym_keyboard_space_led can be shared with Black and White symbol themes.
if (isAutoCompletion) {
mSpaceKey.mIcon = new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion));
mSpaceKey.setIcon(new BitmapDrawable(res,
drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCompletion)));
} else {
mSpaceKey.mIcon = mSpaceIcon;
mSpaceKey.setIcon(mSpaceIcon);
}
}
}
@ -238,15 +238,15 @@ public class LatinKeyboard extends Keyboard {
mSlidingLocaleIcon =
new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height);
mSlidingLocaleIcon.setBounds(0, 0, width, height);
mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
mSpaceKey.setPreviewIcon(mSlidingLocaleIcon);
}
mSlidingLocaleIcon.setDiff(diff);
if (Math.abs(diff) == Integer.MAX_VALUE) {
mSpaceKey.mPreviewIcon = mSpacePreviewIcon;
mSpaceKey.setPreviewIcon(mSpacePreviewIcon);
} else {
mSpaceKey.mPreviewIcon = mSlidingLocaleIcon;
mSpaceKey.setPreviewIcon(mSlidingLocaleIcon);
}
mSpaceKey.mPreviewIcon.invalidateSelf();
mSpaceKey.getPreviewIcon().invalidateSelf();
}
public int getLanguageChangeDirection() {

View File

@ -30,44 +30,52 @@ import android.util.Xml;
*/
public class Row {
/** Default width of a key in this row. */
public int mDefaultWidth;
public final int mDefaultWidth;
/** Default height of a key in this row. */
public int mDefaultHeight;
public final int mDefaultHeight;
/** Default horizontal gap between keys in this row. */
public int mDefaultHorizontalGap;
public final int mDefaultHorizontalGap;
/** Vertical gap following this row. */
public int mVerticalGap;
public final int mVerticalGap;
/**
* 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 mRowEdgeFlags;
public final int mRowEdgeFlags;
/* package */ final Keyboard mParent;
private final Keyboard mKeyboard;
/* package */ Row(Keyboard parent) {
this.mParent = parent;
public Row(Keyboard keyboard) {
this.mKeyboard = keyboard;
mDefaultHeight = keyboard.getKeyHeight();
mDefaultWidth = keyboard.getKeyWidth();
mDefaultHorizontalGap = keyboard.getHorizontalGap();
mVerticalGap = keyboard.getVerticalGap();
mRowEdgeFlags = Keyboard.EDGE_TOP | Keyboard.EDGE_BOTTOM;
}
public Row(Resources res, Keyboard parent, XmlResourceParser parser) {
this.mParent = parent;
public Row(Resources res, Keyboard keyboard, XmlResourceParser parser) {
this.mKeyboard = keyboard;
final int keyboardWidth = keyboard.getKeyboardWidth();
final int keyboardHeight = keyboard.getKeyboardHeight();
TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard);
mDefaultWidth = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyWidth,
parent.mDisplayWidth, parent.mDefaultWidth);
R.styleable.Keyboard_keyWidth, keyboardWidth, keyboard.getKeyWidth());
mDefaultHeight = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_keyHeight,
parent.mDisplayHeight, parent.mDefaultHeight);
R.styleable.Keyboard_keyHeight, keyboardHeight, keyboard.getKeyHeight());
mDefaultHorizontalGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_horizontalGap,
parent.mDisplayWidth, parent.mDefaultHorizontalGap);
R.styleable.Keyboard_horizontalGap, keyboardWidth, keyboard.getHorizontalGap());
mVerticalGap = KeyboardParser.getDimensionOrFraction(a,
R.styleable.Keyboard_verticalGap,
parent.mDisplayHeight, parent.mDefaultVerticalGap);
R.styleable.Keyboard_verticalGap, keyboardHeight, keyboard.getVerticalGap());
a.recycle();
a = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard_Row);
mRowEdgeFlags = a.getInt(R.styleable.Keyboard_Row_rowEdgeFlags, 0);
a.recycle();
}
public Keyboard getKeyboard() {
return mKeyboard;
}
}