diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index feb955e86..7473b42ec 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -94,8 +94,16 @@ - - + + + + + @@ -161,6 +169,9 @@ + + diff --git a/java/res/xml-sw768dp/kbd_ar_rows.xml b/java/res/xml-sw768dp/kbd_ar_rows.xml index e84aae6b5..daaa38e4d 100644 --- a/java/res/xml-sw768dp/kbd_ar_rows.xml +++ b/java/res/xml-sw768dp/kbd_ar_rows.xml @@ -27,12 +27,12 @@ @@ -61,16 +61,17 @@ latin:popupCharacters="ج,چ" /> @@ -100,15 +101,19 @@ latin:keyLabel="ط" /> + diff --git a/java/res/xml-sw768dp/kbd_azerty_rows.xml b/java/res/xml-sw768dp/kbd_azerty_rows.xml index 564f77629..5288ccf91 100644 --- a/java/res/xml-sw768dp/kbd_azerty_rows.xml +++ b/java/res/xml-sw768dp/kbd_azerty_rows.xml @@ -24,12 +24,12 @@ @@ -53,11 +53,12 @@ latin:keyLabel="פ" /> diff --git a/java/res/xml-sw768dp/kbd_number.xml b/java/res/xml-sw768dp/kbd_number.xml index 7cb77ea00..01c41a50c 100644 --- a/java/res/xml-sw768dp/kbd_number.xml +++ b/java/res/xml-sw768dp/kbd_number.xml @@ -24,7 +24,7 @@ latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" - latin:keyWidth="11.949%p" + latin:keyWidth="11.954%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" @@ -40,42 +40,42 @@ > - + latin:keyStyle="tabKeyStyle" + latin:keyLabelOption="alignLeft" + latin:keyWidth="7.969%p" + latin:keyEdgeFlags="left" /> + - - + latin:keyStyle="num4KeyStyle" + latin:keyXPos="32.076%p" /> - - + latin:keyStyle="num7KeyStyle" + latin:keyXPos="32.076%p" /> + latin:keyXPos="32.076%p" /> - + latin:keyXPos="13.829%p" + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> - + latin:keyWidth="8.047%p" /> + latin:keyLabel="7" + latin:keyXPos="45.000%p" /> - - + latin:keyWidth="8.047%p" /> - - - - + latin:keyXPos="13.829%p" + latin:keyWidth="24.140%p" /> + latin:keyLabel="*" + latin:keyXPos="45.000%p" /> + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> - diff --git a/java/res/xml-sw768dp/kbd_phone.xml b/java/res/xml-sw768dp/kbd_phone.xml index 60edcf2bd..583239afb 100644 --- a/java/res/xml-sw768dp/kbd_phone.xml +++ b/java/res/xml-sw768dp/kbd_phone.xml @@ -24,7 +24,7 @@ latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" - latin:keyWidth="11.949%p" + latin:keyWidth="11.954%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" @@ -39,115 +39,101 @@ - + latin:keyXPos="20.400%p" + latin:keyWidth="8.047%p" /> - + latin:keyWidth="8.047%p" /> + latin:keyStyle="num1KeyStyle" + latin:keyXPos="45.000%p" /> - - + latin:keyXPos="20.400%p" + latin:keyWidth="8.047%p" /> - + latin:keyWidth="8.047%p" /> + latin:keyStyle="num4KeyStyle" + latin:keyXPos="45.000%p" /> - - - + latin:keyXPos="20.400%p" + latin:keyWidth="8.047%p" /> - + latin:keyWidth="8.047%p" /> + latin:keyStyle="num7KeyStyle" + latin:keyXPos="45.000%p" /> - - - + latin:keyWidth="8.047%p" /> - - - - + latin:keyStyle="numStarKeyStyle" + latin:keyXPos="45.000%p" /> + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> - diff --git a/java/res/xml-sw768dp/kbd_phone_symbols.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml index c388a4667..714e5e5f3 100644 --- a/java/res/xml-sw768dp/kbd_phone_symbols.xml +++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml @@ -24,7 +24,7 @@ latin:maxKeyboardHeight="@fraction/maxKeyboardHeight" latin:minKeyboardHeight="@fraction/minKeyboardHeight" latin:rowHeight="25%p" - latin:keyWidth="11.949%p" + latin:keyWidth="11.954%p" latin:horizontalGap="@dimen/key_horizontal_gap" latin:verticalGap="@dimen/key_bottom_gap" latin:popupKeyboardTemplate="@xml/kbd_popup_template" @@ -39,127 +39,113 @@ - + latin:keyXPos="13.829%p" + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> - + latin:keyStyle="num1KeyStyle" + latin:keyXPos="45.000%p" /> - - + latin:keyXPos="13.829%p" + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> - + latin:keyStyle="num4KeyStyle" + latin:keyXPos="45.000%p" /> - - - + latin:keyXPos="13.829%p" + latin:keyWidth="8.047%p" /> + latin:keyWidth="8.047%p" /> - + latin:keyWidth="8.047%p" /> + latin:keyStyle="num7KeyStyle" + latin:keyXPos="45.000%p" /> - - - + latin:keyWidth="8.047%p" /> - - - - + latin:keyXPos="13.829%p" + latin:keyWidth="24.140%p" /> + latin:keyStyle="numStarKeyStyle" + latin:keyXPos="45.000%p" /> + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> - diff --git a/java/res/xml-sw768dp/kbd_qwerty_row1.xml b/java/res/xml-sw768dp/kbd_qwerty_row1.xml index f5135591c..3727cf34e 100644 --- a/java/res/xml-sw768dp/kbd_qwerty_row1.xml +++ b/java/res/xml-sw768dp/kbd_qwerty_row1.xml @@ -23,12 +23,12 @@ > diff --git a/java/res/xml-sw768dp/kbd_qwerty_row2.xml b/java/res/xml-sw768dp/kbd_qwerty_row2.xml index 02bd0a6c9..45af120e2 100644 --- a/java/res/xml-sw768dp/kbd_qwerty_row2.xml +++ b/java/res/xml-sw768dp/kbd_qwerty_row2.xml @@ -22,12 +22,12 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > diff --git a/java/res/xml-sw768dp/kbd_qwerty_row3.xml b/java/res/xml-sw768dp/kbd_qwerty_row3.xml index b7e9bcff9..7d59dfb9e 100644 --- a/java/res/xml-sw768dp/kbd_qwerty_row3.xml +++ b/java/res/xml-sw768dp/kbd_qwerty_row3.xml @@ -22,11 +22,11 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > diff --git a/java/res/xml-sw768dp/kbd_qwerty_row4.xml b/java/res/xml-sw768dp/kbd_qwerty_row4.xml index e5bc342ae..b24ea5e43 100644 --- a/java/res/xml-sw768dp/kbd_qwerty_row4.xml +++ b/java/res/xml-sw768dp/kbd_qwerty_row4.xml @@ -23,20 +23,18 @@ > - + latin:keyStyle="settingsKeyStyle" + latin:keyWidth="8.047%p" /> - - - + + latin:keyXPos="31.250%p" + latin:keyWidth="37.500%p" /> + latin:keyStyle="micKeyStyle" + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> diff --git a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml b/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml index fb2034fb7..b8875282c 100644 --- a/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml +++ b/java/res/xml-sw768dp/kbd_qwerty_rows_scandinavia.xml @@ -24,12 +24,12 @@ + latin:keyLabel="й" /> + latin:keyLabel="ц" /> + latin:keyLabel="у" /> + latin:keyLabel="к" /> + latin:keyLabel="н" /> + latin:keyLabel="г" /> + latin:keyLabel="ш" /> + latin:keyLabel="щ" /> + latin:keyLabel="з" /> @@ -101,11 +93,12 @@ latin:keyLabel="э" /> + latin:keyLabel="љ" /> + latin:keyLabel="њ" /> + latin:keyLabel="е" /> + latin:keyLabel="р" /> + latin:keyLabel="т" /> + latin:keyLabel="з" /> + latin:keyLabel="у" /> + latin:keyLabel="и" /> + latin:keyLabel="о" /> + latin:keyLabel="п" /> @@ -101,15 +92,16 @@ latin:keyLabel="ћ" /> @@ -143,7 +135,8 @@ latin:popupCharacters="\?" /> @@ -108,15 +109,16 @@ latin:popupCharacters="],},>" /> - + latin:keyStyle="settingsKeyStyle" + latin:keyWidth="8.047%p" /> - - - + latin:keyLabel="/" + latin:keyXPos="15.157%p" /> + latin:keyXPos="31.250%p" + latin:keyWidth="37.500%p" /> + latin:keyStyle="micKeyStyle" + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> diff --git a/java/res/xml-sw768dp/kbd_symbols_shift.xml b/java/res/xml-sw768dp/kbd_symbols_shift.xml index d7f5958b7..94bd761ba 100644 --- a/java/res/xml-sw768dp/kbd_symbols_shift.xml +++ b/java/res/xml-sw768dp/kbd_symbols_shift.xml @@ -33,12 +33,12 @@ latin:keyboardLayout="@xml/kbd_key_styles" /> @@ -72,16 +72,17 @@ latin:keyLabel="Δ" /> @@ -148,34 +150,33 @@ latin:keyLabel="¿" /> - + latin:keyStyle="settingsKeyStyle" + latin:keyWidth="8.047%p" /> - - - + latin:keyXPos="31.250%p" + latin:keyWidth="37.500%p" /> + latin:keyStyle="micKeyStyle" + latin:keyXPos="-8.047%p" + latin:keyWidth="fillRight" /> diff --git a/java/res/xml/kbd_ar_rows.xml b/java/res/xml/kbd_ar_rows.xml index b2ea45701..a548775a4 100644 --- a/java/res/xml/kbd_ar_rows.xml +++ b/java/res/xml/kbd_ar_rows.xml @@ -53,6 +53,7 @@ diff --git a/java/res/xml/kbd_azerty_rows.xml b/java/res/xml/kbd_azerty_rows.xml index 2f2b05495..9c81aad71 100644 --- a/java/res/xml/kbd_azerty_rows.xml +++ b/java/res/xml/kbd_azerty_rows.xml @@ -68,6 +68,7 @@ latin:keyLabel="p" latin:keyHintIcon="@drawable/key_hint_num0" latin:popupCharacters="@string/alternates_for_p" + latin:keyWidth="fillRight" latin:keyEdgeFlags="right" /> diff --git a/java/res/xml/kbd_iw_rows.xml b/java/res/xml/kbd_iw_rows.xml index fb0c2a915..af017ad6f 100644 --- a/java/res/xml/kbd_iw_rows.xml +++ b/java/res/xml/kbd_iw_rows.xml @@ -29,10 +29,9 @@ - @@ -50,7 +49,7 @@ latin:keyLabel="פ" /> @@ -76,13 +75,13 @@ latin:keyLabel="ך" /> - @@ -101,6 +100,7 @@ + diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml index d4d25d4a2..f888b231e 100644 --- a/java/res/xml/kbd_key_styles.xml +++ b/java/res/xml/kbd_key_styles.xml @@ -51,7 +51,7 @@ @@ -101,20 +101,20 @@ + latin:iconPreview="@drawable/sym_keyboard_tab" /> - + - + @@ -101,7 +99,7 @@ @@ -115,7 +113,7 @@ @@ -128,7 +126,7 @@ latin:keyLabel="9" /> diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml index ca591c72d..e1d1ee8d0 100644 --- a/java/res/xml/kbd_phone.xml +++ b/java/res/xml/kbd_phone.xml @@ -47,7 +47,7 @@ @@ -61,7 +61,7 @@ @@ -74,7 +74,7 @@ latin:keyStyle="num9KeyStyle" /> diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml index 99db23ef1..2af218cfe 100644 --- a/java/res/xml/kbd_phone_symbols.xml +++ b/java/res/xml/kbd_phone_symbols.xml @@ -47,7 +47,7 @@ @@ -64,7 +64,7 @@ @@ -79,7 +79,7 @@ latin:keyStyle="numPoundKeyStyle" /> diff --git a/java/res/xml/kbd_qwerty_row1.xml b/java/res/xml/kbd_qwerty_row1.xml index 3964d3c3e..ba804d321 100644 --- a/java/res/xml/kbd_qwerty_row1.xml +++ b/java/res/xml/kbd_qwerty_row1.xml @@ -66,6 +66,7 @@ latin:keyLabel="p" latin:keyHintIcon="@drawable/key_hint_num0" latin:popupCharacters="@string/alternates_for_p" + latin:keyWidth="fillRight" latin:keyEdgeFlags="right" /> diff --git a/java/res/xml/kbd_qwerty_row2.xml b/java/res/xml/kbd_qwerty_row2.xml index 9ed4553c4..57bbad75a 100644 --- a/java/res/xml/kbd_qwerty_row2.xml +++ b/java/res/xml/kbd_qwerty_row2.xml @@ -24,11 +24,10 @@ - + diff --git a/java/res/xml/kbd_qwerty_row3.xml b/java/res/xml/kbd_qwerty_row3.xml index 3d106e615..98f0404c0 100644 --- a/java/res/xml/kbd_qwerty_row3.xml +++ b/java/res/xml/kbd_qwerty_row3.xml @@ -49,7 +49,7 @@ latin:keyLabel="m" /> diff --git a/java/res/xml/kbd_qwerty_row4.xml b/java/res/xml/kbd_qwerty_row4.xml index a8d150e4b..21d80eb0b 100644 --- a/java/res/xml/kbd_qwerty_row4.xml +++ b/java/res/xml/kbd_qwerty_row4.xml @@ -26,54 +26,6 @@ latin:rowEdgeFlags="bottom" > - - - - - - - - - - - - - - - - - - - - - @@ -88,42 +40,54 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/res/xml/kbd_qwerty_rows_scandinavia.xml b/java/res/xml/kbd_qwerty_rows_scandinavia.xml index 06bb286a2..8cb0640e5 100644 --- a/java/res/xml/kbd_qwerty_rows_scandinavia.xml +++ b/java/res/xml/kbd_qwerty_rows_scandinavia.xml @@ -71,7 +71,7 @@ latin:popupCharacters="@string/alternates_for_p" /> diff --git a/java/res/xml/kbd_ru_rows.xml b/java/res/xml/kbd_ru_rows.xml index b99259938..76250a303 100644 --- a/java/res/xml/kbd_ru_rows.xml +++ b/java/res/xml/kbd_ru_rows.xml @@ -71,7 +71,7 @@ latin:popupCharacters="0" /> @@ -95,6 +96,7 @@ @@ -126,7 +128,7 @@ latin:popupCharacters="¿" /> diff --git a/java/res/xml/kbd_symbols_row4.xml b/java/res/xml/kbd_symbols_row4.xml index b330095af..e701b9cdd 100644 --- a/java/res/xml/kbd_symbols_row4.xml +++ b/java/res/xml/kbd_symbols_row4.xml @@ -22,44 +22,10 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > - - - - - - - - - - - - - - @@ -70,33 +36,58 @@ + latin:keyboardLayout="@xml/kbd_qwerty_f1" /> + + + + + + + + + + + + + - - - - - - - - + + + + + + + + diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml index cde07333b..96e741bbc 100644 --- a/java/res/xml/kbd_symbols_shift.xml +++ b/java/res/xml/kbd_symbols_shift.xml @@ -63,6 +63,7 @@ latin:keyLabel="{" /> @@ -94,6 +95,7 @@ latin:keyLabel="[" /> @@ -125,7 +127,7 @@ latin:popupCharacters="≥,»,›" /> diff --git a/java/res/xml/kbd_symbols_shift_row4.xml b/java/res/xml/kbd_symbols_shift_row4.xml index 4f8567d58..7376bab17 100644 --- a/java/res/xml/kbd_symbols_shift_row4.xml +++ b/java/res/xml/kbd_symbols_shift_row4.xml @@ -22,43 +22,10 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > - - - - - - - - - - - - - - @@ -75,26 +42,50 @@ + + + + + + + + + + + + + - - - - - - - - + + + + + + + + diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index ef86d66ad..cb529461a 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -101,6 +101,10 @@ public class Key { /** Key is enabled and responds on press */ public boolean mEnabled = true; + // keyWidth constants + private static final int KEYWIDTH_FILL_RIGHT = 0; + private static final int KEYWIDTH_FILL_BOTH = -1; + private final static int[] KEY_STATE_NORMAL_ON = { android.R.attr.state_checkable, android.R.attr.state_checked @@ -140,7 +144,7 @@ public class Key { }; /** - * This constructor is being used only for key in mini popup keyboard. + * This constructor is being used only for key in popup mini keyboard. */ public Key(Resources res, Keyboard keyboard, CharSequence popupCharacter, int x, int y, int width, int height, int edgeFlags) { @@ -178,6 +182,7 @@ public class Key { * @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 + * @param keyStyles active key styles set */ public Key(Resources res, Row row, int x, int y, XmlResourceParser parser, KeyStyles keyStyles) { @@ -185,6 +190,7 @@ public class Key { final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard); + int keyWidth; try { mHeight = KeyboardParser.getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_rowHeight, @@ -192,17 +198,13 @@ public class Key { mGap = KeyboardParser.getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_horizontalGap, mKeyboard.getDisplayWidth(), row.mDefaultHorizontalGap); - mWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr, + keyWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth, - mKeyboard.getDisplayWidth(), row.mDefaultWidth) - mGap; + mKeyboard.getDisplayWidth(), row.mDefaultWidth); } finally { keyboardAttr.recycle(); } - // Horizontal gap is divided equally to both sides of the key. - mX = x + mGap / 2; - mY = y; - final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); try { @@ -216,6 +218,35 @@ public class Key { style = keyStyles.getEmptyKeyStyle(); } + final int keyboardWidth = mKeyboard.getDisplayWidth(); + int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr, + R.styleable.Keyboard_Key_keyXPos, keyboardWidth, x); + if (keyXPos < 0) { + // If keyXPos is negative, the actual x-coordinate will be k + keyXPos. + keyXPos += keyboardWidth; + if (keyXPos < x) { + // keyXPos shouldn't be less than x because drawable area for this key starts + // at x. Or, this key will overlaps the adjacent key on its left hand side. + keyXPos = x; + } + } + if (keyWidth == KEYWIDTH_FILL_RIGHT) { + // If keyWidth is zero, the actual key width will be determined to fill out the + // area up to the right edge of the keyboard. + keyWidth = keyboardWidth - keyXPos; + } else if (keyWidth <= KEYWIDTH_FILL_BOTH) { + // If keyWidth is negative, the actual key width will be determined to fill out the + // area between the nearest key on the left hand side and the right edge of the + // keyboard. + keyXPos = x; + keyWidth = keyboardWidth - keyXPos; + } + + // Horizontal gap is divided equally to both sides of the key. + mX = keyXPos + mGap / 2; + mY = y; + mWidth = keyWidth - mGap; + final CharSequence[] popupCharacters = style.getTextArray(keyAttr, R.styleable.Keyboard_Key_popupCharacters); if (res.getBoolean(R.bool.config_digit_popup_characters_enabled)) { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index 88d23985a..7c03ec71e 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -159,7 +159,7 @@ public class KeyboardId { @Override public String toString() { - return String.format("[%s.xml %s %s%d %s %s %s %s%s%s%s%s%s]", + return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s]", mXmlName, mLocale, (mOrientation == 1 ? "port" : "land"), mWidth, diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java index 43d9f271f..4ae011347 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java @@ -280,7 +280,7 @@ public class KeyboardParser { if (TAG_KEY.equals(tag)) { parseKey(parser, row, keys); } else if (TAG_SPACER.equals(tag)) { - parseSpacer(parser, keys); + parseSpacer(parser, row, keys); } else if (TAG_INCLUDE.equals(tag)) { parseIncludeRowContent(parser, row, keys); } else if (TAG_SWITCH.equals(tag)) { @@ -327,19 +327,32 @@ public class KeyboardParser { } } - private void parseSpacer(XmlResourceParser parser, List keys) + private void parseSpacer(XmlResourceParser parser, Row row, List keys) throws XmlPullParserException, IOException { if (keys == null) { checkEndTag(TAG_SPACER, parser); } else { if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER)); - final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), + final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard); - final int gap = getDimensionOrFraction(a, R.styleable.Keyboard_horizontalGap, - mKeyboard.getDisplayWidth(), 0); - a.recycle(); + if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap)) + throw new IllegalAttribute(parser, "horizontalGap"); + final int defaultWidth = (row != null) ? row.mDefaultWidth : 0; + final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth, + mKeyboard.getDisplayWidth(), defaultWidth); + keyboardAttr.recycle(); + + final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), + R.styleable.Keyboard_Key); + int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr, + R.styleable.Keyboard_Key_keyXPos, mKeyboard.getDisplayWidth(), mCurrentX); + if (keyXPos < 0) { + // If keyXPos is negative, the actual x-coordinate will be display_width + keyXPos. + keyXPos += mKeyboard.getDisplayWidth(); + } + checkEndTag(TAG_SPACER, parser); - setSpacer(gap); + setSpacer(keyXPos, keyWidth); } } @@ -566,14 +579,14 @@ public class KeyboardParser { private void startRow(Row row) { mCurrentX = 0; - setSpacer(mHorizontalEdgesPadding); + setSpacer(mCurrentX, mHorizontalEdgesPadding); mCurrentRow = row; } private void endRow() { if (mCurrentRow == null) throw new InflateException("orphant end row tag"); - setSpacer(mHorizontalEdgesPadding); + setSpacer(mCurrentX, mHorizontalEdgesPadding); if (mCurrentX > mMaxRowWidth) mMaxRowWidth = mCurrentX; mCurrentY += mCurrentRow.mDefaultHeight; @@ -581,7 +594,7 @@ public class KeyboardParser { } private void endKey(Key key) { - mCurrentX += key.mGap + key.mWidth; + mCurrentX = key.mX + key.mGap + key.mWidth; } private void endKeyboard(int defaultVerticalGap) { @@ -589,19 +602,23 @@ public class KeyboardParser { mTotalHeight = mCurrentY - defaultVerticalGap; } - private void setSpacer(int gap) { - mCurrentX += gap; + private void setSpacer(int keyXPos, int width) { + mCurrentX = keyXPos + width; } public static int getDimensionOrFraction(TypedArray a, int index, int base, int defValue) { final TypedValue value = a.peekValue(index); if (value == null) return defValue; - if (value.type == TypedValue.TYPE_DIMENSION) { - return a.getDimensionPixelOffset(index, defValue); - } else if (value.type == TypedValue.TYPE_FRACTION) { + if (value.type == TypedValue.TYPE_FRACTION) { // Round it to avoid values like 47.9999 from getting truncated return Math.round(a.getFraction(index, base, base, defValue)); + } else if (value.type == TypedValue.TYPE_DIMENSION) { + return a.getDimensionPixelOffset(index, defValue); + } else if (value.type >= TypedValue.TYPE_FIRST_INT + && value.type <= TypedValue.TYPE_LAST_INT) { + // For enum value. + return a.getInt(index, defValue); } return defValue; } @@ -627,6 +644,13 @@ public class KeyboardParser { } } + @SuppressWarnings("serial") + private static class IllegalAttribute extends ParseException { + public IllegalAttribute(XmlResourceParser parser, String attribute) { + super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser); + } + } + @SuppressWarnings("serial") private static class NonEmptyTag extends ParseException { public NonEmptyTag(String tag, XmlResourceParser parser) {