Suggest punctuations between word suggestions, for easy access to ?,!, etc.

Also fix a visual bug with the dividers between suggested words.
main
Amith Yamasani 2010-02-03 15:35:49 -08:00
parent f892861b7b
commit 6a6075caba
6 changed files with 41 additions and 10 deletions

BIN
res/drawable-hdpi/keyboard_suggest_strip_divider.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -22,7 +22,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/candidate_strip_height"
android:background="@drawable/keyboard_suggest_strip" android:background="@drawable/keyboard_suggest_strip"
> >

View File

@ -22,6 +22,8 @@
<string name="word_separators">.\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string> <string name="word_separators">.\u0020,;:!?\n()[]*&amp;@{}/&lt;&gt;_+=|\u0022</string>
<!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. --> <!-- Symbols that are sentence separators, for purposes of making it hug the last sentence. -->
<string name="sentence_separators">.,!?</string> <string name="sentence_separators">.,!?</string>
<!-- Symbols that are suggested between words -->
<string name="suggested_punctuations">!?,@_</string>
<!-- Accented characters related to "d" --> <!-- Accented characters related to "d" -->
<string name="alternates_for_d"></string> <string name="alternates_for_d"></string>
<!-- Accented characters related to "r" --> <!-- Accented characters related to "r" -->

View File

