Implement both automatic and manual temporary upper cases
With this change, - Shift and Shift lock state of keyboard is maintained by LatinKeyboard.ShiftState. - Shift key state is maintained by ShiftKeyState object in KeyboardSwitcher. - LatinIME informs KeyboardSwitcher that shift key press, release and long press and KeyboardSwitcher determines which state LatinKeyboard and ShiftLeyState should be. Bug: 3193390 Change-Id: I948ef26fda512eb1cb0ebddc89d322c4f4f4d670
This commit is contained in:
parent
1d2d3228a3
commit
f27364600c
11 changed files with 312 additions and 102 deletions
|
@ -626,7 +626,7 @@ public class BaseKeyboard {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShifted() {
|
public boolean isShiftedOrShiftLocked() {
|
||||||
return mShifted;
|
return mShifted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -683,7 +683,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CharSequence adjustCase(CharSequence label) {
|
protected CharSequence adjustCase(CharSequence label) {
|
||||||
if (mKeyboard.isShifted() && label != null && label.length() < 3
|
if (mKeyboard.isShiftedOrShiftLocked() && label != null && label.length() < 3
|
||||||
&& Character.isLowerCase(label.charAt(0))) {
|
&& Character.isLowerCase(label.charAt(0))) {
|
||||||
label = label.toString().toUpperCase();
|
label = label.toString().toUpperCase();
|
||||||
}
|
}
|
||||||
|
@ -772,8 +772,8 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
final int kbdPaddingTop = getPaddingTop();
|
final int kbdPaddingTop = getPaddingTop();
|
||||||
final Key[] keys = mKeys;
|
final Key[] keys = mKeys;
|
||||||
final Key invalidKey = mInvalidatedKey;
|
final Key invalidKey = mInvalidatedKey;
|
||||||
final boolean isTemporaryUpperCase = (mKeyboard instanceof LatinKeyboard
|
final boolean isManualTemporaryUpperCase = (mKeyboard instanceof LatinKeyboard
|
||||||
&& ((LatinKeyboard)mKeyboard).isTemporaryUpperCase());
|
&& ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase());
|
||||||
|
|
||||||
paint.setColor(mKeyTextColor);
|
paint.setColor(mKeyTextColor);
|
||||||
boolean drawSingleKey = false;
|
boolean drawSingleKey = false;
|
||||||
|
@ -853,7 +853,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
int drawableHeight = key.height;
|
int drawableHeight = key.height;
|
||||||
int drawableX = 0;
|
int drawableX = 0;
|
||||||
int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
|
int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL;
|
||||||
Drawable icon = (isTemporaryUpperCase
|
Drawable icon = (isManualTemporaryUpperCase
|
||||||
&& key.manualTemporaryUpperCaseHintIcon != null)
|
&& key.manualTemporaryUpperCaseHintIcon != null)
|
||||||
? key.manualTemporaryUpperCaseHintIcon : key.hintIcon;
|
? key.manualTemporaryUpperCaseHintIcon : key.hintIcon;
|
||||||
drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
|
drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight);
|
||||||
|
@ -1226,7 +1226,7 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy {
|
||||||
// TODO: change the below line to use getLatinKeyboard() instead of getKeyboard()
|
// TODO: change the below line to use getLatinKeyboard() instead of getKeyboard()
|
||||||
BaseKeyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard();
|
BaseKeyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard();
|
||||||
if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null
|
if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null
|
||||||
? false : mKeyboard.isShifted())) {
|
? false : mKeyboard.isShiftedOrShiftLocked())) {
|
||||||
mMiniKeyboard.invalidateAllKeys();
|
mMiniKeyboard.invalidateAllKeys();
|
||||||
}
|
}
|
||||||
// Mini keyboard needs no pop-up key preview displayed.
|
// Mini keyboard needs no pop-up key preview displayed.
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -32,6 +31,7 @@ import java.util.Locale;
|
||||||
public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private static final String TAG = "KeyboardSwitcher";
|
private static final String TAG = "KeyboardSwitcher";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
public static final boolean DEBUG_STATE = false;
|
||||||
|
|
||||||
public static final int MODE_TEXT = 0;
|
public static final int MODE_TEXT = 0;
|
||||||
public static final int MODE_URL = 1;
|
public static final int MODE_URL = 1;
|
||||||
|
@ -76,8 +76,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
private LatinKeyboardView mInputView;
|
private LatinKeyboardView mInputView;
|
||||||
private LatinIME mInputMethodService;
|
private LatinIME mInputMethodService;
|
||||||
|
|
||||||
private ShiftKeyState mShiftState = new ShiftKeyState();
|
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||||
private ModifierKeyState mSymbolKeyState = new ModifierKeyState();
|
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||||
|
|
||||||
private KeyboardId mSymbolsId;
|
private KeyboardId mSymbolsId;
|
||||||
private KeyboardId mSymbolsShiftedId;
|
private KeyboardId mSymbolsShiftedId;
|
||||||
|
@ -374,10 +374,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
latinKeyboard.keyReleased();
|
latinKeyboard.keyReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShifted() {
|
public boolean isShiftedOrShiftLocked() {
|
||||||
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
if (latinKeyboard != null)
|
if (latinKeyboard != null)
|
||||||
return latinKeyboard.isShifted();
|
return latinKeyboard.isShiftedOrShiftLocked();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,21 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setShifted(boolean shifted) {
|
public boolean isAutomaticTemporaryUpperCase() {
|
||||||
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
|
if (latinKeyboard != null)
|
||||||
|
return latinKeyboard.isAutomaticTemporaryUpperCase();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isManualTemporaryUpperCase() {
|
||||||
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
|
if (latinKeyboard != null)
|
||||||
|
return latinKeyboard.isManualTemporaryUpperCase();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setManualTemporaryUpperCase(boolean shifted) {
|
||||||
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
if (latinKeyboard != null && latinKeyboard.setShifted(shifted)) {
|
if (latinKeyboard != null && latinKeyboard.setShifted(shifted)) {
|
||||||
mInputView.invalidateAllKeys();
|
mInputView.invalidateAllKeys();
|
||||||
|
@ -403,21 +417,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleShift() {
|
public void toggleShift() {
|
||||||
handleShiftInternal(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetShift() {
|
|
||||||
handleShiftInternal(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleShiftInternal(boolean forceNormal) {
|
|
||||||
mInputMethodService.mHandler.cancelUpdateShiftState();
|
mInputMethodService.mHandler.cancelUpdateShiftState();
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "toggleShift:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + mShiftKeyState);
|
||||||
if (isAlphabetMode()) {
|
if (isAlphabetMode()) {
|
||||||
if (forceNormal) {
|
setManualTemporaryUpperCase(!isShiftedOrShiftLocked());
|
||||||
setShifted(false);
|
|
||||||
} else {
|
|
||||||
setShifted(!isShifted());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
toggleShiftInSymbol();
|
toggleShiftInSymbol();
|
||||||
}
|
}
|
||||||
|
@ -425,27 +431,50 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
|
|
||||||
public void toggleCapsLock() {
|
public void toggleCapsLock() {
|
||||||
mInputMethodService.mHandler.cancelUpdateShiftState();
|
mInputMethodService.mHandler.cancelUpdateShiftState();
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "toggleCapsLock:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + mShiftKeyState);
|
||||||
if (isAlphabetMode()) {
|
if (isAlphabetMode()) {
|
||||||
if (isShiftLocked()) {
|
if (isShiftLocked()) {
|
||||||
// setShifted(false) also disable shift locked state.
|
// Shift key is long pressed while caps lock state, we will toggle back to normal
|
||||||
// Note: Caps lock LED is off when Key.on is false.
|
// state. And mark as if shift key is released.
|
||||||
setShifted(false);
|
setShiftLocked(false);
|
||||||
|
mShiftKeyState.onRelease();
|
||||||
} else {
|
} else {
|
||||||
// setShiftLocked(true) enable shift state too.
|
|
||||||
// Note: Caps lock LED is on when Key.on is true.
|
|
||||||
setShiftLocked(true);
|
setShiftLocked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setAutomaticTemporaryUpperCase() {
|
||||||
|
LatinKeyboard latinKeyboard = getLatinKeyboard();
|
||||||
|
if (latinKeyboard != null) {
|
||||||
|
latinKeyboard.setAutomaticTemporaryUpperCase();
|
||||||
|
mInputView.invalidateAllKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void updateShiftState() {
|
public void updateShiftState() {
|
||||||
if (isAlphabetMode() && !mShiftState.isIgnoring()) {
|
if (DEBUG_STATE)
|
||||||
final boolean autoCapsMode = mInputMethodService.getCurrentAutoCapsState();
|
Log.d(TAG, "updateShiftState:"
|
||||||
setShifted(mShiftState.isMomentary() || isShiftLocked() || autoCapsMode);
|
+ " autoCaps=" + mInputMethodService.getCurrentAutoCapsState()
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + mShiftKeyState);
|
||||||
|
if (isAlphabetMode() && !isShiftLocked() && !mShiftKeyState.isIgnoring()) {
|
||||||
|
if (mInputMethodService.getCurrentAutoCapsState()) {
|
||||||
|
setAutomaticTemporaryUpperCase();
|
||||||
|
} else {
|
||||||
|
setManualTemporaryUpperCase(mShiftKeyState.isMomentary());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeKeyboardMode() {
|
public void changeKeyboardMode() {
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "changeKeyboardMode:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + mShiftKeyState);
|
||||||
toggleKeyboardMode();
|
toggleKeyboardMode();
|
||||||
if (isShiftLocked() && isAlphabetMode())
|
if (isShiftLocked() && isAlphabetMode())
|
||||||
setShiftLocked(true);
|
setShiftLocked(true);
|
||||||
|
@ -455,47 +484,82 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
public void onPressShift() {
|
public void onPressShift() {
|
||||||
if (!isKeyboardAvailable())
|
if (!isKeyboardAvailable())
|
||||||
return;
|
return;
|
||||||
if (isAlphabetMode() && isShifted()) {
|
ShiftKeyState shiftKeyState = mShiftKeyState;
|
||||||
// In alphabet mode, we don't call toggleShift() when we are already in the shifted
|
if (DEBUG_STATE)
|
||||||
// state.
|
Log.d(TAG, "onPressShift:"
|
||||||
mShiftState.onPressOnShifted();
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + shiftKeyState);
|
||||||
|
if (isAlphabetMode()) {
|
||||||
|
if (isShiftLocked()) {
|
||||||
|
// Shift key is pressed while caps lock state, we will treat this state as shifted
|
||||||
|
// caps lock state and mark as if shift key pressed while normal state.
|
||||||
|
setManualTemporaryUpperCase(true);
|
||||||
|
shiftKeyState.onPress();
|
||||||
|
} else if (isAutomaticTemporaryUpperCase()) {
|
||||||
|
// Shift key is pressed while automatic temporary upper case, we have to move to
|
||||||
|
// manual temporary upper case.
|
||||||
|
setManualTemporaryUpperCase(true);
|
||||||
|
shiftKeyState.onPressOnShifted();
|
||||||
|
} else if (isShiftedOrShiftLocked()) {
|
||||||
|
// In manual upper case state, we just record shift key has been pressing while
|
||||||
|
// shifted state.
|
||||||
|
shiftKeyState.onPressOnShifted();
|
||||||
} else {
|
} else {
|
||||||
// In alphabet mode, we call toggleShift() to go into the shifted mode only when we are
|
// In base layout, chording or manual temporary upper case mode is started.
|
||||||
// not in the shifted state.
|
|
||||||
// This else clause also handles shift key pressing in symbol mode.
|
|
||||||
mShiftState.onPress();
|
|
||||||
toggleShift();
|
toggleShift();
|
||||||
|
shiftKeyState.onPress();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// In symbol mode, just toggle symbol and symbol more keyboard.
|
||||||
|
toggleShift();
|
||||||
|
shiftKeyState.onPress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onReleaseShift() {
|
public void onReleaseShift() {
|
||||||
if (!isKeyboardAvailable())
|
if (!isKeyboardAvailable())
|
||||||
return;
|
return;
|
||||||
|
ShiftKeyState shiftKeyState = mShiftKeyState;
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "onReleaseShift:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " shiftKeyState=" + shiftKeyState);
|
||||||
if (isAlphabetMode()) {
|
if (isAlphabetMode()) {
|
||||||
if (mShiftState.isMomentary()) {
|
if (shiftKeyState.isMomentary()) {
|
||||||
resetShift();
|
// After chording input while normal state.
|
||||||
} else if (isShifted() && mShiftState.isPressingOnShifted()) {
|
toggleShift();
|
||||||
// In alphabet mode, we call toggleShift() to go into the non shifted state only
|
} else if (isShiftLocked() && !shiftKeyState.isIgnoring()) {
|
||||||
// when we are in the shifted state -- temporary shifted mode or caps lock mode.
|
// Shift has been pressed without chording while caps lock state.
|
||||||
|
toggleCapsLock();
|
||||||
|
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()) {
|
||||||
|
// Shift has been pressed without chording while shifted state.
|
||||||
toggleShift();
|
toggleShift();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mShiftState.onRelease();
|
shiftKeyState.onRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPressSymbol() {
|
public void onPressSymbol() {
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "onReleaseShift:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " symbolKeyState=" + mSymbolKeyState);
|
||||||
changeKeyboardMode();
|
changeKeyboardMode();
|
||||||
mSymbolKeyState.onPress();
|
mSymbolKeyState.onPress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onReleaseSymbol() {
|
public void onReleaseSymbol() {
|
||||||
|
if (DEBUG_STATE)
|
||||||
|
Log.d(TAG, "onReleaseShift:"
|
||||||
|
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||||
|
+ " symbolKeyState=" + mSymbolKeyState);
|
||||||
if (mSymbolKeyState.isMomentary())
|
if (mSymbolKeyState.isMomentary())
|
||||||
changeKeyboardMode();
|
changeKeyboardMode();
|
||||||
mSymbolKeyState.onRelease();
|
mSymbolKeyState.onRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onOtherKeyPressed() {
|
public void onOtherKeyPressed() {
|
||||||
mShiftState.onOtherKeyPressed();
|
mShiftKeyState.onOtherKeyPressed();
|
||||||
mSymbolKeyState.onOtherKeyPressed();
|
mSymbolKeyState.onOtherKeyPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +585,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
mInputView.setKeyboard(keyboard);
|
mInputView.setKeyboard(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toggleKeyboardMode() {
|
private void toggleKeyboardMode() {
|
||||||
loadKeyboardInternal(mMode, mImeOptions, mVoiceButtonEnabled, mVoiceButtonOnPrimary,
|
loadKeyboardInternal(mMode, mImeOptions, mVoiceButtonEnabled, mVoiceButtonOnPrimary,
|
||||||
!mIsSymbols);
|
!mIsSymbols);
|
||||||
if (mIsSymbols) {
|
if (mIsSymbols) {
|
||||||
|
|
|
@ -1004,7 +1004,8 @@ public class LatinIME extends InputMethodService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Enable shift key and DPAD to do selections
|
// Enable shift key and DPAD to do selections
|
||||||
if (mKeyboardSwitcher.isInputViewShown() && mKeyboardSwitcher.isShifted()) {
|
if (mKeyboardSwitcher.isInputViewShown()
|
||||||
|
&& mKeyboardSwitcher.isShiftedOrShiftLocked()) {
|
||||||
event = new KeyEvent(event.getDownTime(), event.getEventTime(),
|
event = new KeyEvent(event.getDownTime(), event.getEventTime(),
|
||||||
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
|
event.getAction(), event.getKeyCode(), event.getRepeatCount(),
|
||||||
event.getDeviceId(), event.getScanCode(),
|
event.getDeviceId(), event.getScanCode(),
|
||||||
|
@ -1373,7 +1374,7 @@ public class LatinIME extends InputMethodService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||||
if (switcher.isShifted()) {
|
if (switcher.isShiftedOrShiftLocked()) {
|
||||||
if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
|
if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
|
||||||
|| keyCodes[0] > Character.MAX_CODE_POINT) {
|
|| keyCodes[0] > Character.MAX_CODE_POINT) {
|
||||||
return;
|
return;
|
||||||
|
@ -1392,7 +1393,8 @@ public class LatinIME extends InputMethodService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mPredicting) {
|
if (mPredicting) {
|
||||||
if (mComposing.length() == 0 && switcher.isAlphabetMode() && switcher.isShifted()) {
|
if (mComposing.length() == 0 && switcher.isAlphabetMode()
|
||||||
|
&& switcher.isShiftedOrShiftLocked()) {
|
||||||
mWord.setFirstCharCapitalized(true);
|
mWord.setFirstCharCapitalized(true);
|
||||||
}
|
}
|
||||||
mComposing.append((char) primaryCode);
|
mComposing.append((char) primaryCode);
|
||||||
|
@ -1677,7 +1679,7 @@ public class LatinIME extends InputMethodService
|
||||||
final List<CharSequence> nBest = new ArrayList<CharSequence>();
|
final List<CharSequence> nBest = new ArrayList<CharSequence>();
|
||||||
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||||
boolean capitalizeFirstWord = preferCapitalization()
|
boolean capitalizeFirstWord = preferCapitalization()
|
||||||
|| (switcher.isAlphabetMode() && switcher.isShifted());
|
|| (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked());
|
||||||
for (String c : mVoiceResults.candidates) {
|
for (String c : mVoiceResults.candidates) {
|
||||||
if (capitalizeFirstWord) {
|
if (capitalizeFirstWord) {
|
||||||
c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length());
|
c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length());
|
||||||
|
|
|
@ -46,9 +46,9 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
private static final int OPACITY_FULLY_OPAQUE = 255;
|
private static final int OPACITY_FULLY_OPAQUE = 255;
|
||||||
private static final int SPACE_LED_LENGTH_PERCENT = 80;
|
private static final int SPACE_LED_LENGTH_PERCENT = 80;
|
||||||
|
|
||||||
private Drawable mShiftLockIcon;
|
private Drawable mShiftedIcon;
|
||||||
private Drawable mShiftLockPreviewIcon;
|
private Drawable mShiftLockPreviewIcon;
|
||||||
private final HashMap<Key, Drawable> mOldShiftIcons = new HashMap<Key, Drawable>();
|
private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>();
|
||||||
private Drawable mSpaceIcon;
|
private Drawable mSpaceIcon;
|
||||||
private Drawable mSpaceAutoCompletionIndicator;
|
private Drawable mSpaceAutoCompletionIndicator;
|
||||||
private Drawable mSpacePreviewIcon;
|
private Drawable mSpacePreviewIcon;
|
||||||
|
@ -92,11 +92,7 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
// TODO: generalize for any keyboardId
|
// TODO: generalize for any keyboardId
|
||||||
private boolean mIsBlackSym;
|
private boolean mIsBlackSym;
|
||||||
|
|
||||||
private static final int SHIFT_OFF = 0;
|
private LatinKeyboardShiftState mShiftState = new LatinKeyboardShiftState();
|
||||||
private static final int SHIFT_ON = 1;
|
|
||||||
private static final int SHIFT_LOCKED = 2;
|
|
||||||
|
|
||||||
private int mShiftState = SHIFT_OFF;
|
|
||||||
|
|
||||||
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
|
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
|
||||||
private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
|
private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
|
||||||
|
@ -117,7 +113,7 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mRes = res;
|
mRes = res;
|
||||||
mMode = id.mMode;
|
mMode = id.mMode;
|
||||||
mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
mShiftedIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
||||||
mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
|
mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
|
||||||
setDefaultBounds(mShiftLockPreviewIcon);
|
setDefaultBounds(mShiftLockPreviewIcon);
|
||||||
mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
|
mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
|
||||||
|
@ -226,61 +222,62 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
if (key instanceof LatinKey) {
|
if (key instanceof LatinKey) {
|
||||||
((LatinKey)key).enableShiftLock();
|
((LatinKey)key).enableShiftLock();
|
||||||
}
|
}
|
||||||
mOldShiftIcons.put(key, key.icon);
|
mNormalShiftIcons.put(key, key.icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setShiftLocked(boolean shiftLocked) {
|
public boolean setShiftLocked(boolean newShiftLockState) {
|
||||||
// TODO: cleanup this method with BaseKeyboard.Key
|
|
||||||
for (final Key key : getShiftKeys()) {
|
for (final Key key : getShiftKeys()) {
|
||||||
key.on = shiftLocked;
|
key.on = newShiftLockState;
|
||||||
key.icon = mShiftLockIcon;
|
key.icon = newShiftLockState ? mShiftedIcon : mNormalShiftIcons.get(key);
|
||||||
}
|
}
|
||||||
mShiftState = shiftLocked ? SHIFT_LOCKED : SHIFT_ON;
|
mShiftState.setShiftLocked(newShiftLockState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShiftLocked() {
|
public boolean isShiftLocked() {
|
||||||
return mShiftState == SHIFT_LOCKED;
|
return mShiftState.isShiftLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setShifted(boolean shiftState) {
|
public boolean setShifted(boolean newShiftState) {
|
||||||
// TODO: cleanup this method with BaseKeyboard.Key.
|
if (getShiftKeys().size() == 0)
|
||||||
boolean shiftChanged = false;
|
return super.setShifted(newShiftState);
|
||||||
if (getShiftKeys().size() > 0) {
|
|
||||||
for (final Key key : getShiftKeys()) {
|
for (final Key key : getShiftKeys()) {
|
||||||
if (shiftState == false) {
|
if (!newShiftState && !mShiftState.isShiftLocked()) {
|
||||||
key.on = false;
|
key.icon = mNormalShiftIcons.get(key);
|
||||||
key.icon = mOldShiftIcons.get(key);
|
} else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) {
|
||||||
} else if (mShiftState == SHIFT_OFF) {
|
key.icon = mShiftedIcon;
|
||||||
key.icon = mShiftLockIcon;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shiftState == false) {
|
return mShiftState.setShifted(newShiftState);
|
||||||
shiftChanged = mShiftState != SHIFT_OFF;
|
|
||||||
mShiftState = SHIFT_OFF;
|
|
||||||
} else if (mShiftState == SHIFT_OFF) {
|
|
||||||
shiftChanged = mShiftState == SHIFT_OFF;
|
|
||||||
mShiftState = SHIFT_ON;
|
|
||||||
}
|
|
||||||
return shiftChanged;
|
|
||||||
} else {
|
|
||||||
return super.setShifted(shiftState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isShifted() {
|
public boolean isShiftedOrShiftLocked() {
|
||||||
if (getShiftKeys().size() > 0) {
|
if (getShiftKeys().size() > 0) {
|
||||||
return mShiftState != SHIFT_OFF;
|
return mShiftState.isShiftedOrShiftLocked();
|
||||||
} else {
|
} else {
|
||||||
return super.isShifted();
|
return super.isShiftedOrShiftLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTemporaryUpperCase() {
|
public void setAutomaticTemporaryUpperCase() {
|
||||||
return mIsAlphaKeyboard && isShifted() && !isShiftLocked();
|
setShifted(true);
|
||||||
|
mShiftState.setAutomaticTemporaryUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutomaticTemporaryUpperCase() {
|
||||||
|
return mIsAlphaKeyboard && mShiftState.isAutomaticTemporaryUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isManualTemporaryUpperCase() {
|
||||||
|
return mIsAlphaKeyboard && mShiftState.isManualTemporaryUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ LatinKeyboardShiftState getKeyboardShiftState() {
|
||||||
|
return mShiftState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAlphaKeyboard() {
|
public boolean isAlphaKeyboard() {
|
||||||
|
@ -291,12 +288,12 @@ public class LatinKeyboard extends BaseKeyboard {
|
||||||
mIsBlackSym = isBlack;
|
mIsBlackSym = isBlack;
|
||||||
final Resources res = mRes;
|
final Resources res = mRes;
|
||||||
if (isBlack) {
|
if (isBlack) {
|
||||||
mShiftLockIcon = res.getDrawable(R.drawable.sym_bkeyboard_shift_locked);
|
mShiftedIcon = res.getDrawable(R.drawable.sym_bkeyboard_shift_locked);
|
||||||
mSpaceIcon = res.getDrawable(R.drawable.sym_bkeyboard_space);
|
mSpaceIcon = res.getDrawable(R.drawable.sym_bkeyboard_space);
|
||||||
mMicIcon = res.getDrawable(R.drawable.sym_bkeyboard_mic);
|
mMicIcon = res.getDrawable(R.drawable.sym_bkeyboard_mic);
|
||||||
m123MicIcon = res.getDrawable(R.drawable.sym_bkeyboard_123_mic);
|
m123MicIcon = res.getDrawable(R.drawable.sym_bkeyboard_123_mic);
|
||||||
} else {
|
} else {
|
||||||
mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
mShiftedIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
|
||||||
mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
|
mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
|
||||||
mMicIcon = res.getDrawable(R.drawable.sym_keyboard_mic);
|
mMicIcon = res.getDrawable(R.drawable.sym_keyboard_mic);
|
||||||
m123MicIcon = res.getDrawable(R.drawable.sym_keyboard_123_mic);
|
m123MicIcon = res.getDrawable(R.drawable.sym_keyboard_123_mic);
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class LatinKeyboardShiftState {
|
||||||
|
private static final String TAG = "LatinKeyboardShiftState";
|
||||||
|
private static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
|
||||||
|
|
||||||
|
private static final int NORMAL = 0;
|
||||||
|
private static final int MANUAL_SHIFTED = 1;
|
||||||
|
private static final int SHIFT_LOCKED = 2;
|
||||||
|
private static final int AUTO_SHIFTED = 3;
|
||||||
|
private static final int SHIFT_LOCK_SHIFTED = 4;
|
||||||
|
|
||||||
|
private int mState = NORMAL;
|
||||||
|
|
||||||
|
public boolean setShifted(boolean newShiftState) {
|
||||||
|
final int oldState = mState;
|
||||||
|
if (newShiftState) {
|
||||||
|
if (oldState == NORMAL || oldState == AUTO_SHIFTED) {
|
||||||
|
mState = MANUAL_SHIFTED;
|
||||||
|
} else if (oldState == SHIFT_LOCKED) {
|
||||||
|
mState = SHIFT_LOCK_SHIFTED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (oldState == MANUAL_SHIFTED || oldState == AUTO_SHIFTED) {
|
||||||
|
mState = NORMAL;
|
||||||
|
} else if (oldState == SHIFT_LOCK_SHIFTED) {
|
||||||
|
mState = SHIFT_LOCKED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "setShifted: " + toString(oldState) + " > " + this);
|
||||||
|
return mState != oldState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShiftLocked(boolean newShiftLockState) {
|
||||||
|
final int oldState = mState;
|
||||||
|
if (newShiftLockState) {
|
||||||
|
if (oldState == NORMAL || oldState == MANUAL_SHIFTED || oldState == AUTO_SHIFTED)
|
||||||
|
mState = SHIFT_LOCKED;
|
||||||
|
} else {
|
||||||
|
if (oldState == SHIFT_LOCKED || oldState == SHIFT_LOCK_SHIFTED)
|
||||||
|
mState = NORMAL;
|
||||||
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "setShiftLocked: " + toString(oldState) + " > " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutomaticTemporaryUpperCase() {
|
||||||
|
final int oldState = mState;
|
||||||
|
mState = AUTO_SHIFTED;
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "setAutomaticTemporaryUpperCase: " + toString(oldState) + " > " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShiftedOrShiftLocked() {
|
||||||
|
return mState != NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShiftLocked() {
|
||||||
|
return mState == SHIFT_LOCKED || mState == SHIFT_LOCK_SHIFTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutomaticTemporaryUpperCase() {
|
||||||
|
return mState == AUTO_SHIFTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isManualTemporaryUpperCase() {
|
||||||
|
return mState == MANUAL_SHIFTED || mState == SHIFT_LOCK_SHIFTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString(mState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString(int state) {
|
||||||
|
switch (state) {
|
||||||
|
case NORMAL: return "NORMAL";
|
||||||
|
case MANUAL_SHIFTED: return "MANUAL_SHIFTED";
|
||||||
|
case SHIFT_LOCKED: return "SHIFT_LOCKED";
|
||||||
|
case AUTO_SHIFTED: return "AUTO_SHIFTED";
|
||||||
|
case SHIFT_LOCK_SHIFTED: return "SHIFT_LOCK_SHIFTED";
|
||||||
|
default: return "UKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -119,7 +119,7 @@ public class LatinKeyboardView extends BaseKeyboardView {
|
||||||
protected CharSequence adjustCase(CharSequence label) {
|
protected CharSequence adjustCase(CharSequence label) {
|
||||||
LatinKeyboard keyboard = getLatinKeyboard();
|
LatinKeyboard keyboard = getLatinKeyboard();
|
||||||
if (keyboard.isAlphaKeyboard()
|
if (keyboard.isAlphaKeyboard()
|
||||||
&& keyboard.isShifted()
|
&& keyboard.isShiftedOrShiftLocked()
|
||||||
&& !TextUtils.isEmpty(label) && label.length() < 3
|
&& !TextUtils.isEmpty(label) && label.length() < 3
|
||||||
&& Character.isLowerCase(label.charAt(0))) {
|
&& Character.isLowerCase(label.charAt(0))) {
|
||||||
label = label.toString().toUpperCase();
|
label = label.toString().toUpperCase();
|
||||||
|
|
|
@ -16,26 +16,60 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class ModifierKeyState {
|
public class ModifierKeyState {
|
||||||
|
protected static final String TAG = "ModifierKeyState";
|
||||||
|
protected static final boolean DEBUG = KeyboardSwitcher.DEBUG_STATE;
|
||||||
|
|
||||||
protected static final int RELEASING = 0;
|
protected static final int RELEASING = 0;
|
||||||
protected static final int PRESSING = 1;
|
protected static final int PRESSING = 1;
|
||||||
protected static final int MOMENTARY = 2;
|
protected static final int MOMENTARY = 2;
|
||||||
|
|
||||||
|
protected final String mName;
|
||||||
protected int mState = RELEASING;
|
protected int mState = RELEASING;
|
||||||
|
|
||||||
|
public ModifierKeyState(String name) {
|
||||||
|
mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
public void onPress() {
|
public void onPress() {
|
||||||
|
final int oldState = mState;
|
||||||
mState = PRESSING;
|
mState = PRESSING;
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, mName + ".onPress: " + toString(oldState) + " > " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRelease() {
|
public void onRelease() {
|
||||||
|
final int oldState = mState;
|
||||||
mState = RELEASING;
|
mState = RELEASING;
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, mName + ".onRelease: " + toString(oldState) + " > " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onOtherKeyPressed() {
|
public void onOtherKeyPressed() {
|
||||||
|
final int oldState = mState;
|
||||||
|
if (mState == PRESSING)
|
||||||
mState = MOMENTARY;
|
mState = MOMENTARY;
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, mName + ".onOtherKeyPressed: " + toString(oldState) + " > " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMomentary() {
|
public boolean isMomentary() {
|
||||||
return mState == MOMENTARY;
|
return mState == MOMENTARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString(mState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String toString(int state) {
|
||||||
|
switch (state) {
|
||||||
|
case RELEASING: return "RELEASING";
|
||||||
|
case PRESSING: return "PRESSING";
|
||||||
|
case MOMENTARY: return "MOMENTARY";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,9 +423,9 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTemporaryUpperCase() {
|
private boolean isManualTemporaryUpperCase() {
|
||||||
return mKeyboard instanceof LatinKeyboard
|
return mKeyboard instanceof LatinKeyboard
|
||||||
&& ((LatinKeyboard)mKeyboard).isTemporaryUpperCase();
|
&& ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void detectAndSendKey(int index, int x, int y, long eventTime) {
|
private void detectAndSendKey(int index, int x, int y, long eventTime) {
|
||||||
|
@ -458,7 +458,7 @@ public class PointerTracker {
|
||||||
|
|
||||||
// If keyboard is in manual temporary upper case state and key has manual temporary
|
// If keyboard is in manual temporary upper case state and key has manual temporary
|
||||||
// shift code, alternate character code should be sent.
|
// shift code, alternate character code should be sent.
|
||||||
if (isTemporaryUpperCase() && key.manualTemporaryUpperCaseCode != 0) {
|
if (isManualTemporaryUpperCase() && key.manualTemporaryUpperCaseCode != 0) {
|
||||||
code = key.manualTemporaryUpperCaseCode;
|
code = key.manualTemporaryUpperCaseCode;
|
||||||
codes[0] = code;
|
codes[0] = code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,21 +16,33 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class ShiftKeyState extends ModifierKeyState {
|
public class ShiftKeyState extends ModifierKeyState {
|
||||||
private static final int PRESSING_ON_SHIFTED = 3; // both temporary shifted & shift locked
|
private static final int PRESSING_ON_SHIFTED = 3; // both temporary shifted & shift locked
|
||||||
private static final int IGNORING = 4;
|
private static final int IGNORING = 4;
|
||||||
|
|
||||||
|
public ShiftKeyState(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOtherKeyPressed() {
|
public void onOtherKeyPressed() {
|
||||||
|
int oldState = mState;
|
||||||
if (mState == PRESSING) {
|
if (mState == PRESSING) {
|
||||||
mState = MOMENTARY;
|
mState = MOMENTARY;
|
||||||
} else if (mState == PRESSING_ON_SHIFTED) {
|
} else if (mState == PRESSING_ON_SHIFTED) {
|
||||||
mState = IGNORING;
|
mState = IGNORING;
|
||||||
}
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, mName + ".onOtherKeyPressed: " + toString(oldState) + " > " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPressOnShifted() {
|
public void onPressOnShifted() {
|
||||||
|
int oldState = mState;
|
||||||
mState = PRESSING_ON_SHIFTED;
|
mState = PRESSING_ON_SHIFTED;
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, mName + ".onPressOnShifted: " + toString(oldState) + " > " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPressingOnShifted() {
|
public boolean isPressingOnShifted() {
|
||||||
|
@ -40,4 +52,17 @@ public class ShiftKeyState extends ModifierKeyState {
|
||||||
public boolean isIgnoring() {
|
public boolean isIgnoring() {
|
||||||
return mState == IGNORING;
|
return mState == IGNORING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString(mState);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String toString(int state) {
|
||||||
|
switch (state) {
|
||||||
|
case PRESSING_ON_SHIFTED: return "PRESSING_ON_SHIFTED";
|
||||||
|
case IGNORING: return "IGNORING";
|
||||||
|
default: return ModifierKeyState.toString(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,7 @@ public class Tutorial implements OnTouchListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mBubbleIndex == 3 || mBubbleIndex == 4) {
|
if (mBubbleIndex == 3 || mBubbleIndex == 4) {
|
||||||
mKeyboardSwitcher.toggleKeyboardMode();
|
mKeyboardSwitcher.changeKeyboardMode();
|
||||||
}
|
}
|
||||||
mHandler.sendMessageDelayed(
|
mHandler.sendMessageDelayed(
|
||||||
mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);
|
mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);
|
||||||
|
|
Loading…
Reference in a new issue