Refactor KeyboardSwitcher and LatinIME

Bug: 3193390
Change-Id: Id894c9bc574a53966d9efc419ab398bae89c34c1
main
Tadashi G. Takaoka 2010-11-13 00:16:34 -08:00
parent 10227a71a0
commit b643dab73a
5 changed files with 154 additions and 186 deletions

View File

@ -344,89 +344,155 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public boolean isKeyboardAvailable() {
return mInputView != null && mInputView.getLatinKeyboard() != null;
if (mInputView != null)
return mInputView.getLatinKeyboard() != null;
return false;
}
private LatinKeyboard getLatinKeyboard() {
if (mInputView != null)
return mInputView.getLatinKeyboard();
return null;
}
public void setPreferredLetters(int[] frequencies) {
LatinKeyboard latinKeyboard;
if (mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null)
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
latinKeyboard.setPreferredLetters(frequencies);
}
public void keyReleased() {
LatinKeyboard latinKeyboard;
if (mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null)
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
latinKeyboard.keyReleased();
}
public boolean isShifted() {
LatinKeyboard latinKeyboard;
return mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null
&& latinKeyboard.isShifted();
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
return latinKeyboard.isShifted();
return false;
}
public boolean isShiftLocked() {
LatinKeyboard latinKeyboard;
return mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null
&& latinKeyboard.isShiftLocked();
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null)
return latinKeyboard.isShiftLocked();
return false;
}
public void setShifted(boolean shifted) {
if (mInputView == null) return;
LatinKeyboard latinKeyboard = mInputView.getLatinKeyboard();
if (latinKeyboard == null) return;
if (latinKeyboard.setShifted(shifted)) {
private void setShifted(boolean shifted) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null && latinKeyboard.setShifted(shifted)) {
mInputView.invalidateAllKeys();
}
}
public void setShiftLocked(boolean shiftLocked) {
if (mInputView == null) return;
mInputView.setShiftLocked(shiftLocked);
private void setShiftLocked(boolean shiftLocked) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) {
mInputView.invalidateAllKeys();
}
}
public void toggleShift() {
handleShiftInternal(false);
}
private void resetShift() {
handleShiftInternal(true);
}
private void handleShiftInternal(boolean forceNormal) {
mInputMethodService.mHandler.cancelUpdateShiftState();
if (isAlphabetMode()) {
if (forceNormal) {
setShifted(false);
} else {
setShifted(!isShifted());
}
} else {
toggleShiftInSymbol();
}
}
public void toggleCapsLock() {
mInputMethodService.mHandler.cancelUpdateShiftState();
if (isAlphabetMode()) {
if (isShiftLocked()) {
// setShifted(false) also disable shift locked state.
// Note: Caps lock LED is off when Key.on is false.
setShifted(false);
} else {
// setShiftLocked(true) enable shift state too.
// Note: Caps lock LED is on when Key.on is true.
setShiftLocked(true);
}
}
}
public void updateShiftState() {
if (isAlphabetMode() && !mShiftState.isIgnoring()) {
final boolean autoCapsMode = mInputMethodService.getCurrentAutoCapsState();
setShifted(mShiftState.isMomentary() || isShiftLocked() || autoCapsMode);
}
}
public void changeKeyboardMode() {
toggleKeyboardMode();
if (isShiftLocked() && isAlphabetMode())
setShiftLocked(true);
updateShiftState();
}
public void onPressShift() {
mShiftState.onPress();
}
public void onPressShiftOnShifted() {
mShiftState.onPressOnShifted();
if (!isKeyboardAvailable())
return;
if (isAlphabetMode() && isShifted()) {
// In alphabet mode, we don't call toggleShift() when we are already in the shifted
// state.
mShiftState.onPressOnShifted();
} else {
// In alphabet mode, we call toggleShift() to go into the shifted mode only when we are
// not in the shifted state.
// This else clause also handles shift key pressing in symbol mode.
mShiftState.onPress();
toggleShift();
}
}
public void onReleaseShift() {
if (!isKeyboardAvailable())
return;
if (isAlphabetMode()) {
if (mShiftState.isMomentary()) {
resetShift();
} else if (isShifted() && mShiftState.isPressingOnShifted()) {
// In alphabet mode, we call toggleShift() to go into the non shifted state only
// when we are in the shifted state -- temporary shifted mode or caps lock mode.
toggleShift();
}
}
mShiftState.onRelease();
}
public boolean isShiftMomentary() {
return mShiftState.isMomentary();
}
public boolean isShiftPressingOnShifted() {
return mShiftState.isPressingOnShifted();
}
public boolean isShiftIgnoring() {
return mShiftState.isIgnoring();
}
public void onPressSymbol() {
changeKeyboardMode();
mSymbolKeyState.onPress();
}
public void onReleaseSymbol() {
if (mSymbolKeyState.isMomentary())
changeKeyboardMode();
mSymbolKeyState.onRelease();
}
public boolean isSymbolMomentary() {
return mSymbolKeyState.isMomentary();
}
public void onOtherKeyPressed() {
mShiftState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
}
public void toggleShift() {
private void toggleShiftInSymbol() {
if (isAlphabetMode())
return;
final LatinKeyboard keyboard;
@ -448,7 +514,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mInputView.setKeyboard(keyboard);
}
public void toggleSymbols() {
public void toggleKeyboardMode() {
loadKeyboardInternal(mMode, mImeOptions, mVoiceButtonEnabled, mVoiceButtonOnPrimary,
!mIsSymbols);
if (mIsSymbols) {
@ -464,22 +530,22 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
/**
* Updates state machine to figure out when to automatically switch back to alpha mode.
* Returns true if the keyboard needs to switch back
*/
public boolean onKey(int key) {
// Switch back to alpha mode if user types one or more non-space/enter characters
// followed by a space/enter
public void onKey(int key) {
// Switch back to alpha mode if user types one or more non-space/enter
// characters followed by a space/enter
switch (mSymbolsModeState) {
case SYMBOLS_MODE_STATE_BEGIN:
if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) {
mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
}
break;
case SYMBOLS_MODE_STATE_SYMBOL:
if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) return true;
break;
case SYMBOLS_MODE_STATE_BEGIN:
if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) {
mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
}
break;
case SYMBOLS_MODE_STATE_SYMBOL:
if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) {
changeKeyboardMode();
}
break;
}
return false;
}
public LatinKeyboardView getInputView() {

View File

@ -331,7 +331,7 @@ public class LatinIME extends InputMethodService
setOldSuggestions();
break;
case MSG_UPDATE_SHIFT_STATE:
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
break;
case MSG_VOICE_RESULTS:
handleVoiceResults();
@ -714,7 +714,7 @@ public class LatinIME extends InputMethodService
loadSettings(attribute);
mKeyboardSwitcher.loadKeyboard(mode, attribute.imeOptions, mVoiceButtonEnabled,
mVoiceButtonOnPrimary);
updateShiftKeyState(attribute);
mKeyboardSwitcher.updateShiftState();
setCandidatesViewShownInternal(isCandidateStripVisible(),
false /* needsInputViewShown */ );
@ -1081,25 +1081,13 @@ public class LatinIME extends InputMethodService
}
}
public void updateShiftKeyState(EditorInfo attr) {
public boolean getCurrentAutoCapsState() {
InputConnection ic = getCurrentInputConnection();
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
if (ic != null && attr != null && switcher.isAlphabetMode()
&& !switcher.isShiftIgnoring()) {
switcher.setShifted(switcher.isShiftMomentary()
|| switcher.isShiftLocked() || getCursorCapsMode(ic, attr) != 0);
}
}
private int getCursorCapsMode(InputConnection ic, EditorInfo attr) {
int caps = 0;
EditorInfo ei = getCurrentInputEditorInfo();
if (mAutoCap && ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
caps = ic.getCursorCapsMode(attr.inputType);
if (mAutoCap && ic != null && ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
return ic.getCursorCapsMode(ei.inputType) != 0;
}
return caps;
return false;
}
private void swapPunctuationAndSpace() {
@ -1112,7 +1100,7 @@ public class LatinIME extends InputMethodService
ic.deleteSurroundingText(2, 0);
ic.commitText(lastTwo.charAt(1) + " ", 1);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
mJustAddedAutoSpace = true;
}
}
@ -1129,7 +1117,7 @@ public class LatinIME extends InputMethodService
ic.deleteSurroundingText(3, 0);
ic.commitText(" ..", 1);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
}
}
@ -1146,7 +1134,7 @@ public class LatinIME extends InputMethodService
ic.deleteSurroundingText(2, 0);
ic.commitText(". ", 1);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
mJustAddedAutoSpace = true;
}
}
@ -1229,7 +1217,8 @@ public class LatinIME extends InputMethodService
mDeleteCount = 0;
}
mLastKeyTime = when;
final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
KeyboardSwitcher switcher = mKeyboardSwitcher;
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
switch (primaryCode) {
case BaseKeyboard.KEYCODE_DELETE:
handleBackspace();
@ -1239,12 +1228,12 @@ public class LatinIME extends InputMethodService
case BaseKeyboard.KEYCODE_SHIFT:
// Shift key is handled in onPress() when device has distinct multi-touch panel.
if (!distinctMultiTouch)
handleShift();
switcher.toggleShift();
break;
case BaseKeyboard.KEYCODE_MODE_CHANGE:
// Symbol key is handled in onPress() when device has distinct multi-touch panel.
if (!distinctMultiTouch)
changeKeyboardMode();
switcher.changeKeyboardMode();
break;
case BaseKeyboard.KEYCODE_CANCEL:
if (!isShowingOptionDialog()) {
@ -1264,7 +1253,7 @@ public class LatinIME extends InputMethodService
toggleLanguage(false, false);
break;
case LatinKeyboardView.KEYCODE_CAPSLOCK:
handleCapsLock();
switcher.toggleCapsLock();
break;
case LatinKeyboardView.KEYCODE_VOICE:
if (VOICE_INSTALLED) {
@ -1288,9 +1277,7 @@ public class LatinIME extends InputMethodService
// Cancel the just reverted state
mJustReverted = false;
}
if (mKeyboardSwitcher.onKey(primaryCode)) {
changeKeyboardMode();
}
switcher.onKey(primaryCode);
// Reset after any single keystroke
mEnteredText = null;
}
@ -1309,7 +1296,7 @@ public class LatinIME extends InputMethodService
maybeRemovePreviousPeriod(text);
ic.commitText(text, 1);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
mJustReverted = false;
mJustAddedAutoSpace = false;
mEnteredText = text;
@ -1389,48 +1376,6 @@ public class LatinIME extends InputMethodService
ic.endBatchEdit();
}
private void resetShift() {
handleShiftInternal(true);
}
private void handleShift() {
handleShiftInternal(false);
}
private void handleShiftInternal(boolean forceNormal) {
mHandler.cancelUpdateShiftState();
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (switcher.isAlphabetMode()) {
if (!switcher.isKeyboardAvailable())
return;
if (switcher.isShiftLocked() || forceNormal) {
switcher.setShifted(false);
} else {
switcher.setShifted(!switcher.isShifted());
}
} else {
switcher.toggleShift();
}
}
private void handleCapsLock() {
mHandler.cancelUpdateShiftState();
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (switcher.isAlphabetMode()) {
if (!switcher.isKeyboardAvailable())
return;
if (switcher.isShiftLocked()) {
// KeyboardSwitcher.setShifted(false) also disable shift locked state.
// Note: Caps lock LED is off when Key.on is false.
switcher.setShifted(false);
} else {
// KeyboardSwitcher.setShiftLocked(true) enable shift state too.
// Note: Caps lock LED is on when Key.on is true.
switcher.setShiftLocked(true);
}
}
}
private void abortCorrection(boolean force) {
if (force || TextEntryState.isCorrecting()) {
TextEntryState.onAbortCorrection();
@ -1490,8 +1435,7 @@ public class LatinIME extends InputMethodService
if (ic != null) {
// If it's the first letter, make note of auto-caps state
if (mWord.size() == 1) {
mWord.setAutoCapitalized(
getCursorCapsMode(ic, getCurrentInputEditorInfo()) != 0);
mWord.setAutoCapitalized(getCurrentAutoCapsState());
}
ic.setComposingText(mComposing, 1);
}
@ -1499,7 +1443,7 @@ public class LatinIME extends InputMethodService
} else {
sendKeyChar((char)primaryCode);
}
updateShiftKeyState(getCurrentInputEditorInfo());
switcher.updateShiftState();
if (LatinIME.PERF_DEBUG) measureCps();
TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode));
}
@ -1565,7 +1509,7 @@ public class LatinIME extends InputMethodService
if (pickedDefault) {
TextEntryState.backToAcceptedDefault(mWord.getTypedWord());
}
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
if (ic != null) {
ic.endBatchEdit();
}
@ -1937,7 +1881,7 @@ public class LatinIME extends InputMethodService
if (mCandidateView != null) {
mCandidateView.clear();
}
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
if (ic != null) {
ic.endBatchEdit();
}
@ -2030,7 +1974,8 @@ public class LatinIME extends InputMethodService
* word.
*/
private void pickSuggestion(CharSequence suggestion, boolean correcting) {
if (!mKeyboardSwitcher.isKeyboardAvailable())
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
@ -2040,12 +1985,12 @@ public class LatinIME extends InputMethodService
saveWordInHistory(suggestion);
mPredicting = false;
mCommittedLength = suggestion.length();
mKeyboardSwitcher.setPreferredLetters(null);
switcher.setPreferredLetters(null);
// If we just corrected a word, then don't show punctuations
if (!correcting) {
setPunctuationSuggestions();
}
updateShiftKeyState(getCurrentInputEditorInfo());
switcher.updateShiftState();
}
/**
@ -2264,7 +2209,7 @@ public class LatinIME extends InputMethodService
private void sendSpace() {
sendKeyChar((char)KEYCODE_SPACE);
updateShiftKeyState(getCurrentInputEditorInfo());
mKeyboardSwitcher.updateShiftState();
//onKey(KEY_SPACE[0], KEY_SPACE);
}
@ -2282,14 +2227,15 @@ public class LatinIME extends InputMethodService
mLanguageSwitcher.prev();
}
}
final int mode = mKeyboardSwitcher.getKeyboardMode();
KeyboardSwitcher switcher = mKeyboardSwitcher;
final int mode = switcher.getKeyboardMode();
final EditorInfo attribute = getCurrentInputEditorInfo();
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
mKeyboardSwitcher.loadKeyboard(mode, imeOptions, mVoiceButtonEnabled,
switcher.loadKeyboard(mode, imeOptions, mVoiceButtonEnabled,
mVoiceButtonOnPrimary);
initSuggest(mLanguageSwitcher.getInputLanguage());
mLanguageSwitcher.persist();
updateShiftKeyState(getCurrentInputEditorInfo());
switcher.updateShiftState();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
@ -2328,21 +2274,11 @@ public class LatinIME extends InputMethodService
vibrate();
playKeyClick(primaryCode);
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) {
// In alphabet mode, we call handleShift() to go into the shifted mode in this
// method, onPress(), only when we are in the small letter mode.
if (switcher.isAlphabetMode() && switcher.isShifted()) {
switcher.onPressShiftOnShifted();
} else {
switcher.onPressShift();
handleShift();
}
switcher.onPressShift();
} else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) {
switcher.onPressSymbol();
changeKeyboardMode();
} else {
switcher.onOtherKeyPressed();
}
@ -2350,28 +2286,12 @@ public class LatinIME extends InputMethodService
public void onRelease(int primaryCode) {
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
// Reset any drag flags in the keyboard
switcher.keyReleased();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) {
if (switcher.isShiftMomentary()) {
resetShift();
}
if (switcher.isAlphabetMode()) {
// In alphabet mode, we call handleShift() to go into the small letter mode in this
// method, onRelease(), only when we are in the shifted modes -- temporary shifted
// mode or caps lock mode.
if (switcher.isShifted() && switcher.isShiftPressingOnShifted()) {
handleShift();
}
}
switcher.onReleaseShift();
} else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) {
if (switcher.isSymbolMomentary()) {
changeKeyboardMode();
}
switcher.onReleaseSymbol();
}
}
@ -2679,18 +2599,6 @@ public class LatinIME extends InputMethodService
mOptionsDialog.show();
}
private void changeKeyboardMode() {
KeyboardSwitcher switcher = mKeyboardSwitcher;
switcher.toggleSymbols();
if (!switcher.isKeyboardAvailable())
return;
if (switcher.isShiftLocked() && switcher.isAlphabetMode()) {
switcher.setShiftLocked(true);
}
updateShiftKeyState(getCurrentInputEditorInfo());
}
public static <E> ArrayList<E> newArrayList(E... elements) {
int capacity = (elements.length * 110) / 100 + 5;
ArrayList<E> list = new ArrayList<E>(capacity);

View File

@ -232,13 +232,14 @@ public class LatinKeyboard extends BaseKeyboard {
}
}
public void setShiftLocked(boolean shiftLocked) {
public boolean setShiftLocked(boolean shiftLocked) {
// TODO: cleanup this method with BaseKeyboard.Key
for (final Key key : getShiftKeys()) {
key.on = shiftLocked;
key.icon = mShiftLockIcon;
}
mShiftState = shiftLocked ? SHIFT_LOCKED : SHIFT_ON;
return true;
}
public boolean isShiftLocked() {

View File

@ -127,13 +127,6 @@ public class LatinKeyboardView extends BaseKeyboardView {
return label;
}
public boolean setShiftLocked(boolean shiftLocked) {
LatinKeyboard keyboard = getLatinKeyboard();
keyboard.setShiftLocked(shiftLocked);
invalidateAllKeys();
return true;
}
/**
* This function checks to see if we need to handle any sudden jumps in the pointer location
* that could be due to a multi-touch being treated as a move by the firmware or hardware.

View File

@ -217,7 +217,7 @@ public class Tutorial implements OnTouchListener {
return;
}
if (mBubbleIndex == 3 || mBubbleIndex == 4) {
mKeyboardSwitcher.toggleSymbols();
mKeyboardSwitcher.toggleKeyboardMode();
}
mHandler.sendMessageDelayed(
mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);