Refactor SuggestionStripLayoutHelper a bit
Bug: 9059710 Change-Id: Ief12029bad75d4dc78090ab97555aece01b873demain
parent
70c2dcffa3
commit
a0c3e02d71
|
@ -161,7 +161,7 @@
|
||||||
|
|
||||||
<declare-styleable name="SuggestionStripView">
|
<declare-styleable name="SuggestionStripView">
|
||||||
<attr name="suggestionStripOption" format="integer">
|
<attr name="suggestionStripOption" format="integer">
|
||||||
<!-- This should be aligned with SuggestionStripViewParams.AUTO_CORRECT_* and etc. -->
|
<!-- This should be aligned with SuggestionStripLayoutHelper.AUTO_CORRECT_* and etc. -->
|
||||||
<flag name="autoCorrectBold" value="0x01" />
|
<flag name="autoCorrectBold" value="0x01" />
|
||||||
<flag name="autoCorrectUnderline" value="0x02" />
|
<flag name="autoCorrectUnderline" value="0x02" />
|
||||||
<flag name="validTypedWordBold" value="0x04" />
|
<flag name="validTypedWordBold" value="0x04" />
|
||||||
|
|
|
@ -24,6 +24,9 @@ import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
public final class SuggestedWords {
|
public final class SuggestedWords {
|
||||||
|
public static final int INDEX_OF_TYPED_WORD = 0;
|
||||||
|
public static final int INDEX_OF_AUTO_CORRECTION = 1;
|
||||||
|
|
||||||
private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST =
|
private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST =
|
||||||
CollectionUtils.newArrayList(0);
|
CollectionUtils.newArrayList(0);
|
||||||
public static final SuggestedWords EMPTY = new SuggestedWords(
|
public static final SuggestedWords EMPTY = new SuggestedWords(
|
||||||
|
@ -61,12 +64,12 @@ public final class SuggestedWords {
|
||||||
return mSuggestedWordInfoList.size();
|
return mSuggestedWordInfoList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWord(int pos) {
|
public String getWord(final int index) {
|
||||||
return mSuggestedWordInfoList.get(pos).mWord;
|
return mSuggestedWordInfoList.get(index).mWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuggestedWordInfo getInfo(int pos) {
|
public SuggestedWordInfo getInfo(final int index) {
|
||||||
return mSuggestedWordInfoList.get(pos);
|
return mSuggestedWordInfoList.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean willAutoCorrect() {
|
public boolean willAutoCorrect() {
|
||||||
|
@ -108,8 +111,8 @@ public final class SuggestedWords {
|
||||||
SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED));
|
SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED));
|
||||||
alreadySeen.add(typedWord.toString());
|
alreadySeen.add(typedWord.toString());
|
||||||
final int previousSize = previousSuggestions.size();
|
final int previousSize = previousSuggestions.size();
|
||||||
for (int pos = 1; pos < previousSize; pos++) {
|
for (int index = 1; index < previousSize; index++) {
|
||||||
final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(pos);
|
final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(index);
|
||||||
final String prevWord = prevWordInfo.mWord;
|
final String prevWord = prevWordInfo.mWord;
|
||||||
// Filter out duplicate suggestion.
|
// Filter out duplicate suggestion.
|
||||||
if (!alreadySeen.contains(prevWord)) {
|
if (!alreadySeen.contains(prevWord)) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int layout(final SuggestedWords suggestedWords, final int fromPos,
|
public int layout(final SuggestedWords suggestedWords, final int fromIndex,
|
||||||
final int maxWidth, final int minWidth, final int maxRow, final Paint paint,
|
final int maxWidth, final int minWidth, final int maxRow, final Paint paint,
|
||||||
final Resources res) {
|
final Resources res) {
|
||||||
clearKeys();
|
clearKeys();
|
||||||
|
@ -70,53 +70,54 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
final float padding = res.getDimension(R.dimen.more_suggestions_key_horizontal_padding);
|
final float padding = res.getDimension(R.dimen.more_suggestions_key_horizontal_padding);
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int pos = fromPos, rowStartPos = fromPos;
|
int index = fromIndex;
|
||||||
|
int rowStartIndex = fromIndex;
|
||||||
final int size = Math.min(suggestedWords.size(), SuggestionStripView.MAX_SUGGESTIONS);
|
final int size = Math.min(suggestedWords.size(), SuggestionStripView.MAX_SUGGESTIONS);
|
||||||
while (pos < size) {
|
while (index < size) {
|
||||||
final String word = suggestedWords.getWord(pos);
|
final String word = suggestedWords.getWord(index);
|
||||||
// TODO: Should take care of text x-scaling.
|
// TODO: Should take care of text x-scaling.
|
||||||
mWidths[pos] = (int)(TypefaceUtils.getLabelWidth(word, paint) + padding);
|
mWidths[index] = (int)(TypefaceUtils.getLabelWidth(word, paint) + padding);
|
||||||
final int numColumn = pos - rowStartPos + 1;
|
final int numColumn = index - rowStartIndex + 1;
|
||||||
final int columnWidth =
|
final int columnWidth =
|
||||||
(maxWidth - mDividerWidth * (numColumn - 1)) / numColumn;
|
(maxWidth - mDividerWidth * (numColumn - 1)) / numColumn;
|
||||||
if (numColumn > MAX_COLUMNS_IN_ROW
|
if (numColumn > MAX_COLUMNS_IN_ROW
|
||||||
|| !fitInWidth(rowStartPos, pos + 1, columnWidth)) {
|
|| !fitInWidth(rowStartIndex, index + 1, columnWidth)) {
|
||||||
if ((row + 1) >= maxRow) {
|
if ((row + 1) >= maxRow) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mNumColumnsInRow[row] = pos - rowStartPos;
|
mNumColumnsInRow[row] = index - rowStartIndex;
|
||||||
rowStartPos = pos;
|
rowStartIndex = index;
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
mColumnOrders[pos] = pos - rowStartPos;
|
mColumnOrders[index] = index - rowStartIndex;
|
||||||
mRowNumbers[pos] = row;
|
mRowNumbers[index] = row;
|
||||||
pos++;
|
index++;
|
||||||
}
|
}
|
||||||
mNumColumnsInRow[row] = pos - rowStartPos;
|
mNumColumnsInRow[row] = index - rowStartIndex;
|
||||||
mNumRows = row + 1;
|
mNumRows = row + 1;
|
||||||
mBaseWidth = mOccupiedWidth = Math.max(
|
mBaseWidth = mOccupiedWidth = Math.max(
|
||||||
minWidth, calcurateMaxRowWidth(fromPos, pos));
|
minWidth, calcurateMaxRowWidth(fromIndex, index));
|
||||||
mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
|
mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight + mVerticalGap;
|
||||||
return pos - fromPos;
|
return index - fromIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fitInWidth(final int startPos, final int endPos, final int width) {
|
private boolean fitInWidth(final int startIndex, final int endIndex, final int width) {
|
||||||
for (int pos = startPos; pos < endPos; pos++) {
|
for (int index = startIndex; index < endIndex; index++) {
|
||||||
if (mWidths[pos] > width)
|
if (mWidths[index] > width)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calcurateMaxRowWidth(final int startPos, final int endPos) {
|
private int calcurateMaxRowWidth(final int startIndex, final int endIndex) {
|
||||||
int maxRowWidth = 0;
|
int maxRowWidth = 0;
|
||||||
int pos = startPos;
|
int index = startIndex;
|
||||||
for (int row = 0; row < mNumRows; row++) {
|
for (int row = 0; row < mNumRows; row++) {
|
||||||
final int numColumnInRow = mNumColumnsInRow[row];
|
final int numColumnInRow = mNumColumnsInRow[row];
|
||||||
int maxKeyWidth = 0;
|
int maxKeyWidth = 0;
|
||||||
while (pos < endPos && mRowNumbers[pos] == row) {
|
while (index < endIndex && mRowNumbers[index] == row) {
|
||||||
maxKeyWidth = Math.max(maxKeyWidth, mWidths[pos]);
|
maxKeyWidth = Math.max(maxKeyWidth, mWidths[index]);
|
||||||
pos++;
|
index++;
|
||||||
}
|
}
|
||||||
maxRowWidth = Math.max(maxRowWidth,
|
maxRowWidth = Math.max(maxRowWidth,
|
||||||
maxKeyWidth * numColumnInRow + mDividerWidth * (numColumnInRow - 1));
|
maxKeyWidth * numColumnInRow + mDividerWidth * (numColumnInRow - 1));
|
||||||
|
@ -130,40 +131,40 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
{ 2, 0, 1},
|
{ 2, 0, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
public int getNumColumnInRow(final int pos) {
|
public int getNumColumnInRow(final int index) {
|
||||||
return mNumColumnsInRow[mRowNumbers[pos]];
|
return mNumColumnsInRow[mRowNumbers[index]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColumnNumber(final int pos) {
|
public int getColumnNumber(final int index) {
|
||||||
final int columnOrder = mColumnOrders[pos];
|
final int columnOrder = mColumnOrders[index];
|
||||||
final int numColumn = getNumColumnInRow(pos);
|
final int numColumn = getNumColumnInRow(index);
|
||||||
return COLUMN_ORDER_TO_NUMBER[numColumn - 1][columnOrder];
|
return COLUMN_ORDER_TO_NUMBER[numColumn - 1][columnOrder];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX(final int pos) {
|
public int getX(final int index) {
|
||||||
final int columnNumber = getColumnNumber(pos);
|
final int columnNumber = getColumnNumber(index);
|
||||||
return columnNumber * (getWidth(pos) + mDividerWidth);
|
return columnNumber * (getWidth(index) + mDividerWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getY(final int pos) {
|
public int getY(final int index) {
|
||||||
final int row = mRowNumbers[pos];
|
final int row = mRowNumbers[index];
|
||||||
return (mNumRows -1 - row) * mDefaultRowHeight + mTopPadding;
|
return (mNumRows -1 - row) * mDefaultRowHeight + mTopPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth(final int pos) {
|
public int getWidth(final int index) {
|
||||||
final int numColumnInRow = getNumColumnInRow(pos);
|
final int numColumnInRow = getNumColumnInRow(index);
|
||||||
return (mOccupiedWidth - mDividerWidth * (numColumnInRow - 1)) / numColumnInRow;
|
return (mOccupiedWidth - mDividerWidth * (numColumnInRow - 1)) / numColumnInRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markAsEdgeKey(final Key key, final int pos) {
|
public void markAsEdgeKey(final Key key, final int index) {
|
||||||
final int row = mRowNumbers[pos];
|
final int row = mRowNumbers[index];
|
||||||
if (row == 0)
|
if (row == 0)
|
||||||
key.markAsBottomEdge(this);
|
key.markAsBottomEdge(this);
|
||||||
if (row == mNumRows - 1)
|
if (row == mNumRows - 1)
|
||||||
key.markAsTopEdge(this);
|
key.markAsTopEdge(this);
|
||||||
|
|
||||||
final int numColumnInRow = mNumColumnsInRow[row];
|
final int numColumnInRow = mNumColumnsInRow[row];
|
||||||
final int column = getColumnNumber(pos);
|
final int column = getColumnNumber(index);
|
||||||
if (column == 0)
|
if (column == 0)
|
||||||
key.markAsLeftEdge(this);
|
key.markAsLeftEdge(this);
|
||||||
if (column == numColumnInRow - 1)
|
if (column == numColumnInRow - 1)
|
||||||
|
@ -174,15 +175,15 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
public static final class Builder extends KeyboardBuilder<MoreSuggestionsParam> {
|
public static final class Builder extends KeyboardBuilder<MoreSuggestionsParam> {
|
||||||
private final MoreSuggestionsView mPaneView;
|
private final MoreSuggestionsView mPaneView;
|
||||||
private SuggestedWords mSuggestedWords;
|
private SuggestedWords mSuggestedWords;
|
||||||
private int mFromPos;
|
private int mFromIndex;
|
||||||
private int mToPos;
|
private int mToIndex;
|
||||||
|
|
||||||
public Builder(final Context context, final MoreSuggestionsView paneView) {
|
public Builder(final Context context, final MoreSuggestionsView paneView) {
|
||||||
super(context, new MoreSuggestionsParam());
|
super(context, new MoreSuggestionsParam());
|
||||||
mPaneView = paneView;
|
mPaneView = paneView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder layout(final SuggestedWords suggestedWords, final int fromPos,
|
public Builder layout(final SuggestedWords suggestedWords, final int fromIndex,
|
||||||
final int maxWidth, final int minWidth, final int maxRow,
|
final int maxWidth, final int minWidth, final int maxRow,
|
||||||
final Keyboard parentKeyboard) {
|
final Keyboard parentKeyboard) {
|
||||||
final int xmlId = R.xml.kbd_suggestions_pane_template;
|
final int xmlId = R.xml.kbd_suggestions_pane_template;
|
||||||
|
@ -190,10 +191,10 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
|
mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
|
||||||
|
|
||||||
mPaneView.updateKeyboardGeometry(mParams.mDefaultRowHeight);
|
mPaneView.updateKeyboardGeometry(mParams.mDefaultRowHeight);
|
||||||
final int count = mParams.layout(suggestedWords, fromPos, maxWidth, minWidth, maxRow,
|
final int count = mParams.layout(suggestedWords, fromIndex, maxWidth, minWidth, maxRow,
|
||||||
mPaneView.newLabelPaint(null /* key */), mResources);
|
mPaneView.newLabelPaint(null /* key */), mResources);
|
||||||
mFromPos = fromPos;
|
mFromIndex = fromIndex;
|
||||||
mToPos = fromPos + count;
|
mToIndex = fromIndex + count;
|
||||||
mSuggestedWords = suggestedWords;
|
mSuggestedWords = suggestedWords;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -201,20 +202,20 @@ public final class MoreSuggestions extends Keyboard {
|
||||||
@Override
|
@Override
|
||||||
public MoreSuggestions build() {
|
public MoreSuggestions build() {
|
||||||
final MoreSuggestionsParam params = mParams;
|
final MoreSuggestionsParam params = mParams;
|
||||||
for (int pos = mFromPos; pos < mToPos; pos++) {
|
for (int index = mFromIndex; index < mToIndex; index++) {
|
||||||
final int x = params.getX(pos);
|
final int x = params.getX(index);
|
||||||
final int y = params.getY(pos);
|
final int y = params.getY(index);
|
||||||
final int width = params.getWidth(pos);
|
final int width = params.getWidth(index);
|
||||||
final String word = mSuggestedWords.getWord(pos);
|
final String word = mSuggestedWords.getWord(index);
|
||||||
final String info = Utils.getDebugInfo(mSuggestedWords, pos);
|
final String info = Utils.getDebugInfo(mSuggestedWords, index);
|
||||||
final int index = pos + SUGGESTION_CODE_BASE;
|
final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE;
|
||||||
final Key key = new Key(
|
final Key key = new Key(
|
||||||
params, word, info, KeyboardIconsSet.ICON_UNDEFINED, index, null, x, y,
|
params, word, info, KeyboardIconsSet.ICON_UNDEFINED, indexInMoreSuggestions,
|
||||||
width, params.mDefaultRowHeight, 0);
|
null, x, y, width, params.mDefaultRowHeight, 0);
|
||||||
params.markAsEdgeKey(key, pos);
|
params.markAsEdgeKey(key, index);
|
||||||
params.onAddKey(key);
|
params.onAddKey(key);
|
||||||
final int columnNumber = params.getColumnNumber(pos);
|
final int columnNumber = params.getColumnNumber(index);
|
||||||
final int numColumnInRow = params.getNumColumnInRow(pos);
|
final int numColumnInRow = params.getNumColumnInRow(index);
|
||||||
if (columnNumber < numColumnInRow - 1) {
|
if (columnNumber < numColumnInRow - 1) {
|
||||||
final Divider divider = new Divider(params, params.mDivider, x + width, y,
|
final Divider divider = new Divider(params, params.mDivider, x + width, y,
|
||||||
params.mDividerWidth, params.mDefaultRowHeight);
|
params.mDividerWidth, params.mDefaultRowHeight);
|
||||||
|
|
|
@ -23,9 +23,9 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Paint.Align;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.Paint.Align;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
|
@ -40,14 +40,13 @@ import android.util.AttributeSet;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.ViewLayoutUtils;
|
import com.android.inputmethod.keyboard.ViewLayoutUtils;
|
||||||
import com.android.inputmethod.latin.AutoCorrection;
|
import com.android.inputmethod.latin.AutoCorrection;
|
||||||
import com.android.inputmethod.latin.CollectionUtils;
|
|
||||||
import com.android.inputmethod.latin.LatinImeLogger;
|
import com.android.inputmethod.latin.LatinImeLogger;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.ResourceUtils;
|
import com.android.inputmethod.latin.ResourceUtils;
|
||||||
|
@ -71,7 +70,11 @@ final class SuggestionStripLayoutHelper {
|
||||||
private int mMaxMoreSuggestionsRow;
|
private int mMaxMoreSuggestionsRow;
|
||||||
public final float mMinMoreSuggestionsWidth;
|
public final float mMinMoreSuggestionsWidth;
|
||||||
public final int mMoreSuggestionsBottomGap;
|
public final int mMoreSuggestionsBottomGap;
|
||||||
|
public boolean mMoreSuggestionsAvailable;
|
||||||
|
|
||||||
|
// The index of these {@link ArrayList} is the position in the suggestion strip. The indices
|
||||||
|
// increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
|
||||||
|
// The position of the most important suggestion is in {@link #mCenterPositionInStrip}
|
||||||
private final ArrayList<TextView> mWordViews;
|
private final ArrayList<TextView> mWordViews;
|
||||||
private final ArrayList<View> mDividerViews;
|
private final ArrayList<View> mDividerViews;
|
||||||
private final ArrayList<TextView> mDebugInfoViews;
|
private final ArrayList<TextView> mDebugInfoViews;
|
||||||
|
@ -89,16 +92,14 @@ final class SuggestionStripLayoutHelper {
|
||||||
|
|
||||||
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
|
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
|
||||||
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
|
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
|
||||||
|
|
||||||
|
private final int mSuggestionStripOption;
|
||||||
|
// These constants are the flag values of
|
||||||
|
// {@link R.styleable#SuggestionStripView_suggestionStripOption} attribute.
|
||||||
private static final int AUTO_CORRECT_BOLD = 0x01;
|
private static final int AUTO_CORRECT_BOLD = 0x01;
|
||||||
private static final int AUTO_CORRECT_UNDERLINE = 0x02;
|
private static final int AUTO_CORRECT_UNDERLINE = 0x02;
|
||||||
private static final int VALID_TYPED_WORD_BOLD = 0x04;
|
private static final int VALID_TYPED_WORD_BOLD = 0x04;
|
||||||
|
|
||||||
private final int mSuggestionStripOption;
|
|
||||||
|
|
||||||
private final ArrayList<CharSequence> mWords = CollectionUtils.newArrayList();
|
|
||||||
|
|
||||||
public boolean mMoreSuggestionsAvailable;
|
|
||||||
|
|
||||||
private final TextView mWordToSaveView;
|
private final TextView mWordToSaveView;
|
||||||
private final TextView mLeftwardsArrowView;
|
private final TextView mLeftwardsArrowView;
|
||||||
private final TextView mHintToSaveView;
|
private final TextView mHintToSaveView;
|
||||||
|
@ -205,7 +206,7 @@ final class SuggestionStripLayoutHelper {
|
||||||
return new BitmapDrawable(res, buffer);
|
return new BitmapDrawable(res, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords,
|
private CharSequence getStyledSuggestedWord(final SuggestedWords suggestedWords,
|
||||||
final int indexInSuggestedWords) {
|
final int indexInSuggestedWords) {
|
||||||
final String word = suggestedWords.getWord(indexInSuggestedWords);
|
final String word = suggestedWords.getWord(indexInSuggestedWords);
|
||||||
final boolean isAutoCorrect = indexInSuggestedWords == 1
|
final boolean isAutoCorrect = indexInSuggestedWords == 1
|
||||||
|
@ -233,7 +234,8 @@ final class SuggestionStripLayoutHelper {
|
||||||
final SuggestedWords suggestedWords) {
|
final SuggestedWords suggestedWords) {
|
||||||
// TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
|
// TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
|
||||||
// suggestions.
|
// suggestions.
|
||||||
final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() ? 1 : 0;
|
final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect()
|
||||||
|
? SuggestedWords.INDEX_OF_AUTO_CORRECTION : SuggestedWords.INDEX_OF_TYPED_WORD;
|
||||||
if (positionInStrip == mCenterPositionInStrip) {
|
if (positionInStrip == mCenterPositionInStrip) {
|
||||||
return mostImportantIndexInSuggestedWords;
|
return mostImportantIndexInSuggestedWords;
|
||||||
}
|
}
|
||||||
|
@ -245,10 +247,9 @@ final class SuggestionStripLayoutHelper {
|
||||||
|
|
||||||
private int getSuggestionTextColor(final int positionInStrip,
|
private int getSuggestionTextColor(final int positionInStrip,
|
||||||
final SuggestedWords suggestedWords) {
|
final SuggestedWords suggestedWords) {
|
||||||
final int indexInSuggestedWords = getIndexInSuggestedWords(
|
final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords);
|
||||||
positionInStrip, suggestedWords);
|
|
||||||
// TODO: Need to revisit this logic with bigram suggestions
|
// TODO: Need to revisit this logic with bigram suggestions
|
||||||
final boolean isSuggested = (indexInSuggestedWords != 0);
|
final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
|
||||||
|
|
||||||
final int color;
|
final int color;
|
||||||
if (positionInStrip == mCenterPositionInStrip && suggestedWords.willAutoCorrect()) {
|
if (positionInStrip == mCenterPositionInStrip && suggestedWords.willAutoCorrect()) {
|
||||||
|
@ -265,7 +266,8 @@ final class SuggestionStripLayoutHelper {
|
||||||
// is in slot 1.
|
// is in slot 1.
|
||||||
if (positionInStrip == mCenterPositionInStrip
|
if (positionInStrip == mCenterPositionInStrip
|
||||||
&& AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
|
&& AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
|
||||||
suggestedWords.getWord(1), suggestedWords.getWord(0))) {
|
suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION),
|
||||||
|
suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD))) {
|
||||||
return 0xFFFF0000;
|
return 0xFFFF0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +298,7 @@ final class SuggestionStripLayoutHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final int countInStrip = mSuggestionsCountInStrip;
|
final int countInStrip = mSuggestionsCountInStrip;
|
||||||
setupWords(suggestedWords, countInStrip);
|
setupWordViewsTextAndColor(suggestedWords, countInStrip);
|
||||||
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
|
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
|
||||||
int x = 0;
|
int x = 0;
|
||||||
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
|
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
|
||||||
|
@ -308,41 +310,37 @@ final class SuggestionStripLayoutHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final int width = getSuggestionWidth(positionInStrip, placerView.getWidth());
|
final int width = getSuggestionWidth(positionInStrip, placerView.getWidth());
|
||||||
final TextView wordView = layoutWord(suggestedWords, positionInStrip, width);
|
final TextView wordView = layoutWord(positionInStrip, width);
|
||||||
stripView.addView(wordView);
|
stripView.addView(wordView);
|
||||||
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
|
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
x += wordView.getMeasuredWidth();
|
x += wordView.getMeasuredWidth();
|
||||||
|
|
||||||
if (SuggestionStripView.DBG) {
|
if (SuggestionStripView.DBG) {
|
||||||
layoutDebugInfo(suggestedWords, positionInStrip, placerView, x);
|
layoutDebugInfo(positionInStrip, placerView, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format appropriately the suggested word indirectly specified by
|
* Format appropriately the suggested word in {@link #mWordViews} specified by
|
||||||
* <code>positionInStrip</code> as text in a corresponding {@link TextView}. When the
|
* <code>positionInStrip</code>. When the suggested word doesn't exist, the corresponding
|
||||||
* suggested word doesn't exist, the corresponding {@link TextView} will be disabled
|
* {@link TextView} will be disabled and never respond to user interaction. The suggested word
|
||||||
* and never respond to user interaction. The suggested word may be shrunk or ellipsized to
|
* may be shrunk or ellipsized to fit in the specified width.
|
||||||
* fit in the specified width.
|
|
||||||
*
|
*
|
||||||
* The <code>positionInStrip</code> argument is the index in the suggestion strip. The indices
|
* The <code>positionInStrip</code> argument is the index in the suggestion strip. The indices
|
||||||
* increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
|
* increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
|
||||||
* The index of the most important suggestion is in {@link #mCenterPositionInStrip}. This
|
* The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This
|
||||||
* usually doesn't match the index in <code>suggedtedWords</code> -- see
|
* usually doesn't match the index in <code>suggedtedWords</code> -- see
|
||||||
* {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
|
* {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
|
||||||
*
|
*
|
||||||
* @param suggestedWords the list of suggestions.
|
* @param positionInStrip the position in the suggestion strip.
|
||||||
* @param positionInStrip the in the suggestion strip.
|
|
||||||
* @param width the maximum width for layout in pixels.
|
* @param width the maximum width for layout in pixels.
|
||||||
* @return the {@link TextView} containing the suggested word appropriately formatted.
|
* @return the {@link TextView} containing the suggested word appropriately formatted.
|
||||||
*/
|
*/
|
||||||
private TextView layoutWord(final SuggestedWords suggestedWords, final int positionInStrip,
|
private TextView layoutWord(final int positionInStrip, final int width) {
|
||||||
final int width) {
|
final TextView wordView = mWordViews.get(positionInStrip);
|
||||||
final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords);
|
final CharSequence word = wordView.getText();
|
||||||
final CharSequence word = mWords.get(indexInSuggestedWords);
|
|
||||||
final TextView wordView = mWordViews.get(indexInSuggestedWords);
|
|
||||||
if (positionInStrip == mCenterPositionInStrip && mMoreSuggestionsAvailable) {
|
if (positionInStrip == mCenterPositionInStrip && mMoreSuggestionsAvailable) {
|
||||||
// TODO: This "more suggestions hint" should have a nicely designed icon.
|
// TODO: This "more suggestions hint" should have a nicely designed icon.
|
||||||
wordView.setCompoundDrawablesWithIntrinsicBounds(
|
wordView.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
@ -355,7 +353,6 @@ final class SuggestionStripLayoutHelper {
|
||||||
|
|
||||||
// Disable this suggestion if the suggestion is null or empty.
|
// Disable this suggestion if the suggestion is null or empty.
|
||||||
wordView.setEnabled(!TextUtils.isEmpty(word));
|
wordView.setEnabled(!TextUtils.isEmpty(word));
|
||||||
wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
|
|
||||||
final CharSequence text = getEllipsizedText(word, width, wordView.getPaint());
|
final CharSequence text = getEllipsizedText(word, width, wordView.getPaint());
|
||||||
final float scaleX = wordView.getTextScaleX();
|
final float scaleX = wordView.getTextScaleX();
|
||||||
wordView.setText(text); // TextView.setText() resets text scale x to 1.0.
|
wordView.setText(text); // TextView.setText() resets text scale x to 1.0.
|
||||||
|
@ -363,18 +360,13 @@ final class SuggestionStripLayoutHelper {
|
||||||
return wordView;
|
return wordView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void layoutDebugInfo(final SuggestedWords suggestedWords, final int positionInStrip,
|
private void layoutDebugInfo(final int positionInStrip, final ViewGroup placerView,
|
||||||
final ViewGroup placerView, final int x) {
|
final int x) {
|
||||||
final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords);
|
final TextView debugInfoView = mDebugInfoViews.get(positionInStrip);
|
||||||
if (indexInSuggestedWords >= suggestedWords.size()) {
|
final CharSequence debugInfo = debugInfoView.getText();
|
||||||
return;
|
|
||||||
}
|
|
||||||
final String debugInfo = Utils.getDebugInfo(suggestedWords, indexInSuggestedWords);
|
|
||||||
if (debugInfo == null) {
|
if (debugInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TextView debugInfoView = mDebugInfoViews.get(indexInSuggestedWords);
|
|
||||||
debugInfoView.setText(debugInfo);
|
|
||||||
placerView.addView(debugInfoView);
|
placerView.addView(debugInfoView);
|
||||||
debugInfoView.measure(
|
debugInfoView.measure(
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
@ -399,39 +391,52 @@ final class SuggestionStripLayoutHelper {
|
||||||
return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
|
return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWords(final SuggestedWords suggestedWords, final int countInStrip) {
|
private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords,
|
||||||
mWords.clear();
|
final int countInStrip) {
|
||||||
final int count = Math.min(suggestedWords.size(), countInStrip);
|
final int count = Math.min(suggestedWords.size(), countInStrip);
|
||||||
for (int pos = 0; pos < count; pos++) {
|
for (int positionInStrip = 0; positionInStrip < count; positionInStrip++) {
|
||||||
final CharSequence styled = getStyledSuggestionWord(suggestedWords, pos);
|
final int indexInSuggestedWords =
|
||||||
mWords.add(styled);
|
getIndexInSuggestedWords(positionInStrip, suggestedWords);
|
||||||
|
final TextView wordView = mWordViews.get(positionInStrip);
|
||||||
|
// {@link TextView#getTag()} is used to get the index in suggestedWords at
|
||||||
|
// {@link SuggestionStripView#onClick(View)}.
|
||||||
|
wordView.setTag(indexInSuggestedWords);
|
||||||
|
wordView.setText(getStyledSuggestedWord(suggestedWords, indexInSuggestedWords));
|
||||||
|
wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
|
||||||
|
if (SuggestionStripView.DBG) {
|
||||||
|
mDebugInfoViews.get(positionInStrip).setText(
|
||||||
|
Utils.getDebugInfo(suggestedWords, indexInSuggestedWords));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int pos = count; pos < countInStrip; pos++) {
|
for (int positionInStrip = count; positionInStrip < countInStrip; positionInStrip++) {
|
||||||
// Make this inactive for touches in layout().
|
mWordViews.get(positionInStrip).setText(null);
|
||||||
mWords.add(null);
|
// Make this inactive for touches in {@link #layoutWord(int,int)}.
|
||||||
|
if (SuggestionStripView.DBG) {
|
||||||
|
mDebugInfoViews.get(positionInStrip).setText(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
|
private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
|
||||||
final ViewGroup stripView) {
|
final ViewGroup stripView) {
|
||||||
final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
|
final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
|
||||||
for (int indexInStrip = 0; indexInStrip < countInStrip; indexInStrip++) {
|
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
|
||||||
if (indexInStrip != 0) {
|
if (positionInStrip != 0) {
|
||||||
// Add divider if this isn't the left most suggestion in suggestions strip.
|
// Add divider if this isn't the left most suggestion in suggestions strip.
|
||||||
addDivider(stripView, mDividerViews.get(indexInStrip));
|
addDivider(stripView, mDividerViews.get(positionInStrip));
|
||||||
}
|
}
|
||||||
|
|
||||||
final TextView word = mWordViews.get(indexInStrip);
|
final TextView wordView = mWordViews.get(positionInStrip);
|
||||||
word.setEnabled(true);
|
wordView.setEnabled(true);
|
||||||
word.setTextColor(mColorAutoCorrect);
|
wordView.setTextColor(mColorAutoCorrect);
|
||||||
final String text = suggestedWords.getWord(indexInStrip);
|
final String punctuation = suggestedWords.getWord(positionInStrip);
|
||||||
word.setText(text);
|
wordView.setText(punctuation);
|
||||||
word.setTextScaleX(1.0f);
|
wordView.setTextScaleX(1.0f);
|
||||||
word.setCompoundDrawables(null, null, null, null);
|
wordView.setCompoundDrawables(null, null, null, null);
|
||||||
stripView.addView(word);
|
stripView.addView(wordView);
|
||||||
setLayoutWeight(word, 1.0f, mSuggestionsStripHeight);
|
setLayoutWeight(wordView, 1.0f, mSuggestionsStripHeight);
|
||||||
}
|
}
|
||||||
mMoreSuggestionsAvailable = false;
|
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,
|
public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,
|
||||||
|
|
|
@ -93,12 +93,10 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
|
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
|
||||||
for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) {
|
for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) {
|
||||||
final TextView word = (TextView)inflater.inflate(R.layout.suggestion_word, null);
|
final TextView word = (TextView)inflater.inflate(R.layout.suggestion_word, null);
|
||||||
word.setTag(pos);
|
|
||||||
word.setOnClickListener(this);
|
word.setOnClickListener(this);
|
||||||
word.setOnLongClickListener(this);
|
word.setOnLongClickListener(this);
|
||||||
mWordViews.add(word);
|
mWordViews.add(word);
|
||||||
final View divider = inflater.inflate(R.layout.suggestion_divider, null);
|
final View divider = inflater.inflate(R.layout.suggestion_divider, null);
|
||||||
divider.setTag(pos);
|
|
||||||
divider.setOnClickListener(this);
|
divider.setOnClickListener(this);
|
||||||
mDividerViews.add(divider);
|
mDividerViews.add(divider);
|
||||||
mDebugInfoViews.add((TextView)inflater.inflate(R.layout.suggestion_info, null));
|
mDebugInfoViews.add((TextView)inflater.inflate(R.layout.suggestion_info, null));
|
||||||
|
|
Loading…
Reference in New Issue