@ -26,6 +26,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
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.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
@ -83,6 +84,8 @@ public class CandidateView extends View {
private boolean mScrolled; private boolean mScrolled;
private int mTargetScrollX; private int mTargetScrollX;
private int mMinTouchableWidth;
private int mTotalWidth; private int mTotalWidth;
private GestureDetector mGestureDetector; private GestureDetector mGestureDetector;
@ -133,7 +136,10 @@ public class CandidateView extends View {
mPaint.setAntiAlias(true); mPaint.setAntiAlias(true);
mPaint.setTextSize(mPreviewText.getTextSize()); mPaint.setTextSize(mPreviewText.getTextSize());
mPaint.setStrokeWidth(0); mPaint.setStrokeWidth(0);
mPaint.setTextAlign(Align.CENTER);
mDescent = (int) mPaint.descent(); mDescent = (int) mPaint.descent();
// 80 pixels for a 160dpi device would mean half an inch
mMinTouchableWidth = (int) (getResources().getDisplayMetrics().density * 50);
mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
@Override @Override
@ -203,7 +209,7 @@ public class CandidateView extends View {
if (getBackground() != null) { if (getBackground() != null) {
getBackground().getPadding(mBgPadding); getBackground().getPadding(mBgPadding);
} }
mDivider.setBounds(0, mBgPadding.top, mDivider.getIntrinsicWidth(), mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight()); mDivider.getIntrinsicHeight());
} }
int x = 0; int x = 0;
@ -233,7 +239,7 @@ public class CandidateView extends View {
wordWidth = mWordWidth[i]; wordWidth = mWordWidth[i];
} else { } else {
float textWidth = paint.measureText(suggestion, 0, suggestion.length()); float textWidth = paint.measureText(suggestion, 0, suggestion.length());
wordWidth = (int) textWidth + X_GAP * 2; wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2);
mWordWidth[i] = wordWidth; mWordWidth[i] = wordWidth;
} }
@ -253,7 +259,7 @@ public class CandidateView extends View {
} }
if (canvas != null) { if (canvas != null) {
canvas.drawText(suggestion, 0, suggestion.length(), x + X_GAP, y, paint); canvas.drawText(suggestion, 0, suggestion.length(), x + wordWidth / 2, y, paint);
paint.setColor(mColorOther); paint.setColor(mColorOther);
canvas.translate(x + wordWidth, 0); canvas.translate(x + wordWidth, 0);
mDivider.draw(canvas); mDivider.draw(canvas);
@ -462,7 +468,8 @@ public class CandidateView extends View {
+ mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight(); + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight();
final int popupHeight = mPreviewText.getMeasuredHeight(); final int popupHeight = mPreviewText.getMeasuredHeight();
//mPreviewText.setVisibility(INVISIBLE); //mPreviewText.setVisibility(INVISIBLE);
mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX(); mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX()
+ (mWordWidth[wordIndex] - wordWidth) / 2;
mPopupPreviewY = - popupHeight; mPopupPreviewY = - popupHeight;
mHandler.removeMessages(MSG_REMOVE_PREVIEW); mHandler.removeMessages(MSG_REMOVE_PREVIEW);
int [] offsetInWindow = new int[2]; int [] offsetInWindow = new int[2];
@ -488,6 +495,7 @@ public class CandidateView extends View {
private void longPressFirstWord() { private void longPressFirstWord() {
CharSequence word = mSuggestions.get(0); CharSequence word = mSuggestions.get(0);
if (word.length() < 2) return;
if (mService.addWordToDictionary(word.toString())) { if (mService.addWordToDictionary(word.toString())) {
showPreview(0, getContext().getResources().getString(R.string.added_word, word)); showPreview(0, getContext().getResources().getString(R.string.added_word, word));
} }

View File

@ -159,7 +159,6 @@ public class KeyboardSwitcher {
void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) { void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) { if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) {
System.err.println("Clearing keyboards");
mKeyboards.clear(); mKeyboards.clear();
} }
mHasVoice = enableVoice; mHasVoice = enableVoice;

View File

@ -215,6 +215,7 @@ public class LatinIME extends InputMethodService
private boolean mEnableVoice = true; private boolean mEnableVoice = true;
private boolean mVoiceOnPrimary; private boolean mVoiceOnPrimary;
private int mOrientation; private int mOrientation;
private List<CharSequence> mSuggestPuncList;
// Indicates whether the suggestion strip is to be on in landscape // Indicates whether the suggestion strip is to be on in landscape
private boolean mJustAccepted; private boolean mJustAccepted;
@ -296,6 +297,7 @@ public class LatinIME extends InputMethodService
} }
initSuggest(inputLanguage); initSuggest(inputLanguage);
mOrientation = conf.orientation; mOrientation = conf.orientation;
initSuggestPuncList();
mVibrateDuration = mResources.getInteger(R.integer.vibrate_duration_ms); mVibrateDuration = mResources.getInteger(R.integer.vibrate_duration_ms);
@ -1337,7 +1339,7 @@ public class LatinIME extends InputMethodService
} }
if (!mPredicting) { if (!mPredicting) {
setSuggestions(null, false, false, false); setNextSuggestions();
return; return;
} }
@ -1397,6 +1399,12 @@ public class LatinIME extends InputMethodService
updateShiftKeyState(getCurrentInputEditorInfo()); updateShiftKeyState(getCurrentInputEditorInfo());
return; return;
} }
// If this is a punctuation, apply it through the normal key press
if (suggestion.length() == 1 && isWordSeparator(suggestion.charAt(0))) {
onKey(suggestion.charAt(0), null);
return;
}
pickSuggestion(suggestion); pickSuggestion(suggestion);
TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
// Follow it with a space // Follow it with a space
@ -1430,10 +1438,14 @@ public class LatinIME extends InputMethodService
} }
mPredicting = false; mPredicting = false;
mCommittedLength = suggestion.length(); mCommittedLength = suggestion.length();
setSuggestions(null, false, false, false); setNextSuggestions();
updateShiftKeyState(getCurrentInputEditorInfo()); updateShiftKeyState(getCurrentInputEditorInfo());
} }
private void setNextSuggestions() {
setSuggestions(mSuggestPuncList, false, false, false);
}
private boolean isCursorTouchingWord() { private boolean isCursorTouchingWord() {
InputConnection ic = getCurrentInputConnection(); InputConnection ic = getCurrentInputConnection();
if (ic == null) return false; if (ic == null) return false;
@ -1767,6 +1779,16 @@ public class LatinIME extends InputMethodService
return sp.getString(PREF_SELECTED_LANGUAGES, null); return sp.getString(PREF_SELECTED_LANGUAGES, null);
} }
private void initSuggestPuncList() {
mSuggestPuncList = new ArrayList<CharSequence>();
String suggestPuncs = mResources.getString(R.string.suggested_punctuations);
if (suggestPuncs != null) {
for (int i = 0; i < suggestPuncs.length(); i++) {
mSuggestPuncList.add(suggestPuncs.subSequence(i, i + 1));
}
}
}
private void showOptionsMenu() { private void showOptionsMenu() {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true); builder.setCancelable(true);