aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values-sw600dp-land/dimens.xml1
-rw-r--r--java/res/values-sw768dp-land/dimens.xml1
-rw-r--r--java/res/values/attrs.xml1
-rw-r--r--java/res/values/dimens.xml1
-rw-r--r--java/res/values/donottranslate.xml2
-rw-r--r--java/res/values/styles.xml2
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java250
7 files changed, 116 insertions, 142 deletions
diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml
index 5d4967ffe..c75fcc0d1 100644
--- a/java/res/values-sw600dp-land/dimens.xml
+++ b/java/res/values-sw600dp-land/dimens.xml
@@ -51,5 +51,4 @@
<fraction name="key_uppercase_letter_ratio">29%</fraction>
<dimen name="candidate_strip_padding">40.0mm</dimen>
- <integer name="candidate_count_in_strip">5</integer>
</resources>
diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml
index 18837fecc..0cfdffddd 100644
--- a/java/res/values-sw768dp-land/dimens.xml
+++ b/java/res/values-sw768dp-land/dimens.xml
@@ -59,5 +59,4 @@
<dimen name="key_preview_offset_ics">0.05in</dimen>
<dimen name="candidate_strip_padding">40.0mm</dimen>
- <integer name="candidate_count_in_strip">5</integer>
</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index ab522719f..172ca2f25 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -116,6 +116,7 @@
<attr name="colorAutoCorrect" format="color" />
<attr name="colorSuggested" format="color" />
<attr name="candidateCountInStrip" format="integer" />
+ <attr name="centerCandidatePercentile" format="integer" />
</declare-styleable>
<declare-styleable name="Keyboard">
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index a66caa7bd..44e091403 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -86,6 +86,7 @@
<dimen name="candidate_padding">6dip</dimen>
<dimen name="candidate_text_size">18dip</dimen>
<integer name="candidate_count_in_strip">3</integer>
+ <integer name="center_candidate_percentile">40</integer>
<!-- If the screen height in landscape is larger than the below value, then the keyboard
will not go into extract (fullscreen) mode. -->
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 9727746e7..fb28766e7 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -19,7 +19,7 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Symbols that are suggested between words -->
- <string name="suggested_punctuations">!?,\u0022\u0027:();-/@_</string>
+ <string name="suggested_punctuations">!?,\u0022:;()\u0027-/@_</string>
<!-- Symbols that should be swapped with a magic space -->
<string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
<!-- Symbols that should strip a magic space -->
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 9f91ef57c..1ebd2cee1 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -90,6 +90,7 @@
<item name="colorAutoCorrect">#FFFCAE00</item>
<item name="colorSuggested">#FFFCAE00</item>
<item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
+ <item name="centerCandidatePercentile">@integer/center_candidate_percentile</item>
</style>
<!-- Theme "Basic high contrast" -->
<style name="KeyboardView.HighContrast" parent="KeyboardView">
@@ -192,6 +193,7 @@
<item name="colorAutoCorrect">#FF3DC8FF</item>
<item name="colorSuggested">#FFFFFFFF</item>
<item name="candidateCountInStrip">@integer/candidate_count_in_strip</item>
+ <item name="centerCandidatePercentile">@integer/center_candidate_percentile</item>
</style>
<style name="PopupMiniKeyboardAnimation">
<item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index 915e73ccb..db54ef6cf 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -259,12 +259,15 @@ public class CandidateView extends LinearLayout implements OnClickListener {
private static class SuggestionsStripParams extends CandidateViewParams {
private static final int DEFAULT_CANDIDATE_COUNT_IN_STRIP = 3;
+ private static final int DEFAULT_CENTER_CANDIDATE_PERCENTILE = 40;
private static final int PUNCTUATIONS_IN_STRIP = 6;
private final int mColorTypedWord;
private final int mColorAutoCorrect;
private final int mColorSuggestedCandidate;
private final int mCandidateCountInStrip;
+ private final float mCenterCandidateWeight;
+ private final int mCenterCandidateIndex;
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
@@ -278,17 +281,6 @@ public class CandidateView extends LinearLayout implements OnClickListener {
private final int mAutoCorrectHighlight;
private final ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>();
- private SuggestedWords mSuggestedWords;
-
- private int mCountInStrip;
- // True if the mCountInStrip suggestions can fit in suggestion strip in equally divided
- // width without squeezing the text.
- private boolean mCanUseFixedWidthColumns;
- private int mMaxWidth;
- private int mAvailableWidthForWords;
- private int mConstantWidthForPaddings;
- private int mVariableWidthForWords;
- private float mScaleX;
public SuggestionsStripParams(Context context, AttributeSet attrs, int defStyle,
List<TextView> words, List<View> dividers, List<TextView> infos, View control) {
@@ -302,8 +294,13 @@ public class CandidateView extends LinearLayout implements OnClickListener {
mCandidateCountInStrip = a.getInt(
R.styleable.CandidateView_candidateCountInStrip,
DEFAULT_CANDIDATE_COUNT_IN_STRIP);
+ mCenterCandidateWeight = a.getInt(
+ R.styleable.CandidateView_centerCandidatePercentile,
+ DEFAULT_CENTER_CANDIDATE_PERCENTILE) / 100.0f;
a.recycle();
+ mCenterCandidateIndex = mCandidateCountInStrip / 2;
+
mInvertedForegroundColorSpan = new ForegroundColorSpan(mColorTypedWord ^ 0x00ffffff);
mInvertedBackgroundColorSpan = new BackgroundColorSpan(mColorTypedWord);
@@ -328,35 +325,38 @@ public class CandidateView extends LinearLayout implements OnClickListener {
return spannedWord;
}
- private int getWordPosition(int index) {
- if (index >= 2) {
+ private static boolean willAutoCorrect(SuggestedWords suggestions) {
+ return !suggestions.mTypedWordValid && suggestions.mHasMinimalSuggestion;
+ }
+
+ private int getWordPosition(int index, SuggestedWords suggestions) {
+ // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
+ // suggestions.
+ final int centerPos = willAutoCorrect(suggestions) ? 1 : 0;
+ if (index == mCenterCandidateIndex) {
+ return centerPos;
+ } else if (index == centerPos) {
+ return mCenterCandidateIndex;
+ } else {
return index;
}
- final boolean willAutoCorrect = !mSuggestedWords.mTypedWordValid
- && mSuggestedWords.mHasMinimalSuggestion;
- return willAutoCorrect ? 1 - index : index;
}
- private int getCandidateTextColor(int pos) {
- final SuggestedWords suggestions = mSuggestedWords;
- final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
- && ((pos == 1 && !suggestions.mTypedWordValid)
- || (pos == 0 && suggestions.mTypedWordValid));
+ private int getCandidateTextColor(int index, SuggestedWords suggestions, int pos) {
// TODO: Need to revisit this logic with bigram suggestions
final boolean isSuggestedCandidate = (pos != 0);
- final boolean isPunctuationSuggestions = suggestions.isPunctuationSuggestions();
final int color;
- if (isPunctuationSuggestions) {
- color = mColorTypedWord;
- } else if (isAutoCorrect) {
+ if (index == mCenterCandidateIndex && willAutoCorrect(suggestions)) {
color = mColorAutoCorrect;
} else if (isSuggestedCandidate) {
color = mColorSuggestedCandidate;
} else {
color = mColorTypedWord;
}
- final SuggestedWordInfo info = suggestions.getInfo(pos);
+
+ final SuggestedWordInfo info = (pos < suggestions.size())
+ ? suggestions.getInfo(pos) : null;
if (info != null && info.isPreviousSuggestedWord()) {
return applyAlpha(color, 0.5f);
} else {
@@ -381,136 +381,105 @@ public class CandidateView extends LinearLayout implements OnClickListener {
public int layout(SuggestedWords suggestions, ViewGroup stripView, ViewGroup paneView,
int stripWidth) {
- mSuggestedWords = suggestions;
- final int maxCount = suggestions.isPunctuationSuggestions()
- ? PUNCTUATIONS_IN_STRIP : mCandidateCountInStrip;
- final int size = suggestions.size();
- setupTexts(suggestions, size);
- mCountInStrip = Math.min(maxCount, size);
- mScaleX = 1.0f;
- calculateParameters(size, stripWidth);
-
- int infoX = 0;
- for (int index = 0; index < mCountInStrip; index++) {
- final int pos = getWordPosition(index);
- final TextView word = mWords.get(pos);
- final View divider = mDividers.get(pos);
- final TextPaint paint = word.getPaint();
- // TODO: Reorder candidates in strip as appropriate. The center candidate should
- // hold the word when space is typed (valid typed word or auto corrected word).
- word.setTextColor(getCandidateTextColor(pos));
+ if (suggestions.isPunctuationSuggestions()) {
+ return layoutPunctuationSuggestions(suggestions, stripView);
+ }
+
+ final int countInStrip = mCandidateCountInStrip;
+ setupTexts(suggestions, countInStrip);
+ final int maxWidth = (suggestions.size() <= countInStrip)
+ ? stripWidth : stripWidth - mControlWidth;
+
+ int x = 0;
+ for (int index = 0; index < countInStrip; index++) {
+ final int pos = getWordPosition(index, suggestions);
+
+ if (index != 0) {
+ final View divider = mDividers.get(pos);
+ // Add divider if this isn't the left most suggestion in candidate strip.
+ stripView.addView(divider);
+ }
+
final CharSequence styled = mTexts.get(pos);
+ final TextView word = mWords.get(pos);
+ // Disable this candidate if the suggestion is null or empty.
+ word.setEnabled(!TextUtils.isEmpty(styled));
+ word.setTextColor(getCandidateTextColor(index, suggestions, pos));
+ final int width = getCandidateWidth(index, maxWidth);
+ final CharSequence text = getEllipsizedText(styled, width, word.getPaint());
+ final float scaleX = word.getTextScaleX();
+ word.setText(text); // TextView.setText() resets text scale x to 1.0.
+ word.setTextScaleX(scaleX);
+ stripView.addView(word);
+ setLayoutWeight(word, getCandidateWeight(index), mCandidateStripHeight);
- final TextView info;
if (DBG) {
- final CharSequence debugInfo = getDebugInfo(mSuggestedWords, index);
+ final CharSequence debugInfo = getDebugInfo(suggestions, pos);
if (debugInfo != null) {
- info = mInfos.get(index);
+ final TextView info = mInfos.get(pos);
info.setText(debugInfo);
- } else {
- info = null;
- }
- } else {
- info = null;
- }
-
- final CharSequence text;
- final float scaleX;
- if (index == 0 && mCountInStrip == 1) {
- text = getEllipsizedText(styled, mMaxWidth, paint);
- scaleX = paint.getTextScaleX();
- } else {
- text = styled;
- scaleX = mScaleX;
- }
- word.setText(text);
- word.setTextScaleX(scaleX);
- if (index != 0) {
- // Add divider if this isn't the left most suggestion in candidate strip.
- stripView.addView(divider);
- }
- stripView.addView(word);
- if (mCanUseFixedWidthColumns) {
- setLayoutWeight(word, 1.0f, mCandidateStripHeight);
- } else {
- final int width = getTextWidth(text, paint) + mPadding;
- setLayoutWeight(word, width, mCandidateStripHeight);
- }
- if (info != null) {
paneView.addView(info);
info.measure(WRAP_CONTENT, WRAP_CONTENT);
- final int width = info.getMeasuredWidth();
+ final int infoWidth = info.getMeasuredWidth();
final int y = info.getMeasuredHeight();
- FrameLayoutCompatUtils.placeViewAt(info, infoX, 0, width, y);
- infoX += width * 2;
+ FrameLayoutCompatUtils.placeViewAt(info, x, 0, infoWidth, y);
+ x += infoWidth * 2;
}
+ }
}
- return mCountInStrip;
+ return countInStrip;
}
- private void calculateParameters(int size, int maxWidth) {
- do {
- mMaxWidth = maxWidth;
- if (size > mCountInStrip) {
- mMaxWidth -= mControlWidth;
- }
-
- tryLayout();
-
- if (mCanUseFixedWidthColumns) {
- return;
- }
- if (mVariableWidthForWords <= mAvailableWidthForWords) {
- return;
- }
-
- final float scaleX = mAvailableWidthForWords / (float)mVariableWidthForWords;
- if (scaleX >= MIN_TEXT_XSCALE) {
- mScaleX = scaleX;
- return;
- }
+ private int getCandidateWidth(int index, int maxWidth) {
+ final int paddings = mPadding * mCandidateCountInStrip;
+ final int dividers = mDividerWidth * (mCandidateCountInStrip - 1);
+ final int availableWidth = maxWidth - paddings - dividers;
+ return (int)(availableWidth * getCandidateWeight(index));
+ }
- mCountInStrip--;
- } while (mCountInStrip > 1);
- }
-
- private void tryLayout() {
- final int maxCount = mCountInStrip;
- final int dividers = mDividerWidth * (maxCount - 1);
- mConstantWidthForPaddings = dividers + mPadding * maxCount;
- mAvailableWidthForWords = mMaxWidth - mConstantWidthForPaddings;
-
- mPaint.setTextScaleX(mScaleX);
- final int maxFixedWidthForWord = (mMaxWidth - dividers) / maxCount - mPadding;
- mCanUseFixedWidthColumns = true;
- mVariableWidthForWords = 0;
- for (int i = 0; i < maxCount; i++) {
- final int width = getTextWidth(mTexts.get(i), mPaint);
- if (width > maxFixedWidthForWord)
- mCanUseFixedWidthColumns = false;
- mVariableWidthForWords += width;
+ private float getCandidateWeight(int index) {
+ if (index == mCenterCandidateIndex) {
+ return mCenterCandidateWeight;
+ } else {
+ // TODO: Revisit this for cases of 5 or more suggestions
+ return (1.0f - mCenterCandidateWeight) / (mCandidateCountInStrip - 1);
}
}
- private void setupTexts(SuggestedWords suggestions, int count) {
+ private void setupTexts(SuggestedWords suggestions, int countInStrip) {
mTexts.clear();
- for (int i = 0; i < count; i++) {
- final CharSequence word = suggestions.getWord(i);
- final boolean isAutoCorrect = suggestions.mHasMinimalSuggestion
- && ((i == 1 && !suggestions.mTypedWordValid)
- || (i == 0 && suggestions.mTypedWordValid));
+ final int count = Math.min(suggestions.size(), countInStrip);
+ for (int pos = 0; pos < count; pos++) {
+ final CharSequence word = suggestions.getWord(pos);
+ final boolean isAutoCorrect = pos == 1 && willAutoCorrect(suggestions);
final CharSequence styled = getStyledCandidateWord(word, isAutoCorrect);
mTexts.add(styled);
}
+ for (int pos = count; pos < countInStrip; pos++) {
+ // Make this inactive for touches in layout().
+ mTexts.add(null);
+ }
}
- @Override
- public String toString() {
- return String.format(
- "count=%d width=%d avail=%d fixcol=%s scaleX=%4.2f const=%d var=%d",
- mCountInStrip, mMaxWidth, mAvailableWidthForWords, mCanUseFixedWidthColumns,
- mScaleX, mConstantWidthForPaddings, mVariableWidthForWords);
+ private int layoutPunctuationSuggestions(SuggestedWords suggestions, ViewGroup stripView) {
+ final int countInStrip = Math.min(suggestions.size(), PUNCTUATIONS_IN_STRIP);
+ for (int index = 0; index < countInStrip; index++) {
+ if (index != 0) {
+ // Add divider if this isn't the left most suggestion in candidate strip.
+ stripView.addView(mDividers.get(index));
+ }
+
+ final TextView word = mWords.get(index);
+ word.setEnabled(true);
+ word.setTextColor(mColorTypedWord);
+ final CharSequence text = suggestions.getWord(index);
+ word.setText(text);
+ word.setTextScaleX(1.0f);
+ stripView.addView(word);
+ setLayoutWeight(word, 1.0f, mCandidateStripHeight);
+ }
+ return countInStrip;
}
}
@@ -548,13 +517,13 @@ public class CandidateView extends LinearLayout implements OnClickListener {
mPreviewPopup.setBackgroundDrawable(null);
mCandidatesStrip = (ViewGroup)findViewById(R.id.candidates_strip);
- for (int i = 0; i < MAX_SUGGESTIONS; i++) {
+ for (int pos = 0; pos < MAX_SUGGESTIONS; pos++) {
final TextView word = (TextView)inflater.inflate(R.layout.candidate_word, null);
- word.setTag(i);
+ word.setTag(pos);
word.setOnClickListener(this);
mWords.add(word);
final View divider = inflater.inflate(R.layout.candidate_divider, null);
- divider.setTag(i);
+ divider.setTag(pos);
divider.setOnClickListener(this);
mDividers.add(divider);
mInfos.add((TextView)inflater.inflate(R.layout.candidate_info, null));
@@ -649,7 +618,7 @@ public class CandidateView extends LinearLayout implements OnClickListener {
}
private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
- if (DBG) {
+ if (DBG && pos < suggestions.size()) {
final SuggestedWordInfo wordInfo = suggestions.getInfo(pos);
if (wordInfo != null) {
final CharSequence debugInfo = wordInfo.getDebugString();
@@ -695,14 +664,17 @@ public class CandidateView extends LinearLayout implements OnClickListener {
TextPaint paint) {
paint.setTextScaleX(1.0f);
final int width = getTextWidth(text, paint);
- final float scaleX = Math.min(maxWidth / (float)width, 1.0f);
+ if (width <= maxWidth) {
+ return text;
+ }
+ final float scaleX = maxWidth / (float)width;
if (scaleX >= MIN_TEXT_XSCALE) {
paint.setTextScaleX(scaleX);
return text;
}
// Note that TextUtils.ellipsize() use text-x-scale as 1.0 if ellipsize is needed. To get
- // squeezed and ellipsezed text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
+ // squeezed and ellipsized text, passes enlarged width (maxWidth / MIN_TEXT_XSCALE).
final CharSequence ellipsized = TextUtils.ellipsize(
text, paint, maxWidth / MIN_TEXT_XSCALE, TextUtils.TruncateAt.MIDDLE);
paint.setTextScaleX(MIN_TEXT_XSCALE);